From 91e41a35936377542a3a595724a309f8732919e9 Mon Sep 17 00:00:00 2001 From: sebastien Date: Fri, 8 Nov 2024 12:07:34 +0100 Subject: [PATCH] fix jsLoader factory ambiguity --- .../src/loaders/__tests__/jsLoader.test.ts | 64 ++++++++++++++++--- .../src/loaders/jsLoader.ts | 26 ++++---- packages/docusaurus-types/src/config.d.ts | 2 +- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/packages/docusaurus-bundler/src/loaders/__tests__/jsLoader.test.ts b/packages/docusaurus-bundler/src/loaders/__tests__/jsLoader.test.ts index 22016169b883..a3c7ea43e492 100644 --- a/packages/docusaurus-bundler/src/loaders/__tests__/jsLoader.test.ts +++ b/packages/docusaurus-bundler/src/loaders/__tests__/jsLoader.test.ts @@ -10,19 +10,19 @@ import {createJsLoaderFactory} from '../jsLoader'; import type {RuleSetRule} from 'webpack'; +type SiteConfigSlice = Parameters< + typeof createJsLoaderFactory +>[0]['siteConfig']; + describe('createJsLoaderFactory', () => { - function testJsLoaderFactory( - siteConfig?: PartialDeep< - Parameters[0]['siteConfig'] - >, - ) { + function testJsLoaderFactory(siteConfig?: { + webpack?: SiteConfigSlice['webpack']; + future?: PartialDeep; + }) { return createJsLoaderFactory({ siteConfig: { ...siteConfig, - webpack: { - jsLoader: 'babel', - ...siteConfig?.webpack, - }, + webpack: siteConfig?.webpack, future: fromPartial({ ...siteConfig?.future, experimental_faster: fromPartial({ @@ -43,6 +43,52 @@ describe('createJsLoaderFactory', () => { ); }); + it('createJsLoaderFactory accepts babel loader preset', async () => { + const createJsLoader = await testJsLoaderFactory({ + webpack: {jsLoader: 'babel'}, + }); + expect(createJsLoader({isServer: true}).loader).toBe( + require.resolve('babel-loader'), + ); + expect(createJsLoader({isServer: false}).loader).toBe( + require.resolve('babel-loader'), + ); + }); + + it('createJsLoaderFactory accepts custom loader', async () => { + const createJsLoader = await testJsLoaderFactory({ + webpack: { + jsLoader: (isServer) => { + return {loader: `my-loader-${isServer ? 'server' : 'client'}`}; + }, + }, + }); + expect(createJsLoader({isServer: true}).loader).toBe('my-loader-server'); + expect(createJsLoader({isServer: false}).loader).toBe('my-loader-client'); + }); + + it('createJsLoaderFactory rejects custom loader when using faster swc loader', async () => { + await expect(() => + testJsLoaderFactory({ + future: { + experimental_faster: { + swcJsLoader: true, + }, + }, + webpack: { + jsLoader: (isServer) => { + return {loader: `my-loader-${isServer ? 'server' : 'client'}`}; + }, + }, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + "You can't use siteConfig.webpack.jsLoader and siteConfig.future.experimental_faster.swcJsLoader at the same time. + To avoid any configuration ambiguity, you must make an explicit choice: + - If you want to use Docusaurus Faster and SWC (recommended), remove siteConfig.webpack.jsLoader + - If you want to use a custom JS loader, use siteConfig.future.experimental_faster.swcJsLoader: false" + `); + }); + it('createJsLoaderFactory accepts loaders with preset', async () => { const createJsLoader = await testJsLoaderFactory({ webpack: {jsLoader: 'babel'}, diff --git a/packages/docusaurus-bundler/src/loaders/jsLoader.ts b/packages/docusaurus-bundler/src/loaders/jsLoader.ts index b6e0088ebd88..6f9213454d5d 100644 --- a/packages/docusaurus-bundler/src/loaders/jsLoader.ts +++ b/packages/docusaurus-bundler/src/loaders/jsLoader.ts @@ -62,26 +62,24 @@ export async function createJsLoaderFactory({ }): Promise { const currentBundler = await getCurrentBundler({siteConfig}); const isSWCLoader = siteConfig.future.experimental_faster.swcJsLoader; - if (currentBundler.name === 'rspack') { - return isSWCLoader + if (isSWCLoader) { + if (siteConfig.webpack?.jsLoader) { + throw new Error( + `You can't use siteConfig.webpack.jsLoader and siteConfig.future.experimental_faster.swcJsLoader at the same time. +To avoid any configuration ambiguity, you must make an explicit choice: +- If you want to use Docusaurus Faster and SWC (recommended), remove siteConfig.webpack.jsLoader +- If you want to use a custom JS loader, use siteConfig.future.experimental_faster.swcJsLoader: false`, + ); + } + return currentBundler.name === 'rspack' ? createRspackSwcJsLoaderFactory() - : BabelJsLoaderFactory; + : createSwcJsLoaderFactory(); } + const jsLoader = siteConfig.webpack?.jsLoader ?? 'babel'; - if ( - jsLoader instanceof Function && - siteConfig.future?.experimental_faster.swcJsLoader - ) { - throw new Error( - "You can't use a custom webpack.jsLoader and experimental_faster.swcJsLoader at the same time", - ); - } if (jsLoader instanceof Function) { return ({isServer}) => jsLoader(isServer); } - if (siteConfig.future?.experimental_faster.swcJsLoader) { - return createSwcJsLoaderFactory(); - } if (jsLoader === 'babel') { return BabelJsLoaderFactory; } diff --git a/packages/docusaurus-types/src/config.d.ts b/packages/docusaurus-types/src/config.d.ts index 575be4a6fd57..8289e8b22282 100644 --- a/packages/docusaurus-types/src/config.d.ts +++ b/packages/docusaurus-types/src/config.d.ts @@ -431,7 +431,7 @@ export type DocusaurusConfig = { // 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); + jsLoader?: 'babel' | ((isServer: boolean) => RuleSetRule); }; /** Markdown-related options. */ markdown: MarkdownConfig;