Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): Replace Webpack with Rspack - siteConfig.future.experimental_faster.rspackBundler #10402

Merged
merged 65 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
0dc5661
Rspack POC
slorber Aug 14, 2024
b1f4ae2
fix scripts
slorber Aug 14, 2024
ca7fefc
temp remove DefinePlugin
slorber Aug 14, 2024
127845d
fix pwa EnvironmentPlugin + CopyRspackPlugin
slorber Aug 14, 2024
c13d987
Add Rsdoctor plugin
slorber Aug 15, 2024
d08a465
remove RSDOCTOR by defaulkt
slorber Aug 15, 2024
2cfe4cd
remove useless exit + use Rspack minifiers
slorber Aug 15, 2024
8a2ab67
builtin:swc-loader
slorber Aug 15, 2024
6ec8d65
remove alias CssExtractRspackPlugin as MiniCssExtractPlugin
slorber Aug 16, 2024
64fdfcf
remove alias CssExtractRspackPlugin as MiniCssExtractPlugin
slorber Aug 16, 2024
4138492
Revert "remove alias CssExtractRspackPlugin as MiniCssExtractPlugin"
slorber Aug 16, 2024
486ee81
use LightningCssMinimizerRspackPlugin
slorber Aug 16, 2024
69f7d43
use RsdoctorRspackMultiplePlugin
slorber Aug 22, 2024
cbddd79
merge from main
slorber Sep 6, 2024
2e27a8a
upgrade and fix Rsdoctor?
slorber Sep 6, 2024
dacc090
upgrade Rspack to v1 stable
slorber Sep 6, 2024
fc9576b
Try to restore ChunkAssetPlugin for preloading
slorber Sep 6, 2024
a76cb73
Merge branch 'main' into slorber/poc-rspack
slorber Sep 10, 2024
b5c267a
Rspack 1.0.4
slorber Sep 10, 2024
2fff52f
damn, ChunkAssetPlugin still doesn't work
slorber Sep 10, 2024
456cde8
Merge branch 'main' into slorber/poc-rspack
slorber Sep 13, 2024
318c2df
fix merge issues
slorber Sep 13, 2024
3b5dbe5
try to fix Rspack build
slorber Sep 13, 2024
5e3fe51
add todo
slorber Sep 13, 2024
68b4bf6
add todo + disable gca
slorber Sep 13, 2024
fc08c5d
make it work
slorber Sep 13, 2024
e8272c4
build perf, log current bundler name
slorber Sep 13, 2024
0cee6bf
add RspackJsLoaderFactory
slorber Sep 13, 2024
6261ab5
simplify Rspack js loader
slorber Sep 13, 2024
bf2ad51
simplify Rspack js loader
slorber Sep 13, 2024
a06b194
fix lint error + wire rspack minimizer properly
slorber Sep 13, 2024
c8dc795
fix minimizer
slorber Sep 13, 2024
3b6987d
fix theme configureWebpack
slorber Sep 13, 2024
200ced7
fix Prism bundle size increase
slorber Sep 13, 2024
b4469fe
refactor: apply lint autofix
slorber Sep 13, 2024
0739fce
empty
slorber Sep 13, 2024
a608e88
Merge branch 'main' into slorber/poc-rspack
slorber Sep 26, 2024
5de89ab
handle merge conflicts
slorber Sep 26, 2024
d6b34a9
rspack 1.0.7
slorber Sep 26, 2024
c4881e7
attempt to restore ChunkAssetPlugin
slorber Sep 26, 2024
402d3ef
temp disable ChunkAssetPlugin
slorber Sep 26, 2024
74ddd14
refactor: apply lint autofix
slorber Sep 26, 2024
628980e
empty
slorber Sep 26, 2024
c66bfb4
fix createJsLoaderFactory test
slorber Sep 26, 2024
cb84db1
remove Rspack config validation errors
slorber Sep 26, 2024
3a202df
Use Rspack canary, restore ChunkAssetPlugin
slorber Sep 26, 2024
128bfd6
Merge branch 'main' into slorber/poc-rspack
slorber Sep 27, 2024
5bb213e
re-add missing rspack dep + fix lockfile
slorber Sep 27, 2024
4eacf9f
Wire browserslist to LightningCSS built-in targets
slorber Sep 27, 2024
e23b63e
restore dynamic require usage
slorber Sep 30, 2024
097ed54
Rspack 1.0.8
slorber Sep 30, 2024
1c48869
Merge branch 'main' into slorber/poc-rspack
slorber Oct 3, 2024
8093a21
Add useful comment for getBrowserslistQueries
slorber Oct 3, 2024
9eebd7f
Merge branch 'main' into slorber/poc-rspack
slorber Oct 3, 2024
4f40e3b
Merge branch 'main' into slorber/poc-rspack
slorber Oct 4, 2024
961a940
Update Rspack
slorber Oct 10, 2024
a26613e
Merge branch 'main' into slorber/poc-rspack
slorber Oct 10, 2024
2cdb41e
Fix rsdoctor skipLibCheck issue
slorber Oct 10, 2024
901be76
upgrade Rsdoctor
slorber Oct 10, 2024
ab0e856
perf log
slorber Oct 10, 2024
c9d3afa
remove temp gca() workaround
slorber Oct 10, 2024
b339274
diff
slorber Oct 10, 2024
d1df260
add SwcJsMinimizerRspackPlugin config
slorber Oct 10, 2024
b913a17
comment
slorber Oct 10, 2024
b02fb3e
use shared conservative swc minifier options
slorber Oct 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions packages/docusaurus-bundler/src/currentBundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import webpack from 'webpack';
import WebpackBar from 'webpackbar';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import logger from '@docusaurus/logger';
import {importRspack} from './importFaster';
import type {FasterModule} from './importFaster';
import type {CurrentBundler, DocusaurusConfig} from '@docusaurus/types';

