Skip to content

Commit

Permalink
feat(v2): Support swizzling TypeScript components
Browse files Browse the repository at this point in the history
  • Loading branch information
SamChou19815 committed Apr 27, 2020
1 parent 1d8cc4b commit 6d495db
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ packages/docusaurus-plugin-content-docs/lib/
packages/docusaurus-plugin-content-pages/lib/
packages/docusaurus-plugin-sitemap/lib/
packages/docusaurus-plugin-ideal-image/lib/
packages/docusaurus-theme-classic/lib/
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@types/react-dev-utils": "^9.0.1",
"@types/semver": "^7.1.0",
"@types/shelljs": "^0.8.6",
"@types/walk": "^2.3.0",
"@types/webpack": "^4.41.0",
"@types/webpack-dev-server": "^3.9.0",
"@types/webpack-merge": "^4.1.5",
Expand Down
10 changes: 10 additions & 0 deletions packages/docusaurus-theme-classic/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

module.exports = {
presets: [['@babel/preset-typescript', { isTSX: true, allExtensions: true }]],
};
7 changes: 7 additions & 0 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"access": "public"
},
"license": "MIT",
"scripts": {
"tsc": "babel src -d lib --extensions '.tsx' && prettier --config ../../.prettierrc --write \"lib/**/*.{js,ts}\""
},
"dependencies": {
"@mdx-js/mdx": "^1.5.8",
"@mdx-js/react": "^1.5.8",
Expand All @@ -19,6 +22,10 @@
"react-router-dom": "^5.1.2",
"react-toggle": "^4.1.1"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@docusaurus/module-type-aliases": "^2.0.0-alpha.50"
},
"peerDependencies": {
"@docusaurus/core": "^2.0.0",
"react": "^16.8.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import React, { ReactNode } from 'react';

function TabItem(props) {
function TabItem(props: { readonly children: ReactNode }) {
return <div>{props.children}</div>;
}

Expand Down
8 changes: 8 additions & 0 deletions packages/docusaurus-theme-classic/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/// <reference types="@docusaurus/module-type-aliases" />
13 changes: 13 additions & 0 deletions packages/docusaurus-theme-classic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
// This file is not used in compilation. It is here just for a nice editor experience.
"extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["DOM"],
"module": "esnext",
"noEmit": true,
"noImplicitAny": false,
"jsx": "react",
"baseUrl": "src"
},
"include": ["src/"]
}
5 changes: 3 additions & 2 deletions packages/docusaurus/bin/docusaurus.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ cli
cli
.command('swizzle <themeName> [componentName] [siteDir]')
.description('Copy the theme files into website folder for customization.')
.action((themeName, componentName, siteDir = '.') => {
wrapCommand(swizzle)(path.resolve(siteDir), themeName, componentName);
.option('--typescript', 'Copy TypeScript theme files when possible (default: false)')
.action((themeName, componentName, siteDir = '.', { typescript }) => {
wrapCommand(swizzle)(path.resolve(siteDir), themeName, componentName, typescript);
});

cli
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"std-env": "^2.2.1",
"terser-webpack-plugin": "^2.3.5",
"wait-file": "^1.0.5",
"walk": "^2.3.14",
"webpack": "^4.41.2",
"webpack-bundle-analyzer": "^3.6.1",
"webpack-dev-server": "^3.10.3",
Expand Down
70 changes: 58 additions & 12 deletions packages/docusaurus/src/commands/swizzle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,87 @@ import chalk = require('chalk');
import fs from 'fs-extra';
import importFresh from 'import-fresh';
import path from 'path';
import walk from 'walk';

import {THEME_PATH} from '../constants';
import {loadContext} from '../server';
import { THEME_PATH } from '../constants';
import { loadContext } from '../server';

export async function swizzle(
siteDir: string,
themeName: string,
componentName?: string,
typescript?: boolean
): Promise<void> {
const plugin: any = importFresh(themeName);
const context = loadContext(siteDir);
const pluginInstance = plugin(context);
let fromPath = pluginInstance.getThemePath();
const themePath = pluginInstance.getThemePath();
const libThemePath = path.join(themePath, '..', '..', 'lib', 'theme');
let fromPath = themePath;

if (fromPath) {
let toPath = path.resolve(siteDir, THEME_PATH);
const toThemePath = path.resolve(siteDir, THEME_PATH);
let toPath = toThemePath;
if (componentName) {
fromPath = path.join(fromPath, componentName);
toPath = path.join(toPath, componentName);

// Handle single JavaScript file only.
// E.g: if <fromPath> does not exist, we try to swizzle <fromPath>.js instead
if (!fs.existsSync(fromPath) && fs.existsSync(`${fromPath}.js`)) {
[fromPath, toPath] = [`${fromPath}.js`, `${toPath}.js`];
// Handle single TypeScript/JavaScript file only.
// E.g: if <fromPath> does not exist, we try to swizzle <fromPath>.(ts|tsx|js) instead
if (!fs.existsSync(fromPath)) {
if (fs.existsSync(`${fromPath}.ts`)) {
[fromPath, toPath] = [`${fromPath}.ts`, `${toPath}.ts`];
} else if (fs.existsSync(`${fromPath}.tsx`)) {
[fromPath, toPath] = [`${fromPath}.tsx`, `${toPath}.tsx`];
} else if (fs.existsSync(`${fromPath}.js`)) {
[fromPath, toPath] = [`${fromPath}.js`, `${toPath}.js`];
}
}
}
await fs.copy(fromPath, toPath);

// If the user doesn't want swizzle TypeScript components, we replace the swizzled TypeScript
// component by traspiled JavaScript.
if (!typescript) {
const replaceSwizzledTypeScriptWithJavaScript = async (
absoluteFilenameToRemove: string
): Promise<string> => {
const fileExtension = path.extname(absoluteFilenameToRemove);
if (fileExtension === '.ts' || fileExtension === '.tsx') {
const relativeTSPath = path.relative(toThemePath, absoluteFilenameToRemove);
const relativeJSPath = path.join(
path.dirname(relativeTSPath),
path.basename(relativeTSPath, fileExtension) + '.js'
);
const transpiledJSFromPath = path.join(libThemePath, relativeJSPath);
const transpiledJSToPath = path.join(toThemePath, relativeJSPath);
await fs.remove(absoluteFilenameToRemove);
await fs.copy(transpiledJSFromPath, transpiledJSToPath);
return transpiledJSToPath;
}
return toPath;
};

if (fs.lstatSync(toPath).isDirectory()) {
walk.walkSync(toPath, {
listeners: {
file: async (directory, fileStats, next) => {
const filename = path.join(directory, fileStats.name);
await replaceSwizzledTypeScriptWithJavaScript(filename);
next();
},
},
});
} else {
toPath = await replaceSwizzledTypeScriptWithJavaScript(toPath);
}
}

const relativeDir = path.relative(process.cwd(), toPath);
const fromMsg = chalk.blue(
componentName ? `${themeName} ${chalk.yellow(componentName)}` : themeName,
componentName ? `${themeName} ${chalk.yellow(componentName)}` : themeName
);
const toMsg = chalk.cyan(relativeDir);
console.log(
`\n${chalk.green('Success!')} Copied ${fromMsg} to ${toMsg}.\n`,
);
console.log(`\n${chalk.green('Success!')} Copied ${fromMsg} to ${toMsg}.\n`);
}
}
42 changes: 41 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
# yarn lockfile v1


"@babel/cli@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"
integrity sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==
dependencies:
commander "^4.0.1"
convert-source-map "^1.1.0"
fs-readdir-recursive "^1.1.0"
glob "^7.0.0"
lodash "^4.17.13"
make-dir "^2.1.0"
slash "^2.0.0"
source-map "^0.5.0"
optionalDependencies:
chokidar "^2.1.8"

"@babel/[email protected]":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
Expand Down Expand Up @@ -2798,6 +2814,13 @@
"@types/unist" "*"
"@types/vfile-message" "*"

"@types/walk@^2.3.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@types/walk/-/walk-2.3.0.tgz#1bfeb19f6fab63a1a39f929c0f2b4c02134468f8"
integrity sha512-I1w1RJW5kowe7JnekvVTSD/Lek8WK0N/Fz80n9Chnb5jYo+mne4tDthgCAV/Fo1tym9m8W6stfsJQvjRMpOHgw==
dependencies:
"@types/node" "*"

"@types/webpack-dev-server@*", "@types/webpack-dev-server@^3.9.0":
version "3.10.1"
resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz#93b7133cc9dab1ca1b76659f5ef8b763ad54c28a"
Expand Down Expand Up @@ -5143,7 +5166,7 @@ conventional-recommended-bump@^5.0.0:
meow "^4.0.0"
q "^1.5.1"

convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
Expand Down Expand Up @@ -7337,6 +7360,11 @@ foreach@^2.0.5:
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=

foreachasync@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6"
integrity sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=

forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
Expand Down Expand Up @@ -7449,6 +7477,11 @@ fs-minipass@^2.0.0:
dependencies:
minipass "^3.0.0"

fs-readdir-recursive@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==

fs-write-stream-atomic@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
Expand Down Expand Up @@ -17154,6 +17187,13 @@ wait-file@^1.0.5:
fs-extra "^8.1.0"
rx "^4.1.0"

walk@^2.3.14:
version "2.3.14"
resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.14.tgz#60ec8631cfd23276ae1e7363ce11d626452e1ef3"
integrity sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==
dependencies:
foreachasync "^3.0.0"

walker@^1.0.7, walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
Expand Down

0 comments on commit 6d495db

Please sign in to comment.