Skip to content

Commit

Permalink
refactor(v2): migrate to Typescript ❄️🌀🐋 (#1490)
Browse files Browse the repository at this point in the history
* refactor(v2): migrate to typescript

* scripts nits

* fix test

* nits

* nits

* tsconfig tweak
  • Loading branch information
endiliey authored and yangshun committed May 18, 2019
1 parent c052b6a commit cbd2a58
Show file tree
Hide file tree
Showing 13 changed files with 383 additions and 118 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ scripts
packages/docusaurus-1.x/lib/core/metadata.js
packages/docusaurus-1.x/lib/core/MetadataBlog.js
packages/docusaurus-1.x/lib/core/__tests__/split-tab.test.js
packages/docusaurus-utils/lib/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ yarn-error.log
build
.docusaurus
.cache-loader
types
packages/docusaurus-utils/lib/

1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ dist
node_modules
build
.docusaurus
packages/docusaurus-utils/lib/
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
},
],
'@babel/react',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-proposal-class-properties',
Expand Down
8 changes: 6 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ module.exports = {
verbose: true,
testURL: 'http://localhost/',
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '__fixtures__'],
testPathIgnorePatterns: [
'/node_modules/',
'__fixtures__',
'/packages/.*/lib',
],
transform: {
'^.+\\.js$': 'babel-jest',
'^.+\\.[jt]sx?$': 'babel-jest',
},
};
19 changes: 17 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@
"website-1.x"
],
"scripts": {
"start": "yarn tsc && yarn start:v2",
"start:v1": "yarn workspace docusaurus-1-website start",
"start:v2": "yarn workspace docusaurus-2-website start",
"build": "yarn tsc && yarn build:v2",
"build:v1": "yarn workspace docusaurus-1-website build",
"build:v2": "yarn workspace docusaurus-2-website build",
"postinstall": "yarn tsc",
"prettier": "prettier --config .prettierrc --write \"**/*.js\"",
"prettier:diff": "prettier --config .prettierrc --list-different \"**/*.js\"",
"lint": "eslint --cache \"**/*.js\"",
"lerna": "lerna",
"test": "jest"
"test": "jest",
"tsc": "lerna run --parallel tsc --no-private"
},
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/preset-typescript": "^7.3.3",
"@types/escape-string-regexp": "^1.0.0",
"@types/fs-extra": "7.0.0",
"@types/jest": "^24.0.13",
"@types/lodash": "^4.14.129",
"@types/node": "^12.0.2",
"babel-eslint": "8",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.12.1",
Expand All @@ -35,7 +49,8 @@
"prettier": "^1.13.7",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"rimraf": "^2.6.3"
"rimraf": "^2.6.3",
"typescript": "^3.4.5"
},
"lint-staged": {
"linters": {
Expand Down
6 changes: 5 additions & 1 deletion packages/docusaurus-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
"name": "@docusaurus/utils",
"version": "2.0.0-alpha.16",
"description": "Node utility functions for Docusaurus packages",
"main": "src/index.js",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"scripts": {
"tsc": "tsc"
},
"publishConfig": {
"access": "public"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('load utils', () => {
});

test('genChunkName', () => {
let asserts = {
const firstAssert = {
'/docs/adding-blog': 'docs-adding-blog-062',
'/docs/versioning': 'docs-versioning-8a8',
'/': 'index',
Expand All @@ -91,8 +91,8 @@ describe('load utils', () => {
'/users/en/': 'users-en-f7a',
'/blog': 'blog-c06',
};
Object.keys(asserts).forEach(str => {
expect(genChunkName(str)).toBe(asserts[str]);
Object.keys(firstAssert).forEach(str => {
expect(genChunkName(str)).toBe(firstAssert[str]);
});

// Don't allow different chunk name for same path.
Expand All @@ -101,12 +101,12 @@ describe('load utils', () => {
);

// Even with same preferred name, still different chunk name for different path
asserts = {
const secondAssert = {
'/blog/1': 'blog-85-f-089',
'/blog/2': 'blog-353-489',
};
Object.keys(asserts).forEach(str => {
expect(genChunkName(str, undefined, 'blog')).toBe(asserts[str]);
Object.keys(secondAssert).forEach(str => {
expect(genChunkName(str, undefined, 'blog')).toBe(secondAssert[str]);
});
});

Expand Down Expand Up @@ -136,7 +136,7 @@ describe('load utils', () => {
};
const test = {arr: [1, 2, 3]};
const variable = 'enabledLanguages';
expect(idx(a, [('b', 'c')])).toBeUndefined();
expect(idx(a, ['b', 'c'])).toBeUndefined();
expect(idx(b, ['hello'])).toEqual('world');
expect(idx(b, 'hello')).toEqual('world');
expect(idx(obj, 'typo')).toBeUndefined();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@
* LICENSE file in the root directory of this source tree.
*/

const path = require('path');
const matter = require('gray-matter');
const {createHash} = require('crypto');

const _ = require(`lodash`);
const escapeStringRegexp = require('escape-string-regexp');
const fs = require('fs-extra');
import path from 'path';
import matter from 'gray-matter';
import {createHash} from 'crypto';
import _ from 'lodash';
import escapeStringRegexp from 'escape-string-regexp';
import fs from 'fs-extra';

const fileHash = new Map();
/**
* @param {string} generatedFilesDir
* @param {string} file
* @param {*} content
* @returns {Promise<void>}
*/
async function generate(generatedFilesDir, file, content) {
export async function generate(
generatedFilesDir: string,
file: string,
content: any,
): Promise<void> {
const filepath = path.join(generatedFilesDir, file);
const lastHash = fileHash.get(filepath);
const currentHash = createHash('md5')
Expand All @@ -38,21 +35,16 @@ const indexRE = /(^|.*\/)index\.(md|js)$/i;
const extRE = /\.(md|js)$/;

/**
* @param {string} file
* @returns {string}
* Convert filepath to url path. Example: 'index.md' -> '/', 'foo/bar.js' -> '/foo/bar',
*/
function fileToPath(file) {
export function fileToPath(file: string): string {
if (indexRE.test(file)) {
return file.replace(indexRE, '/$1');
}
return `/${file.replace(extRE, '').replace(/\\/g, '/')}`;
}

/**
* @param {string} userpath
* @returns {string}
*/
function encodePath(userpath) {
export function encodePath(userpath: string): string {
return userpath
.split('/')
.map(item => encodeURIComponent(item))
Expand All @@ -61,10 +53,8 @@ function encodePath(userpath) {

/**
* Given an input string, convert to kebab-case and append a hash. Avoid str collision
* @param {string} str input string
* @returns {string}
*/
function docuHash(str) {
export function docuHash(str: string): string {
if (str === '/') {
return 'index';
}
Expand All @@ -77,10 +67,8 @@ function docuHash(str) {

/**
* Generate unique React Component Name. E.g: /foo-bar -> FooBar096
* @param {string} pagePath
* @returns {string} unique react component name
*/
function genComponentName(pagePath) {
export function genComponentName(pagePath: string): string {
if (pagePath === '/') {
return 'index';
}
Expand All @@ -94,10 +82,8 @@ function genComponentName(pagePath) {

/**
* Convert Windows backslash paths to posix style paths. E.g: endi\\lie -> endi/lie
* @param {string} str windows backslash paths
* @returns {string} posix-style path
*/
function posixPath(str) {
export function posixPath(str: string): string {
const isExtendedLengthPath = /^\\\\\?\\/.test(str);
const hasNonAscii = /[^\u0000-\u0080]+/.test(str); // eslint-disable-line

Expand All @@ -110,12 +96,12 @@ function posixPath(str) {
const chunkNameCache = new Map();
/**
* Generate unique chunk name given a module path
* @param {string} modulePath
* @param {string=} prefix
* @param {string=} preferredName
* @returns {string}
*/
function genChunkName(modulePath, prefix, preferredName) {
export function genChunkName(
modulePath: string,
prefix?: string,
preferredName?: string,
): string {
let chunkName = chunkNameCache.get(modulePath);
if (!chunkName) {
let str = modulePath;
Expand All @@ -132,26 +118,21 @@ function genChunkName(modulePath, prefix, preferredName) {
}
return chunkName;
}
/**
* @param {*} target
* @param {string|string[]} keyPaths
* @returns {*}
*/
function idx(target, keyPaths) {

export function idx(target: any, keyPaths?: string | (string | number)[]): any {
return (
target &&
keyPaths &&
(Array.isArray(keyPaths)
? keyPaths.reduce((obj, key) => obj && obj[key], target)
: target[keyPaths])
);
}

/**
* @param {string} file
* @param {string} refDir
* @returns {string}
* Given a filepath and dirpath, get the first directory
*/
function getSubFolder(file, refDir) {
export function getSubFolder(file: string, refDir: string): string | null {
const separator = escapeStringRegexp(path.sep);
const baseDir = escapeStringRegexp(path.basename(refDir));
const regexSubFolder = new RegExp(
Expand All @@ -161,28 +142,28 @@ function getSubFolder(file, refDir) {
return match && match[1];
}

/**
* @param {string} fileString
* @returns {Object}
*/
function parse(fileString) {
const {data: frontMatter, content, excerpt} = matter(fileString, {
excerpt(file) {
// eslint-disable-next-line no-param-reassign
export function parse(
fileString: string,
): {
frontMatter: {
[key: string]: any,
},
content: string,
excerpt: string | undefined,
} {
const options: {} = {
excerpt: (file: matter.GrayMatterFile<string>): void => {
file.excerpt = file.content
.trim()
.split('\n', 1)
.shift();
},
});
};
const {data: frontMatter, content, excerpt} = matter(fileString, options);
return {frontMatter, content, excerpt};
}

/**
* @param {string[]} rawUrls
* @returns {string}
*/
function normalizeUrl(rawUrls) {
export function normalizeUrl(rawUrls: string[]): string {
const urls = rawUrls;
const resultArray = [];

Expand Down Expand Up @@ -242,17 +223,3 @@ function normalizeUrl(rawUrls) {

return str;
}

module.exports = {
encodePath,
docuHash,
generate,
fileToPath,
genComponentName,
genChunkName,
getSubFolder,
idx,
normalizeUrl,
parse,
posixPath,
};
7 changes: 7 additions & 0 deletions packages/docusaurus-utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib",
}
}
2 changes: 1 addition & 1 deletion packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"wait-on": "endiliey/wait-on#master",
"webpack": "^4.30.0",
"webpack-bundle-analyzer": "^3.1.0",
"webpack-dev-server": "^3.2.1",
"webpack-dev-server": "^3.4.1",
"webpack-merge": "^4.1.4",
"webpack-nicelog": "^2.3.1"
},
Expand Down
37 changes: 37 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": ["es6"],
"declaration": true,

/* Strict Type-Checking Options */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,

/* Additional Checks */
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,

/* Module Resolution Options */
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,

/* Advanced Options */
"resolveJsonModule": true
},
"exclude": [
"node_modules",
"**/__tests__/**/*",
"**/lib/**/*",
]
}
Loading

0 comments on commit cbd2a58

Please sign in to comment.