// We inject a site config slice because the Rspack flag might change place
Expand All @@ -32,24 +33,38 @@ export async function getCurrentBundler({
siteConfig: SiteConfigSlice;
}): Promise<CurrentBundler> {
if (isRspack(siteConfig)) {
// TODO add support for Rspack
logger.error(
'Rspack bundler is not supported yet, will use Webpack instead',
);
return {
name: 'rspack',
instance: (await importRspack()) as unknown as typeof webpack,
};
}
return {
name: 'webpack',
instance: webpack,
};
}

export function getCurrentBundlerAsRspack({
currentBundler,
}: {
currentBundler: CurrentBundler;
}): FasterModule['rspack'] {
if (currentBundler.name !== 'rspack') {
throw new Error(
`Can't getCurrentBundlerAsRspack() because current bundler is ${currentBundler.name}`,
);
}
return currentBundler.instance as unknown as FasterModule['rspack'];
}

export async function getCSSExtractPlugin({
currentBundler,
}: {
currentBundler: CurrentBundler;
}): Promise<typeof MiniCssExtractPlugin> {
if (currentBundler.name === 'rspack') {
throw new Error('Rspack bundler is not supported yet');
// @ts-expect-error: this exists only in Rspack
return currentBundler.instance.CssExtractRspackPlugin;
}
return MiniCssExtractPlugin;
}
Expand All @@ -60,9 +75,9 @@ export async function getCopyPlugin({
currentBundler: CurrentBundler;
}): Promise<typeof CopyWebpackPlugin> {
if (currentBundler.name === 'rspack') {
throw new Error('Rspack bundler is not supported yet');
// @ts-expect-error: this exists only in Rspack
return currentBundler.instance.CopyRspackPlugin;
}
// https://github.com/webpack-contrib/copy-webpack-plugin
return CopyWebpackPlugin;
}

Expand Down
12 changes: 11 additions & 1 deletion packages/docusaurus-bundler/src/importFaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
} from 'terser-webpack-plugin';
import type {MinimizerOptions as CssMinimizerOptions} from 'css-minimizer-webpack-plugin';

type FasterModule = Awaited<typeof import('@docusaurus/faster')>;
export type FasterModule = Awaited<typeof import('@docusaurus/faster')>;

async function importFaster(): Promise<FasterModule> {
return import('@docusaurus/faster');
Expand All @@ -29,6 +29,11 @@ async function ensureFaster(): Promise<FasterModule> {
}
}

export async function importRspack(): Promise<FasterModule['rspack']> {
const faster = await ensureFaster();
return faster.rspack;
}

export async function importSwcJsLoaderFactory(): Promise<
ConfigureWebpackUtils['getJSLoader']
> {
Expand All @@ -50,6 +55,11 @@ export async function importSwcHtmlMinifier(): Promise<
return faster.getSwcHtmlMinifier();
}

export async function importBrowserslistQueries(): Promise<string[]> {
const faster = await ensureFaster();
return faster.getBrowserslistQueries();
}

export async function importLightningCssMinimizerOptions(): Promise<
CssMinimizerOptions<CustomOptions>
> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
* LICENSE file in the root directory of this source tree.
*/

