Skip to content

Commit 3548686

Browse files
feat(v2): Allow customization of js loader, replace babel by esbuild in Docusaurus website (facebook#4766)
* feat(v2): Allow customization of js loader * Change API * use esbuild for Docusaurus website * Enable isolatedModules: true * Revert "Enable isolatedModules: true" This reverts commit e656c35 Co-authored-by: slorber <lorber.sebastien@gmail.com>
1 parent c8812cf commit 3548686

12 files changed

Lines changed: 113 additions & 11 deletions

File tree

packages/docusaurus-theme-common/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"compilerOptions": {
44
"incremental": true,
55
"tsBuildInfoFile": "./lib/.tsbuildinfo",
6+
"module": "esnext",
67
"rootDir": "src",
78
"outDir": "lib"
89
}

packages/docusaurus-types/src/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export interface DocusaurusConfig {
6363
}
6464
)[];
6565
titleDelimiter?: string;
66+
webpack?: {
67+
jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule);
68+
};
6669
}
6770

6871
/**

packages/docusaurus/src/commands/build.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,14 @@ async function buildLocale({
187187
configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
188188
clientConfig,
189189
false,
190+
props.siteConfig.webpack?.jsLoader,
190191
);
191192

192193
serverConfig = applyConfigureWebpack(
193194
configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
194195
serverConfig,
195196
true,
197+
props.siteConfig.webpack?.jsLoader,
196198
);
197199
}
198200
});

packages/docusaurus/src/commands/start.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export default async function start(
153153
configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
154154
config,
155155
false,
156+
props.siteConfig.webpack?.jsLoader,
156157
);
157158
}
158159
});

packages/docusaurus/src/server/configValidation.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ const ConfigSchema = Joi.object({
134134
tagline: Joi.string().allow(''),
135135
titleDelimiter: Joi.string().default('|'),
136136
noIndex: Joi.bool().default(false),
137+
webpack: Joi.object({
138+
jsLoader: Joi.alternatives()
139+
.try(Joi.string().equal('babel'), Joi.function())
140+
.optional(),
141+
}).optional(),
137142
});
138143

139144
// TODO move to @docusaurus/utils-validation

packages/docusaurus/src/webpack/__tests__/base.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ describe('base webpack config', () => {
8181
const props = {
8282
outDir: '',
8383
siteDir: '',
84+
siteConfig: {},
8485
baseUrl: '',
8586
generatedFilesDir: '',
8687
routesPaths: '',

packages/docusaurus/src/webpack/__tests__/utils.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
import {validate, Configuration} from 'webpack';
8+
import {validate, Configuration, RuleSetRule} from 'webpack';
99
import path from 'path';
1010

1111
import {
12+
getCustomizableJSLoader,
1213
applyConfigureWebpack,
1314
applyConfigurePostCss,
1415
getFileLoaderUtils,
@@ -18,6 +19,40 @@ import {
1819
ConfigureWebpackFnMergeStrategy,
1920
} from '@docusaurus/types';
2021

22+
describe('customize JS loader', () => {
23+
test('getCustomizableJSLoader defaults to babel loader', () => {
24+
expect(getCustomizableJSLoader()({isServer: true}).loader).toBe(
25+
require.resolve('babel-loader'),
26+
);
27+
expect(getCustomizableJSLoader()({isServer: false}).loader).toBe(
28+
require.resolve('babel-loader'),
29+
);
30+
});
31+
32+
test('getCustomizableJSLoader accepts loaders with preset', () => {
33+
expect(getCustomizableJSLoader('babel')({isServer: true}).loader).toBe(
34+
require.resolve('babel-loader'),
35+
);
36+
expect(getCustomizableJSLoader('babel')({isServer: false}).loader).toBe(
37+
require.resolve('babel-loader'),
38+
);
39+
});
40+
41+
test('getCustomizableJSLoader allows customization', () => {
42+
const customJSLoader = (isServer: boolean): RuleSetRule => ({
43+
loader: 'my-fast-js-loader',
44+
options: String(isServer),
45+
});
46+
47+
expect(getCustomizableJSLoader(customJSLoader)({isServer: true})).toEqual(
48+
customJSLoader(true),
49+
);
50+
expect(getCustomizableJSLoader(customJSLoader)({isServer: false})).toEqual(
51+
customJSLoader(false),
52+
);
53+
});
54+
});
55+
2156
describe('extending generated webpack config', () => {
2257
test('direct mutation on generated webpack config object', async () => {
2358
// fake generated webpack config

packages/docusaurus/src/webpack/base.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import path from 'path';
1111
import {Configuration} from 'webpack';
1212
import {Props} from '@docusaurus/types';
1313
import {
14-
getJSLoader,
14+
getCustomizableJSLoader,
1515
getStyleLoaders,
1616
getFileLoaderUtils,
1717
getCustomBabelConfigFilePath,
@@ -73,6 +73,7 @@ export function createBaseConfig(
7373
const {
7474
outDir,
7575
siteDir,
76+
siteConfig,
7677
baseUrl,
7778
generatedFilesDir,
7879
routesPaths,
@@ -205,7 +206,7 @@ export function createBaseConfig(
205206
test: /\.(j|t)sx?$/,
206207
exclude: excludeJS,
207208
use: [
208-
getJSLoader({
209+
getCustomizableJSLoader(siteConfig.webpack?.jsLoader)({
209210
isServer,
210211
babelOptions: getCustomBabelConfigFilePath(siteDir),
211212
}),

packages/docusaurus/src/webpack/utils.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function getBabelOptions({
137137

138138
// Name is generic on purpose
139139
// we want to support multiple js loader implementations (babel + esbuild)
140-
export function getJSLoader({
140+
function getDefaultBabelLoader({
141141
isServer,
142142
babelOptions,
143143
}: {
@@ -150,6 +150,19 @@ export function getJSLoader({
150150
};
151151
}
152152

153+
export const getCustomizableJSLoader = (
154+
jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule) = 'babel',
155+
) => ({
156+
isServer,
157+
babelOptions,
158+
}: {
159+
isServer: boolean;
160+
babelOptions?: TransformOptions | string;
161+
}): RuleSetRule =>
162+
jsLoader === 'babel'
163+
? getDefaultBabelLoader({isServer, babelOptions})
164+
: jsLoader(isServer);
165+
153166
// TODO remove this before end of 2021?
154167
const warnBabelLoaderOnce = memoize(function () {
155168
console.warn(
@@ -163,7 +176,7 @@ const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
163176
babelOptions?: TransformOptions | string,
164177
) {
165178
warnBabelLoaderOnce();
166-
return getJSLoader({isServer, babelOptions});
179+
return getDefaultBabelLoader({isServer, babelOptions});
167180
};
168181

169182
// TODO remove this before end of 2021 ?
@@ -184,17 +197,19 @@ function getCacheLoaderDeprecated() {
184197
* @param configureWebpack a webpack config or a function to modify config
185198
* @param config initial webpack config
186199
* @param isServer indicates if this is a server webpack configuration
200+
* @param jsLoader custom js loader config
187201
* @returns final/ modified webpack config
188202
*/
189203
export function applyConfigureWebpack(
190204
configureWebpack: ConfigureWebpackFn,
191205
config: Configuration,
192206
isServer: boolean,
207+
jsLoader?: 'babel' | ((isServer: boolean) => RuleSetRule),
193208
): Configuration {
194209
// Export some utility functions
195210
const utils: ConfigureWebpackUtils = {
196211
getStyleLoaders,
197-
getJSLoader,
212+
getJSLoader: getCustomizableJSLoader(jsLoader),
198213
getBabelLoader: getBabelLoaderDeprecated,
199214
getCacheLoader: getCacheLoaderDeprecated,
200215
};

website/docusaurus.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ const isVersioningDisabled = !!process.env.DISABLE_VERSIONING || isI18nStaging;
6363
: // Production locales
6464
['en', 'fr', 'ko', 'zh-CN'],
6565
},
66+
webpack: {
67+
jsLoader: (isServer) => ({
68+
loader: require.resolve('esbuild-loader'),
69+
options: {
70+
loader: 'tsx',
71+
format: isServer ? 'cjs' : undefined,
72+
target: isServer ? 'node12' : 'es2017',
73+
},
74+
}),
75+
},
6676
onBrokenLinks: 'throw',
6777
onBrokenMarkdownLinks: 'warn',
6878
favicon: 'img/docusaurus.ico',

0 commit comments

Comments
 (0)