mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
feat(core): faster JS minimizer - siteConfig.future.experimental_faster.swcJsMinimizer
(#10441)
This commit is contained in:
parent
aa65f39d8c
commit
bb90e35153
19 changed files with 202 additions and 36 deletions
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {RuleSetRule} from 'webpack';
|
import type {RuleSetRule} from 'webpack';
|
||||||
|
import type {JsMinifyOptions} from '@swc/core';
|
||||||
|
|
||||||
export function getSwcJsLoaderFactory({
|
export function getSwcJsLoaderFactory({
|
||||||
isServer,
|
isServer,
|
||||||
|
@ -33,3 +34,24 @@ export function getSwcJsLoaderFactory({
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: these options are similar to what we use in core
|
||||||
|
// They should rather be kept in sync for now to avoid any unexpected behavior
|
||||||
|
// The goal of faster minifier is not to fine-tune options but only to be faster
|
||||||
|
// See core minification.ts
|
||||||
|
export function getSwcJsMinifierOptions(): JsMinifyOptions {
|
||||||
|
return {
|
||||||
|
ecma: 2020,
|
||||||
|
compress: {
|
||||||
|
ecma: 5,
|
||||||
|
},
|
||||||
|
module: true,
|
||||||
|
mangle: true,
|
||||||
|
safari10: true,
|
||||||
|
format: {
|
||||||
|
ecma: 5,
|
||||||
|
comments: false,
|
||||||
|
ascii_only: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
1
packages/docusaurus-types/src/config.d.ts
vendored
1
packages/docusaurus-types/src/config.d.ts
vendored
|
@ -125,6 +125,7 @@ export type StorageConfig = {
|
||||||
|
|
||||||
export type FasterConfig = {
|
export type FasterConfig = {
|
||||||
swcJsLoader: boolean;
|
swcJsLoader: boolean;
|
||||||
|
swcJsMinimizer: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FutureConfig = {
|
export type FutureConfig = {
|
||||||
|
|
1
packages/docusaurus-types/src/index.d.ts
vendored
1
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -14,6 +14,7 @@ export {
|
||||||
ParseFrontMatter,
|
ParseFrontMatter,
|
||||||
DocusaurusConfig,
|
DocusaurusConfig,
|
||||||
FutureConfig,
|
FutureConfig,
|
||||||
|
FasterConfig,
|
||||||
StorageConfig,
|
StorageConfig,
|
||||||
Config,
|
Config,
|
||||||
} from './config';
|
} from './config';
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
"serve-handler": "^6.1.5",
|
"serve-handler": "^6.1.5",
|
||||||
"shelljs": "^0.8.5",
|
"shelljs": "^0.8.5",
|
||||||
"terser-webpack-plugin": "^5.3.9",
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
"tslib": "^2.6.0",
|
"tslib": "^2.6.0",
|
||||||
"update-notifier": "^6.0.2",
|
"update-notifier": "^6.0.2",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
|
|
|
@ -334,6 +334,7 @@ async function getBuildClientConfig({
|
||||||
const result = await createBuildClientConfig({
|
const result = await createBuildClientConfig({
|
||||||
props,
|
props,
|
||||||
minify: cliOptions.minify ?? true,
|
minify: cliOptions.minify ?? true,
|
||||||
|
faster: props.siteConfig.future.experimental_faster,
|
||||||
bundleAnalyzer: cliOptions.bundleAnalyzer ?? false,
|
bundleAnalyzer: cliOptions.bundleAnalyzer ?? false,
|
||||||
});
|
});
|
||||||
let {config} = result;
|
let {config} = result;
|
||||||
|
|
|
@ -136,6 +136,7 @@ async function getStartClientConfig({
|
||||||
let {clientConfig: config} = await createStartClientConfig({
|
let {clientConfig: config} = await createStartClientConfig({
|
||||||
props,
|
props,
|
||||||
minify,
|
minify,
|
||||||
|
faster: props.siteConfig.future.experimental_faster,
|
||||||
poll,
|
poll,
|
||||||
});
|
});
|
||||||
config = executePluginsConfigureWebpack({
|
config = executePluginsConfigureWebpack({
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {ConfigureWebpackUtils} from '@docusaurus/types';
|
import type {ConfigureWebpackUtils} from '@docusaurus/types';
|
||||||
|
import type {MinimizerOptions, CustomOptions} from 'terser-webpack-plugin';
|
||||||
|
|
||||||
async function importFaster() {
|
async function importFaster() {
|
||||||
return import('@docusaurus/faster');
|
return import('@docusaurus/faster');
|
||||||
|
@ -22,9 +23,16 @@ async function ensureFaster() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSwcJsLoaderFactory(): Promise<
|
export async function importSwcJsLoaderFactory(): Promise<
|
||||||
ConfigureWebpackUtils['getJSLoader']
|
ConfigureWebpackUtils['getJSLoader']
|
||||||
> {
|
> {
|
||||||
const faster = await ensureFaster();
|
const faster = await ensureFaster();
|
||||||
return faster.getSwcJsLoaderFactory;
|
return faster.getSwcJsLoaderFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function importSwcJsMinifierOptions(): Promise<
|
||||||
|
MinimizerOptions<CustomOptions>
|
||||||
|
> {
|
||||||
|
const faster = await ensureFaster();
|
||||||
|
return faster.getSwcJsMinifierOptions() as MinimizerOptions<CustomOptions>;
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -74,6 +75,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -138,6 +140,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -202,6 +205,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -266,6 +270,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -330,6 +335,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -394,6 +400,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -460,6 +467,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -526,6 +534,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
@ -595,6 +604,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
|
|
@ -80,6 +80,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
|
||||||
"future": {
|
"future": {
|
||||||
"experimental_faster": {
|
"experimental_faster": {
|
||||||
"swcJsLoader": false,
|
"swcJsLoader": false,
|
||||||
|
"swcJsMinimizer": false,
|
||||||
},
|
},
|
||||||
"experimental_router": "browser",
|
"experimental_router": "browser",
|
||||||
"experimental_storage": {
|
"experimental_storage": {
|
||||||
|
|
|
@ -47,6 +47,7 @@ describe('normalizeConfig', () => {
|
||||||
future: {
|
future: {
|
||||||
experimental_faster: {
|
experimental_faster: {
|
||||||
swcJsLoader: true,
|
swcJsLoader: true,
|
||||||
|
swcJsMinimizer: true,
|
||||||
},
|
},
|
||||||
experimental_storage: {
|
experimental_storage: {
|
||||||
type: 'sessionStorage',
|
type: 'sessionStorage',
|
||||||
|
@ -741,6 +742,7 @@ describe('future', () => {
|
||||||
const future: DocusaurusConfig['future'] = {
|
const future: DocusaurusConfig['future'] = {
|
||||||
experimental_faster: {
|
experimental_faster: {
|
||||||
swcJsLoader: true,
|
swcJsLoader: true,
|
||||||
|
swcJsMinimizer: true,
|
||||||
},
|
},
|
||||||
experimental_storage: {
|
experimental_storage: {
|
||||||
type: 'sessionStorage',
|
type: 'sessionStorage',
|
||||||
|
@ -1200,5 +1202,75 @@ describe('future', () => {
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('swcJsMinimizer', () => {
|
||||||
|
it('accepts - undefined', () => {
|
||||||
|
const faster: Partial<FasterConfig> = {
|
||||||
|
swcJsMinimizer: undefined,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
normalizeConfig({
|
||||||
|
future: {
|
||||||
|
experimental_faster: faster,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toEqual(fasterContaining({swcJsMinimizer: false}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts - true', () => {
|
||||||
|
const faster: Partial<FasterConfig> = {
|
||||||
|
swcJsMinimizer: true,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
normalizeConfig({
|
||||||
|
future: {
|
||||||
|
experimental_faster: faster,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toEqual(fasterContaining({swcJsMinimizer: true}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts - false', () => {
|
||||||
|
const faster: Partial<FasterConfig> = {
|
||||||
|
swcJsMinimizer: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
normalizeConfig({
|
||||||
|
future: {
|
||||||
|
experimental_faster: faster,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toEqual(fasterContaining({swcJsMinimizer: false}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects - null', () => {
|
||||||
|
// @ts-expect-error: invalid
|
||||||
|
const faster: Partial<FasterConfig> = {swcJsMinimizer: 42};
|
||||||
|
expect(() =>
|
||||||
|
normalizeConfig({
|
||||||
|
future: {
|
||||||
|
experimental_faster: faster,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""future.experimental_faster.swcJsMinimizer" must be a boolean
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects - number', () => {
|
||||||
|
// @ts-expect-error: invalid
|
||||||
|
const faster: Partial<FasterConfig> = {swcJsMinimizer: 42};
|
||||||
|
expect(() =>
|
||||||
|
normalizeConfig({
|
||||||
|
future: {
|
||||||
|
experimental_faster: faster,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""future.experimental_faster.swcJsMinimizer" must be a boolean
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,11 +43,13 @@ export const DEFAULT_STORAGE_CONFIG: StorageConfig = {
|
||||||
|
|
||||||
export const DEFAULT_FASTER_CONFIG: FasterConfig = {
|
export const DEFAULT_FASTER_CONFIG: FasterConfig = {
|
||||||
swcJsLoader: false,
|
swcJsLoader: false,
|
||||||
|
swcJsMinimizer: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When using the "faster: true" shortcut
|
// When using the "faster: true" shortcut
|
||||||
export const DEFAULT_FASTER_CONFIG_TRUE: FasterConfig = {
|
export const DEFAULT_FASTER_CONFIG_TRUE: FasterConfig = {
|
||||||
swcJsLoader: true,
|
swcJsLoader: true,
|
||||||
|
swcJsMinimizer: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_FUTURE_CONFIG: FutureConfig = {
|
export const DEFAULT_FUTURE_CONFIG: FutureConfig = {
|
||||||
|
@ -212,6 +214,9 @@ const FASTER_CONFIG_SCHEMA = Joi.alternatives()
|
||||||
.try(
|
.try(
|
||||||
Joi.object<FasterConfig>({
|
Joi.object<FasterConfig>({
|
||||||
swcJsLoader: Joi.boolean().default(DEFAULT_FASTER_CONFIG.swcJsLoader),
|
swcJsLoader: Joi.boolean().default(DEFAULT_FASTER_CONFIG.swcJsLoader),
|
||||||
|
swcJsMinimizer: Joi.boolean().default(
|
||||||
|
DEFAULT_FASTER_CONFIG.swcJsMinimizer,
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
Joi.boolean()
|
Joi.boolean()
|
||||||
.required()
|
.required()
|
||||||
|
|
|
@ -11,7 +11,10 @@ import _ from 'lodash';
|
||||||
import * as utils from '@docusaurus/utils/lib/webpackUtils';
|
import * as utils from '@docusaurus/utils/lib/webpackUtils';
|
||||||
import {posixPath} from '@docusaurus/utils';
|
import {posixPath} from '@docusaurus/utils';
|
||||||
import {excludeJS, clientDir, createBaseConfig} from '../base';
|
import {excludeJS, clientDir, createBaseConfig} from '../base';
|
||||||
import {DEFAULT_FUTURE_CONFIG} from '../../server/configValidation';
|
import {
|
||||||
|
DEFAULT_FASTER_CONFIG,
|
||||||
|
DEFAULT_FUTURE_CONFIG,
|
||||||
|
} from '../../server/configValidation';
|
||||||
import type {Props} from '@docusaurus/types';
|
import type {Props} from '@docusaurus/types';
|
||||||
|
|
||||||
describe('babel transpilation exclude logic', () => {
|
describe('babel transpilation exclude logic', () => {
|
||||||
|
@ -107,7 +110,12 @@ describe('base webpack config', () => {
|
||||||
|
|
||||||
it('creates webpack aliases', async () => {
|
it('creates webpack aliases', async () => {
|
||||||
const aliases = ((
|
const aliases = ((
|
||||||
await createBaseConfig({props, isServer: true, minify: true})
|
await createBaseConfig({
|
||||||
|
props,
|
||||||
|
isServer: true,
|
||||||
|
minify: true,
|
||||||
|
faster: DEFAULT_FASTER_CONFIG,
|
||||||
|
})
|
||||||
).resolve?.alias ?? {}) as {[alias: string]: string};
|
).resolve?.alias ?? {}) as {[alias: string]: string};
|
||||||
// Make aliases relative so that test work on all computers
|
// Make aliases relative so that test work on all computers
|
||||||
const relativeAliases = _.mapValues(aliases, (a) =>
|
const relativeAliases = _.mapValues(aliases, (a) =>
|
||||||
|
@ -123,7 +131,12 @@ describe('base webpack config', () => {
|
||||||
.spyOn(utils, 'getFileLoaderUtils')
|
.spyOn(utils, 'getFileLoaderUtils')
|
||||||
.mockImplementation(() => fileLoaderUtils);
|
.mockImplementation(() => fileLoaderUtils);
|
||||||
|
|
||||||
await createBaseConfig({props, isServer: false, minify: false});
|
await createBaseConfig({
|
||||||
|
props,
|
||||||
|
isServer: false,
|
||||||
|
minify: false,
|
||||||
|
faster: DEFAULT_FASTER_CONFIG,
|
||||||
|
});
|
||||||
expect(mockSvg).toHaveBeenCalled();
|
expect(mockSvg).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,10 +14,10 @@ import {
|
||||||
getStyleLoaders,
|
getStyleLoaders,
|
||||||
getCustomBabelConfigFilePath,
|
getCustomBabelConfigFilePath,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import {getMinimizer} from './minification';
|
import {getMinimizers} from './minification';
|
||||||
import {loadThemeAliases, loadDocusaurusAliases} from './aliases';
|
import {loadThemeAliases, loadDocusaurusAliases} from './aliases';
|
||||||
import type {Configuration} from 'webpack';
|
import type {Configuration} from 'webpack';
|
||||||
import type {Props} from '@docusaurus/types';
|
import type {FasterConfig, Props} from '@docusaurus/types';
|
||||||
|
|
||||||
const CSS_REGEX = /\.css$/i;
|
const CSS_REGEX = /\.css$/i;
|
||||||
const CSS_MODULE_REGEX = /\.module\.css$/i;
|
const CSS_MODULE_REGEX = /\.module\.css$/i;
|
||||||
|
@ -57,10 +57,12 @@ export async function createBaseConfig({
|
||||||
props,
|
props,
|
||||||
isServer,
|
isServer,
|
||||||
minify,
|
minify,
|
||||||
|
faster,
|
||||||
}: {
|
}: {
|
||||||
props: Props;
|
props: Props;
|
||||||
isServer: boolean;
|
isServer: boolean;
|
||||||
minify: boolean;
|
minify: boolean;
|
||||||
|
faster: FasterConfig;
|
||||||
}): Promise<Configuration> {
|
}): Promise<Configuration> {
|
||||||
const {
|
const {
|
||||||
outDir,
|
outDir,
|
||||||
|
@ -172,7 +174,7 @@ export async function createBaseConfig({
|
||||||
// Only minimize client bundle in production because server bundle is only
|
// Only minimize client bundle in production because server bundle is only
|
||||||
// used for static site generation
|
// used for static site generation
|
||||||
minimize: minimizeEnabled,
|
minimize: minimizeEnabled,
|
||||||
minimizer: minimizeEnabled ? getMinimizer() : undefined,
|
minimizer: minimizeEnabled ? await getMinimizers({faster}) : undefined,
|
||||||
splitChunks: isServer
|
splitChunks: isServer
|
||||||
? false
|
? false
|
||||||
: {
|
: {
|
||||||
|
|
|
@ -17,19 +17,26 @@ import ChunkAssetPlugin from './plugins/ChunkAssetPlugin';
|
||||||
import CleanWebpackPlugin from './plugins/CleanWebpackPlugin';
|
import CleanWebpackPlugin from './plugins/CleanWebpackPlugin';
|
||||||
import ForceTerminatePlugin from './plugins/ForceTerminatePlugin';
|
import ForceTerminatePlugin from './plugins/ForceTerminatePlugin';
|
||||||
import {createStaticDirectoriesCopyPlugin} from './plugins/StaticDirectoriesCopyPlugin';
|
import {createStaticDirectoriesCopyPlugin} from './plugins/StaticDirectoriesCopyPlugin';
|
||||||
import type {Props} from '@docusaurus/types';
|
import type {FasterConfig, Props} from '@docusaurus/types';
|
||||||
import type {Configuration} from 'webpack';
|
import type {Configuration} from 'webpack';
|
||||||
|
|
||||||
async function createBaseClientConfig({
|
async function createBaseClientConfig({
|
||||||
props,
|
props,
|
||||||
hydrate,
|
hydrate,
|
||||||
minify,
|
minify,
|
||||||
|
faster,
|
||||||
}: {
|
}: {
|
||||||
props: Props;
|
props: Props;
|
||||||
hydrate: boolean;
|
hydrate: boolean;
|
||||||
minify: boolean;
|
minify: boolean;
|
||||||
|
faster: FasterConfig;
|
||||||
}): Promise<Configuration> {
|
}): Promise<Configuration> {
|
||||||
const baseConfig = await createBaseConfig({props, isServer: false, minify});
|
const baseConfig = await createBaseConfig({
|
||||||
|
props,
|
||||||
|
isServer: false,
|
||||||
|
minify,
|
||||||
|
faster,
|
||||||
|
});
|
||||||
|
|
||||||
return merge(baseConfig, {
|
return merge(baseConfig, {
|
||||||
// Useless, disabled on purpose (errors on existing sites with no
|
// Useless, disabled on purpose (errors on existing sites with no
|
||||||
|
@ -60,10 +67,12 @@ export async function createStartClientConfig({
|
||||||
props,
|
props,
|
||||||
minify,
|
minify,
|
||||||
poll,
|
poll,
|
||||||
|
faster,
|
||||||
}: {
|
}: {
|
||||||
props: Props;
|
props: Props;
|
||||||
minify: boolean;
|
minify: boolean;
|
||||||
poll: number | boolean | undefined;
|
poll: number | boolean | undefined;
|
||||||
|
faster: FasterConfig;
|
||||||
}): Promise<{clientConfig: Configuration}> {
|
}): Promise<{clientConfig: Configuration}> {
|
||||||
const {siteConfig, headTags, preBodyTags, postBodyTags} = props;
|
const {siteConfig, headTags, preBodyTags, postBodyTags} = props;
|
||||||
|
|
||||||
|
@ -72,6 +81,7 @@ export async function createStartClientConfig({
|
||||||
props,
|
props,
|
||||||
minify,
|
minify,
|
||||||
hydrate: false,
|
hydrate: false,
|
||||||
|
faster,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
|
@ -105,10 +115,12 @@ export async function createStartClientConfig({
|
||||||
export async function createBuildClientConfig({
|
export async function createBuildClientConfig({
|
||||||
props,
|
props,
|
||||||
minify,
|
minify,
|
||||||
|
faster,
|
||||||
bundleAnalyzer,
|
bundleAnalyzer,
|
||||||
}: {
|
}: {
|
||||||
props: Props;
|
props: Props;
|
||||||
minify: boolean;
|
minify: boolean;
|
||||||
|
faster: FasterConfig;
|
||||||
bundleAnalyzer: boolean;
|
bundleAnalyzer: boolean;
|
||||||
}): Promise<{config: Configuration; clientManifestPath: string}> {
|
}): Promise<{config: Configuration; clientManifestPath: string}> {
|
||||||
// Apply user webpack config.
|
// Apply user webpack config.
|
||||||
|
@ -125,7 +137,7 @@ export async function createBuildClientConfig({
|
||||||
);
|
);
|
||||||
|
|
||||||
const config: Configuration = merge(
|
const config: Configuration = merge(
|
||||||
await createBaseClientConfig({props, minify, hydrate}),
|
await createBaseClientConfig({props, minify, faster, hydrate}),
|
||||||
{
|
{
|
||||||
plugins: [
|
plugins: [
|
||||||
new ForceTerminatePlugin(),
|
new ForceTerminatePlugin(),
|
||||||
|
|
|
@ -7,8 +7,14 @@
|
||||||
|
|
||||||
import TerserPlugin from 'terser-webpack-plugin';
|
import TerserPlugin from 'terser-webpack-plugin';
|
||||||
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
||||||
|
import {importSwcJsMinifierOptions} from '../faster';
|
||||||
import type {CustomOptions, CssNanoOptions} from 'css-minimizer-webpack-plugin';
|
import type {CustomOptions, CssNanoOptions} from 'css-minimizer-webpack-plugin';
|
||||||
import type {WebpackPluginInstance} from 'webpack';
|
import type {WebpackPluginInstance} from 'webpack';
|
||||||
|
import type {FasterConfig} from '@docusaurus/types';
|
||||||
|
|
||||||
|
export type MinimizersConfig = {
|
||||||
|
faster: Pick<FasterConfig, 'swcJsMinimizer'>;
|
||||||
|
};
|
||||||
|
|
||||||
// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
|
// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
|
||||||
function getTerserParallel() {
|
function getTerserParallel() {
|
||||||
|
@ -24,7 +30,16 @@ function getTerserParallel() {
|
||||||
return terserParallel;
|
return terserParallel;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJsMinifierPlugin() {
|
async function getJsMinimizer({faster}: MinimizersConfig) {
|
||||||
|
if (faster.swcJsMinimizer) {
|
||||||
|
const terserOptions = await importSwcJsMinifierOptions();
|
||||||
|
return new TerserPlugin({
|
||||||
|
parallel: getTerserParallel(),
|
||||||
|
minify: TerserPlugin.swcMinify,
|
||||||
|
terserOptions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return new TerserPlugin({
|
return new TerserPlugin({
|
||||||
parallel: getTerserParallel(),
|
parallel: getTerserParallel(),
|
||||||
terserOptions: {
|
terserOptions: {
|
||||||
|
@ -85,18 +100,19 @@ function getAdvancedCssMinifier() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMinimizer(): WebpackPluginInstance[] {
|
function getCssMinimizer(): WebpackPluginInstance {
|
||||||
// This is an historical env variable to opt-out of the advanced minifier
|
// This is an historical env variable to opt-out of the advanced minifier
|
||||||
// Sometimes there's a bug in it and people are happy to disable it
|
// Sometimes there's a bug in it and people are happy to disable it
|
||||||
const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';
|
const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';
|
||||||
|
|
||||||
const minimizer: WebpackPluginInstance[] = [getJsMinifierPlugin()];
|
|
||||||
|
|
||||||
if (useSimpleCssMinifier) {
|
if (useSimpleCssMinifier) {
|
||||||
minimizer.push(new CssMinimizerPlugin());
|
return new CssMinimizerPlugin();
|
||||||
} else {
|
} else {
|
||||||
minimizer.push(getAdvancedCssMinifier());
|
return getAdvancedCssMinifier();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return minimizer;
|
|
||||||
|
export async function getMinimizers(
|
||||||
|
params: MinimizersConfig,
|
||||||
|
): Promise<WebpackPluginInstance[]> {
|
||||||
|
return Promise.all([getJsMinimizer(params), getCssMinimizer()]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,8 @@ export default async function createServerConfig(params: {
|
||||||
const baseConfig = await createBaseConfig({
|
const baseConfig = await createBaseConfig({
|
||||||
props,
|
props,
|
||||||
isServer: true,
|
isServer: true,
|
||||||
|
|
||||||
// Minification of server bundle reduces size but doubles bundle time :/
|
|
||||||
minify: false,
|
minify: false,
|
||||||
|
faster: props.siteConfig.future.experimental_faster,
|
||||||
});
|
});
|
||||||
|
|
||||||
const outputFilename = 'server.bundle.js';
|
const outputFilename = 'server.bundle.js';
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {BABEL_CONFIG_FILE_NAME} from '@docusaurus/utils';
|
||||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||||
import webpack, {type Configuration, type RuleSetRule} from 'webpack';
|
import webpack, {type Configuration, type RuleSetRule} from 'webpack';
|
||||||
import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages';
|
import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages';
|
||||||
import {getSwcJsLoaderFactory} from '../faster';
|
import {importSwcJsLoaderFactory} from '../faster';
|
||||||
import type {ConfigureWebpackUtils, DocusaurusConfig} from '@docusaurus/types';
|
import type {ConfigureWebpackUtils, DocusaurusConfig} from '@docusaurus/types';
|
||||||
import type {TransformOptions} from '@babel/core';
|
import type {TransformOptions} from '@babel/core';
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ export async function createJsLoaderFactory({
|
||||||
return ({isServer}) => jsLoader(isServer);
|
return ({isServer}) => jsLoader(isServer);
|
||||||
}
|
}
|
||||||
if (siteConfig.future?.experimental_faster.swcJsLoader) {
|
if (siteConfig.future?.experimental_faster.swcJsLoader) {
|
||||||
return getSwcJsLoaderFactory();
|
return importSwcJsLoaderFactory();
|
||||||
}
|
}
|
||||||
if (jsLoader === 'babel') {
|
if (jsLoader === 'babel') {
|
||||||
return BabelJsLoaderFactory;
|
return BabelJsLoaderFactory;
|
||||||
|
|
|
@ -199,6 +199,7 @@ export default {
|
||||||
future: {
|
future: {
|
||||||
experimental_faster: {
|
experimental_faster: {
|
||||||
swcJsLoader: true,
|
swcJsLoader: true,
|
||||||
|
swcJsMinimizer: true,
|
||||||
},
|
},
|
||||||
experimental_storage: {
|
experimental_storage: {
|
||||||
type: 'localStorage',
|
type: 'localStorage',
|
||||||
|
@ -210,7 +211,8 @@ export default {
|
||||||
```
|
```
|
||||||
|
|
||||||
- `experimental_faster`: An object containing feature flags to make the Docusaurus build faster. This requires adding the `@docusaurus/faster` package to your site's dependencies. Use `true` as a shorthand to enable all flags.
|
- `experimental_faster`: An object containing feature flags to make the Docusaurus build faster. This requires adding the `@docusaurus/faster` package to your site's dependencies. Use `true` as a shorthand to enable all flags.
|
||||||
- `swcJsLoader`: Use `true` to replace the default [Babel](https://babeljs.io/) JS loader by [SWC](https://swc.rs/) loader to speed up the bundling phase.
|
- `swcJsLoader`: Use `true` to replace the default [Babel](https://babeljs.io/) JS loader by the [SWC](https://swc.rs/) JS loader to speed up the bundling phase.
|
||||||
|
- `swcJsMinimizer`: Use `true` to replace the default [`terser-webpack-plugin`](https://github.com/webpack-contrib/terser-webpack-plugin) JS minimizer ([Terser](https://terser.org/)) by the [SWC JS minimizer](https://swc.rs/docs/configuration/minification) to speed up the bundling minification phase.
|
||||||
- `experimental_storage`: Site-wide browser storage options that theme authors should strive to respect.
|
- `experimental_storage`: Site-wide browser storage options that theme authors should strive to respect.
|
||||||
- `type`: The browser storage theme authors should use. Possible values are `localStorage` and `sessionStorage`. Defaults to `localStorage`.
|
- `type`: The browser storage theme authors should use. Possible values are `localStorage` and `sessionStorage`. Defaults to `localStorage`.
|
||||||
- `namespace`: Whether to namespace the browser storage keys to avoid storage key conflicts when Docusaurus sites are hosted under the same domain, or on localhost. Possible values are `string | boolean`. The namespace is appended at the end of the storage keys `key-namespace`. Use `true` to automatically generate a random namespace from your site `url + baseUrl`. Defaults to `false` (no namespace, historical behavior).
|
- `namespace`: Whether to namespace the browser storage keys to avoid storage key conflicts when Docusaurus sites are hosted under the same domain, or on localhost. Possible values are `string | boolean`. The namespace is appended at the end of the storage keys `key-namespace`. Use `true` to automatically generate a random namespace from your site `url + baseUrl`. Defaults to `false` (no namespace, historical behavior).
|
||||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -2002,7 +2002,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
|
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
|
||||||
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
|
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
|
||||||
|
|
||||||
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9":
|
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9":
|
||||||
version "0.3.25"
|
version "0.3.25"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
|
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
|
||||||
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
|
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
|
||||||
|
@ -16080,21 +16080,21 @@ tempy@^0.6.0:
|
||||||
type-fest "^0.16.0"
|
type-fest "^0.16.0"
|
||||||
unique-string "^2.0.0"
|
unique-string "^2.0.0"
|
||||||
|
|
||||||
terser-webpack-plugin@^5.3.7, terser-webpack-plugin@^5.3.9:
|
terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.7, terser-webpack-plugin@^5.3.9:
|
||||||
version "5.3.9"
|
version "5.3.10"
|
||||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1"
|
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199"
|
||||||
integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==
|
integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/trace-mapping" "^0.3.17"
|
"@jridgewell/trace-mapping" "^0.3.20"
|
||||||
jest-worker "^27.4.5"
|
jest-worker "^27.4.5"
|
||||||
schema-utils "^3.1.1"
|
schema-utils "^3.1.1"
|
||||||
serialize-javascript "^6.0.1"
|
serialize-javascript "^6.0.1"
|
||||||
terser "^5.16.8"
|
terser "^5.26.0"
|
||||||
|
|
||||||
terser@^5.0.0, terser@^5.10.0, terser@^5.15.1, terser@^5.16.8:
|
terser@^5.0.0, terser@^5.10.0, terser@^5.15.1, terser@^5.26.0:
|
||||||
version "5.19.0"
|
version "5.31.6"
|
||||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.0.tgz#7b3137b01226bdd179978207b9c8148754a6da9c"
|
resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1"
|
||||||
integrity sha512-JpcpGOQLOXm2jsomozdMDpd5f8ZHh1rR48OFgWUH3QsyZcfPgv2qDCYbcDEAYNd4OZRj2bWYKpwdll/udZCk/Q==
|
integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/source-map" "^0.3.3"
|
"@jridgewell/source-map" "^0.3.3"
|
||||||
acorn "^8.8.2"
|
acorn "^8.8.2"
|
||||||
|
|
Loading…
Add table
Reference in a new issue