Skip to content

Commit

Permalink
feat(core): faster transpiler option - `siteConfig.future.experimenta…
Browse files Browse the repository at this point in the history
…l_faster.swcJsLoader` (#10435)
  • Loading branch information
slorber authored Aug 23, 2024
1 parent 349a584 commit 418247e
Show file tree
Hide file tree
Showing 30 changed files with 1,314 additions and 863 deletions.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"build:website:deployPreview:build": "cross-env NETLIFY=true CONTEXT='deploy-preview' yarn workspace website build",
"build:website:deployPreview": "yarn build:website:deployPreview:testWrap && yarn build:website:deployPreview:build",
"build:website:fast": "yarn workspace website build:fast",
"build:website:fast:rsdoctor": "yarn workspace website build:fast:rsdoctor",
"build:website:fast:profile": "yarn workspace website build:fast:profile",
"build:website:en": "yarn workspace website build --locale en",
"clear:website": "yarn workspace website clear",
Expand Down Expand Up @@ -70,11 +71,11 @@
"devDependencies": {
"@crowdin/cli": "^3.13.0",
"@prettier/plugin-xml": "^2.2.0",
"@swc/core": "1.2.197",
"@swc/jest": "^0.2.26",
"@swc/core": "^1.7.14",
"@swc/jest": "^0.2.36",
"@testing-library/react-hooks": "^8.0.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.5.3",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.197",
"@types/node": "^18.16.19",
"@types/prompts": "^2.4.4",
Expand All @@ -99,9 +100,9 @@
"eslint-plugin-regexp": "^1.15.0",
"husky": "^8.0.3",
"image-size": "^1.0.2",
"jest": "^29.6.1",
"jest-environment-jsdom": "^29.6.1",
"jest-serializer-ansi-escapes": "^2.0.1",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-serializer-ansi-escapes": "^3.0.0",
"jest-serializer-react-helmet-async": "^1.0.21",
"lerna": "^6.6.2",
"lerna-changelog": "^2.2.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/docusaurus-faster/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.tsbuildinfo*
tsconfig*
__tests__
3 changes: 3 additions & 0 deletions packages/docusaurus-faster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `@docusaurus/faster`

Docusaurus experimental package exposing new modern dependencies to make the build faster.
31 changes: 31 additions & 0 deletions packages/docusaurus-faster/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@docusaurus/faster",
"version": "3.5.2",
"description": "Docusaurus experimental package exposing new modern dependencies to make the build faster.",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/facebook/docusaurus.git",
"directory": "packages/docusaurus-faster"
},
"license": "MIT",
"dependencies": {
"webpack": "^5.88.1",
"@swc/core": "^1.7.14",
"swc-loader": "^0.2.6"
},
"engines": {
"node": ">=18.0"
},
"peerDependencies": {
"@docusaurus/types": "*"
}
}
35 changes: 35 additions & 0 deletions packages/docusaurus-faster/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 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.
*/

import type {RuleSetRule} from 'webpack';

export function getSwcJsLoaderFactory({
isServer,
}: {
isServer: boolean;
}): RuleSetRule {
return {
loader: require.resolve('swc-loader'),
options: {
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
},
transform: {
react: {
runtime: 'automatic',
},
},
target: 'es2017',
},
module: {
type: isServer ? 'commonjs' : 'es6',
},
},
};
}
10 changes: 10 additions & 0 deletions packages/docusaurus-faster/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"noEmit": false,
"sourceMap": true,
"declarationMap": true
},
"include": ["src"],
"exclude": ["**/__tests__/**"]
}
Binary file modified packages/docusaurus-plugin-content-docs/src/__tests__/cli.test.ts
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {isMatch} from 'picomatch';
import commander from 'commander';
import webpack from 'webpack';
import {loadContext} from '@docusaurus/core/src/server/site';
import {applyConfigureWebpack} from '@docusaurus/core/src/webpack/configure';
import {
applyConfigureWebpack,
createConfigureWebpackUtils,
} from '@docusaurus/core/src/webpack/configure';
import {sortRoutes} from '@docusaurus/core/src/server/plugins/routeConfig';
import {posixPath} from '@docusaurus/utils';
import {normalizePluginOptions} from '@docusaurus/utils-validation';
Expand All @@ -22,7 +25,7 @@ import pluginContentDocs from '../index';
import {toSidebarsProp} from '../props';
import {DefaultSidebarItemsGenerator} from '../sidebars/generator';
import {DisabledSidebars} from '../sidebars';
import * as cliDocs from '../cli';
import cliDocs from '../cli';
import {validateOptions} from '../options';