import {fromPartial} from '@total-typescript/shoehorn';
import {fromPartial, type PartialDeep} from '@total-typescript/shoehorn';
import {createJsLoaderFactory} from '../jsLoader';

import type {RuleSetRule} from 'webpack';

describe('createJsLoaderFactory', () => {
function testJsLoaderFactory(
siteConfig?: Parameters<typeof createJsLoaderFactory>[0]['siteConfig'],
siteConfig?: PartialDeep<
Parameters<typeof createJsLoaderFactory>[0]['siteConfig']
>,
) {
return createJsLoaderFactory({
siteConfig: {
Expand All @@ -21,7 +23,12 @@ describe('createJsLoaderFactory', () => {
jsLoader: 'babel',
...siteConfig?.webpack,
},
future: fromPartial(siteConfig?.future),
future: fromPartial({
...siteConfig?.future,
experimental_faster: fromPartial({
...siteConfig?.future?.experimental_faster,
}),
}),
},
});
}
Expand Down
33 changes: 32 additions & 1 deletion packages/docusaurus-bundler/src/loaders/jsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import {getBabelOptions} from '@docusaurus/babel';
import {importSwcJsLoaderFactory} from '../importFaster';
import {getCurrentBundler} from '../currentBundler';
import type {ConfigureWebpackUtils, DocusaurusConfig} from '@docusaurus/types';

const BabelJsLoaderFactory: ConfigureWebpackUtils['getJSLoader'] = ({
Expand All @@ -19,6 +20,25 @@ const BabelJsLoaderFactory: ConfigureWebpackUtils['getJSLoader'] = ({
};
};

const RspackJsLoaderFactory: ConfigureWebpackUtils['getJSLoader'] = () => {
return {
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
},
transform: {
react: {
runtime: 'automatic',
},
},
},
},
};
};

// Confusing: function that creates a function that creates actual js loaders
// This is done on purpose because the js loader factory is a public API
// It is injected in configureWebpack plugin lifecycle for plugin authors
Expand All @@ -27,11 +47,22 @@ export async function createJsLoaderFactory({
}: {
siteConfig: {
webpack?: DocusaurusConfig['webpack'];
future?: {
future: {
experimental_faster: DocusaurusConfig['future']['experimental_faster'];
};
};
}): Promise<ConfigureWebpackUtils['getJSLoader']> {
const currentBundler = await getCurrentBundler({siteConfig});
const isSWCLoader = siteConfig.future.experimental_faster.swcJsLoader;

if (currentBundler.name === 'rspack') {
if (!isSWCLoader) {
throw new Error(
'When using Rspack bundler, it is required to enable swcJsLoader too',
);
}
return RspackJsLoaderFactory;
}
const jsLoader = siteConfig.webpack?.jsLoader ?? 'babel';
if (
jsLoader instanceof Function &&
Expand Down
29 changes: 27 additions & 2 deletions packages/docusaurus-bundler/src/minification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import {
importSwcJsMinimizerOptions,
importLightningCssMinimizerOptions,
importBrowserslistQueries,
} from './importFaster';
import {getCurrentBundlerAsRspack} from './currentBundler';
import type {CustomOptions, CssNanoOptions} from 'css-minimizer-webpack-plugin';
import type {WebpackPluginInstance} from 'webpack';
import type {CurrentBundler, FasterConfig} from '@docusaurus/types';
Expand Down Expand Up @@ -48,6 +50,7 @@ async function getJsMinimizer({

return new TerserPlugin({
parallel: getTerserParallel(),
// See https://terser.org/docs/options/
terserOptions: {
parse: {
// We want uglify-js to parse ecma 8 code. However, we don't want it
Expand Down Expand Up @@ -137,8 +140,30 @@ async function getWebpackMinimizers(
async function getRspackMinimizers({
currentBundler,
}: MinimizersConfig): Promise<WebpackPluginInstance[]> {
console.log('currentBundler', currentBundler.name);
throw new Error('TODO Rspack minimizers not implemented yet');
const rspack = getCurrentBundlerAsRspack({currentBundler});
const browserslistQueries = await importBrowserslistQueries();
const swcJsMinimizerOptions = await importSwcJsMinimizerOptions();
return [
// See https://rspack.dev/plugins/rspack/swc-js-minimizer-rspack-plugin
// See https://swc.rs/docs/configuration/minification
new rspack.SwcJsMinimizerRspackPlugin({
minimizerOptions: {
minify: true,
...swcJsMinimizerOptions,
},
}),
new rspack.LightningCssMinimizerRspackPlugin({
minimizerOptions: {
...(await importLightningCssMinimizerOptions()),
// Not sure why but Rspack takes browserslist queries directly
// While LightningCSS targets are normally not browserslist queries
// We have to override the option to avoid errors
// See https://rspack.dev/plugins/rspack/lightning-css-minimizer-rspack-plugin#minimizeroptions
// See https://lightningcss.dev/transpilation.html
targets: browserslistQueries,
},
}),
] as unknown as WebpackPluginInstance[];
}

export async function getMinimizers(
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-faster/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"license": "MIT",
"dependencies": {
"@rspack/core": "^1.0.9",
"@swc/core": "^1.7.28",
"@swc/html": "^1.7.28",
"browserslist": "^4.24.0",
Expand Down
12 changes: 12 additions & 0 deletions packages/docusaurus-faster/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/

import Rspack from '@rspack/core';
import * as lightningcss from 'lightningcss';
import browserslist from 'browserslist';
import {minify as swcHtmlMinifier} from '@swc/html';
import type {RuleSetRule} from 'webpack';
import type {JsMinifyOptions} from '@swc/core';

export const rspack = Rspack;

export function getSwcHtmlMinifier(): typeof swcHtmlMinifier {
return swcHtmlMinifier;
}
Expand Down Expand Up @@ -63,6 +66,15 @@ export function getSwcJsMinimizerOptions(): JsMinifyOptions {
};
}

// We need this because of Rspack built-in LightningCSS integration
// See https://github.com/orgs/browserslist/discussions/846
export function getBrowserslistQueries(): string[] {
const queries = browserslist.loadConfig({path: process.cwd()}) ?? [
...browserslist.defaults,
];
return queries;
}

// LightningCSS doesn't expose any type for css-minimizer-webpack-plugin setup
// So we derive it ourselves
// see https://lightningcss.dev/docs.html#with-webpack
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@docusaurus/core": "3.5.2",
"@docusaurus/logger": "3.5.2",
"@docusaurus/mdx-loader": "3.5.2",
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/plugin-content-blog": "3.5.2",
Expand Down
45 changes: 22 additions & 23 deletions packages/docusaurus/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,32 +174,31 @@ async function buildLocale({

// We can build the 2 configs in parallel
const [{clientConfig, clientManifestPath}, {serverConfig, serverBundlePath}] =
await PerfLogger.async('Creating bundler configs', () =>
Promise.all([
getBuildClientConfig({
props,
cliOptions,
configureWebpackUtils,
}),
getBuildServerConfig({
props,
configureWebpackUtils,
}),
]),
await PerfLogger.async(
`Creating ${props.currentBundler.name} bundler configs`,
() =>
Promise.all([
getBuildClientConfig({
props,
cliOptions,
configureWebpackUtils,
}),
getBuildServerConfig({
props,
configureWebpackUtils,
}),
]),
);

// Run webpack to build JS bundle (client) and static html files (server).
await PerfLogger.async(
`Bundling with ${configureWebpackUtils.currentBundler.name}`,
() => {
return compile({
configs:
// For hash router we don't do SSG and can skip the server bundle
router === 'hash' ? [clientConfig] : [clientConfig, serverConfig],
currentBundler: configureWebpackUtils.currentBundler,
});
},
);
await PerfLogger.async(`Bundling with ${props.currentBundler.name}`, () => {
return compile({
configs:
// For hash router we don't do SSG and can skip the server bundle
router === 'hash' ? [clientConfig] : [clientConfig, serverConfig],
currentBundler: configureWebpackUtils.currentBundler,
});
});

const {collectedData} = await PerfLogger.async('SSG', () =>
executeSSG({
Expand Down
3 changes: 1 addition & 2 deletions packages/docusaurus/src/commands/start/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import path from 'path';
import merge from 'webpack-merge';
import webpack from 'webpack';
import {formatStatsErrorMessage, printStatsWarnings} from '@docusaurus/bundler';
import logger from '@docusaurus/logger';
import WebpackDevServer from 'webpack-dev-server';
Expand Down Expand Up @@ -168,7 +167,7 @@ export async function createWebpackDevServer({
configureWebpackUtils,
});

const compiler = webpack(config);
const compiler = props.currentBundler.instance(config);
registerWebpackE2ETestHook(compiler);

const defaultDevServerConfig = await createDevServerConfig({
Expand Down
Loading