import type {RouteConfig, Validate, Plugin} from '@docusaurus/types';
Expand Down Expand Up @@ -273,19 +276,23 @@ describe('simple website', () => {

const content = await plugin.loadContent?.();

const config = applyConfigureWebpack(
plugin.configureWebpack as NonNullable<Plugin['configureWebpack']>,
{
const config = applyConfigureWebpack({
configureWebpack: plugin.configureWebpack as NonNullable<
Plugin['configureWebpack']
>,
config: {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
},
false,
undefined,
isServer: false,
utils: createConfigureWebpackUtils({
siteConfig: {webpack: {jsLoader: 'babel'}},
}),
content,
);
});
const errors = webpack.validate(config);
expect(errors).toBeUndefined();
});
Expand Down
16 changes: 15 additions & 1 deletion packages/docusaurus-plugin-content-docs/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async function createVersionedSidebarFile({
}

// Tests depend on non-default export for mocking.
export async function cliDocsVersionCommand(
async function cliDocsVersionCommand(
version: unknown,
{id: pluginId, path: docsPath, sidebarPath}: PluginOptions,
{siteDir, i18n}: LoadContext,
Expand Down Expand Up @@ -142,3 +142,17 @@ export async function cliDocsVersionCommand(

logger.success`name=${pluginIdLogPrefix}: version name=${version} created!`;
}

// TODO try to remove this workaround
// Why use a default export instead of named exports here?
// This is only to make Jest mocking happy
// After upgrading Jest/SWC we got this weird mocking error in extendCli tests
// "spyOn: Cannot redefine property cliDocsVersionCommand"
// I tried various workarounds, and it's the only one that worked :/
// See also:
// - https://pyk.sh/fixing-typeerror-cannot-redefine-property-x-error-in-jest-tests#heading-solution-2-using-barrel-imports
// - https://github.com/aelbore/esbuild-jest/issues/26
// - https://stackoverflow.com/questions/67872622/jest-spyon-not-working-on-index-file-cannot-redefine-property/69951703#69951703
export default {
cliDocsVersionCommand,
};
4 changes: 2 additions & 2 deletions packages/docusaurus-plugin-content-docs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
readVersionsMetadata,
toFullVersion,
} from './versions';
import {cliDocsVersionCommand} from './cli';
import cliDocs from './cli';
import {VERSIONS_JSON_FILE} from './constants';
import {toGlobalDataVersion} from './globalData';
import {
Expand Down Expand Up @@ -134,7 +134,7 @@ export default async function pluginContentDocs(
.arguments('<version>')
.description(commandDescription)
.action((version: unknown) =>
cliDocsVersionCommand(version, options, context),
cliDocs.cliDocsVersionCommand(version, options, context),
);
},

Expand Down
27 changes: 23 additions & 4 deletions packages/docusaurus-types/src/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type {SiteStorage} from './context';
import type {RuleSetRule} from 'webpack';
import type {Required as RequireKeys, DeepPartial} from 'utility-types';
import type {DeepPartial, Overwrite} from 'utility-types';
import type {I18nConfig} from './i18n';
import type {PluginConfig, PresetConfig, HtmlTagObject} from './plugin';

Expand Down Expand Up @@ -123,7 +123,13 @@ export type StorageConfig = {
namespace: boolean | string;
};

export type FasterConfig = {
swcJsLoader: boolean;
};

export type FutureConfig = {
experimental_faster: FasterConfig;

experimental_storage: StorageConfig;

/**
Expand Down Expand Up @@ -416,18 +422,31 @@ export type DocusaurusConfig = {
* Babel loader and preset; otherwise, you can provide your custom Webpack
* rule set.
*/
// TODO Docusaurus v4
// Use an object type ({isServer}) so that it conforms to jsLoaderFactory
// Eventually deprecate this if swc loader becomes stable?
jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule);
};
/** Markdown-related options. */
markdown: MarkdownConfig;
};

/**
* Docusaurus config, as provided by the user (partial/unnormalized). This type
* Docusaurus config, as provided by the user (partial/un-normalized). This type
* is used to provide type-safety / IDE auto-complete on the config file.
* @see https://docusaurus.io/docs/typescript-support
*/
export type Config = RequireKeys<
export type Config = Overwrite<
DeepPartial<DocusaurusConfig>,
'title' | 'url' | 'baseUrl'
{
title: DocusaurusConfig['title'];
url: DocusaurusConfig['url'];
baseUrl: DocusaurusConfig['baseUrl'];
future?: Overwrite<
DeepPartial<FutureConfig>,
{
experimental_faster?: boolean | FasterConfig;
}
>;
}
>;
9 changes: 6 additions & 3 deletions packages/docusaurus-types/src/plugin.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export type ConfigureWebpackUtils = {
) => RuleSetRule[];
getJSLoader: (options: {
isServer: boolean;
babelOptions?: {[key: string]: unknown};
// TODO Docusaurus v4 remove?
// not ideal because JS Loader might not use Babel...
babelOptions?: string | {[key: string]: unknown};
}) => RuleSetRule;
};

Expand Down Expand Up @@ -122,8 +124,9 @@ export type Plugin<Content = unknown> = {
head: {[location: string]: HelmetServerState};
},
) => Promise<void> | void;
// TODO refactor the configureWebpack API surface: use an object instead of
// multiple params (requires breaking change)
// TODO Docusaurus v4 ?
// refactor the configureWebpack API surface: use an object instead of
// multiple params (requires breaking change)
configureWebpack?: (
config: WebpackConfiguration,
isServer: boolean,
Expand Down
6 changes: 6 additions & 0 deletions packages/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,16 @@
"tree-node-cli": "^1.6.0"
},
"peerDependencies": {
"@docusaurus/faster": "3.5.2",
"@mdx-js/react": "^3.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependenciesMeta": {
"@docusaurus/faster": {
"optional": true
}
},
"engines": {
"node": ">=18.0"
}
Expand Down
13 changes: 10 additions & 3 deletions packages/docusaurus/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {handleBrokenLinks} from '../server/brokenLinks';

import {createBuildClientConfig} from '../webpack/client';
import createServerConfig from '../webpack/server';
import {executePluginsConfigureWebpack} from '../webpack/configure';
import {
createConfigureWebpackUtils,
executePluginsConfigureWebpack,
} from '../webpack/configure';
import {compile} from '../webpack/utils';
import {PerfLogger} from '../utils';

Expand Down Expand Up @@ -338,7 +341,9 @@ async function getBuildClientConfig({
plugins,
config,
isServer: false,
jsLoader: props.siteConfig.webpack?.jsLoader,
utils: await createConfigureWebpackUtils({
siteConfig: props.siteConfig,
}),
});
return {clientConfig: config, clientManifestPath: result.clientManifestPath};
}
Expand All @@ -353,7 +358,9 @@ async function getBuildServerConfig({props}: {props: Props}) {
plugins,
config,
isServer: true,
jsLoader: props.siteConfig.webpack?.jsLoader,
utils: await createConfigureWebpackUtils({
siteConfig: props.siteConfig,
}),
});
return {serverConfig: config, serverBundlePath: result.serverBundlePath};
}
Expand Down
7 changes: 5 additions & 2 deletions packages/docusaurus/src/commands/start/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import {
getHttpsConfig,
printStatsWarnings,
} from '../../webpack/utils';
import {executePluginsConfigureWebpack} from '../../webpack/configure';
import {
createConfigureWebpackUtils,
executePluginsConfigureWebpack,
} from '../../webpack/configure';
import {createStartClientConfig} from '../../webpack/client';
import type {StartCLIOptions} from './start';
import type {Props} from '@docusaurus/types';
Expand Down Expand Up @@ -139,7 +142,7 @@ async function getStartClientConfig({
plugins,
config,
isServer: false,
jsLoader: siteConfig.webpack?.jsLoader,
utils: await createConfigureWebpackUtils({siteConfig}),
});
return config;
}
Expand Down
Loading

0 comments on commit 418247e

Please sign in to comment.