Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 49 additions & 3 deletions packages/docusaurus-bundler/src/browserslist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,65 @@
*/

import browserslist from 'browserslist';
import semver from 'semver';
import {browserslistToTargets, type TransformOptions} from 'lightningcss';
import type {CurrentBundler} from '@docusaurus/types';

// Used when the site doesn't provide its own Browserslist config
// See https://web.dev/baseline
const DefaultBrowserslistQueries = ['baseline widely available'];

export function getBrowserslistQueries(): string[] {
export function getClientQueries(): string[] {
return (
browserslist.loadConfig({path: process.cwd()}) ?? DefaultBrowserslistQueries
);
}

/**
* The browsers that the client queries match, like
* `['chrome 120', 'firefox 115']`
*/
function getClientTargets(): string[] {
return browserslist(getClientQueries());
}

export function getServerTargets({
bundlerName,
}: {
bundlerName: CurrentBundler['name'];
}): string[] {
// Escape hatch env variable
if (process.env.DOCUSAURUS_SERVER_NODE_TARGET) {
return [`node ${process.env.DOCUSAURUS_SERVER_NODE_TARGET}`];
}
// For server builds, we want to use the current Node version as target
// But we can't pass a target that Browserslist doesn't know about yet
const nodeTarget = getMinVersion(
process.versions.node,
getLastBrowserslistKnownNodeVersion(bundlerName),
);
return [`node ${nodeTarget}`];
}

// TODO this is not accurate
// for Rspack we should read from the built-in browserslist data
// see https://github.com/facebook/docusaurus/pull/11496
function getLastBrowserslistKnownNodeVersion(
bundlerName: CurrentBundler['name'],
): string {
if (bundlerName === 'rspack') {
// TODO hardcoded value until Rspack exposes its Browserslist data
// see https://github.com/facebook/docusaurus/pull/11496
return '26.0.0';
}
// browserslist('last 1 node versions')[0]!.replace('node ', '')
return browserslist.nodeVersions.at(-1)!;
}

function getMinVersion(v1: string, v2: string): string {
return semver.lt(v1, v2) ? v1 : v2;
}

// LightningCSS doesn't expose any type for minimizer-webpack-plugin setup
// So we derive it ourselves
// see https://lightningcss.dev/docs.html#with-webpack
Expand All @@ -27,6 +74,5 @@ type LightningCssMinimizerOptions = Omit<
>;

export function getLightningCssMinimizerOptions(): LightningCssMinimizerOptions {
const browsers = browserslist(getBrowserslistQueries());
return {targets: browserslistToTargets(browsers)};
return {targets: browserslistToTargets(getClientTargets())};
}
2 changes: 1 addition & 1 deletion packages/docusaurus-bundler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export {
registerBundlerTracing,
} from './currentBundler';

export {getBrowserslistQueries} from './browserslist';
export {getClientQueries} from './browserslist';
export {getMinimizers} from './minification';
export {getHtmlMinifier, type HtmlMinifier} from './minifyHtml';
export {createJsLoaderFactory} from './loaders/jsLoader';
Expand Down
8 changes: 1 addition & 7 deletions packages/docusaurus-bundler/src/loaders/jsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import {getBabelOptions, getCustomBabelConfigFilePath} from '@docusaurus/babel';
import {getSwcLoaderOptions} from '../swc';
import {getCurrentBundler} from '../currentBundler';
import {getBrowserslistQueries} from '../browserslist';
import type {ConfigureWebpackUtils, DocusaurusConfig} from '@docusaurus/types';

async function createBabelJsLoaderFactory({
Expand All @@ -27,15 +26,10 @@ async function createBabelJsLoaderFactory({

function createRspackSwcJsLoaderFactory(): ConfigureWebpackUtils['getJSLoader'] {
const loader = 'builtin:swc-loader';
const clientBrowserslistQueries = getBrowserslistQueries();
return ({isServer}) => {
return {
loader,
options: getSwcLoaderOptions({
isServer,
bundlerName: 'rspack',
clientBrowserslistQueries,
}),
options: getSwcLoaderOptions({isServer, bundlerName: 'rspack'}),
};
};
}
Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus-bundler/src/minification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {createRequire} from 'node:module';
import logger from '@docusaurus/logger';
import {rspack} from './rspack';
import {
getBrowserslistQueries,
getClientQueries,
getLightningCssMinimizerOptions,
} from './browserslist';
import type * as MinifyFunctions from './minifyFunctions';
Expand Down Expand Up @@ -137,7 +137,7 @@ function getRspackMinimizers(): RspackPluginInstance[] {
// While LightningCSS targets are normally not Browserslist queries
// See https://rspack.dev/plugins/rspack/lightning-css-minimizer-rspack-plugin#minimizeroptions
// See https://lightningcss.dev/transpilation.html
targets: getBrowserslistQueries(),
targets: getClientQueries(),
},
}),
];
Expand Down
47 changes: 3 additions & 44 deletions packages/docusaurus-bundler/src/swc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,21 @@
* LICENSE file in the root directory of this source tree.
*/

import browserslist from 'browserslist';
import semver from 'semver';
import {getClientQueries, getServerTargets} from './browserslist';
import type {SwcLoaderOptions} from '@rspack/core';
import type {CurrentBundler} from '@docusaurus/types';

export function getSwcLoaderOptions({
isServer,
bundlerName,
clientBrowserslistQueries,
}: {
isServer: boolean;
bundlerName: CurrentBundler['name'];
clientBrowserslistQueries: string[];
}): SwcLoaderOptions {
return {
env: {
targets: isServer
? getServerBrowserslistQueries({bundlerName})
: clientBrowserslistQueries,
// Rspack resolves the client queries with its own Browserslist data
targets: isServer ? getServerTargets({bundlerName}) : getClientQueries(),
},
jsc: {
parser: {
Expand All @@ -43,40 +39,3 @@ export function getSwcLoaderOptions({
},
};
}

// TODO this is not accurate
// for Rspack we should read from the built-in browserslist data
// see https://github.com/facebook/docusaurus/pull/11496
function getLastBrowserslistKnownNodeVersion(
bundlerName: CurrentBundler['name'],
): string {
if (bundlerName === 'rspack') {
// TODO hardcoded value until Rspack exposes its Browserslist data
// see https://github.com/facebook/docusaurus/pull/11496
return '26.0.0';
}
// browserslist('last 1 node versions')[0]!.replace('node ', '')
return browserslist.nodeVersions.at(-1)!;
}

function getMinVersion(v1: string, v2: string): string {
return semver.lt(v1, v2) ? v1 : v2;
}

function getServerBrowserslistQueries({
bundlerName,
}: {
bundlerName: CurrentBundler['name'];
}): string[] {
// Escape hatch env variable
if (process.env.DOCUSAURUS_SERVER_NODE_TARGET) {
return [`node ${process.env.DOCUSAURUS_SERVER_NODE_TARGET}`];
}
// For server builds, we want to use the current Node version as target
// But we can't pass a target that Browserslist doesn't know about yet
const nodeTarget = getMinVersion(
process.versions.node,
getLastBrowserslistKnownNodeVersion(bundlerName),
);
return [`node ${nodeTarget}`];
}
4 changes: 2 additions & 2 deletions packages/docusaurus/src/webpack/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import path from 'node:path';
import {
createJsLoaderFactory,
getBrowserslistQueries,
getClientQueries,
getCSSExtractPlugin,
getMinimizers,
} from '@docusaurus/bundler';
Expand Down Expand Up @@ -114,7 +114,7 @@ export async function createBaseConfig({
const themeAliasesHash = md5Hash(JSON.stringify(themeAliases));
// Loader and minimizer options are not part of the cache key
// Changing the Browserslist config must evict the cache
const browserslistHash = md5Hash(JSON.stringify(getBrowserslistQueries()));
const browserslistHash = md5Hash(JSON.stringify(getClientQueries()));
// Asset module parser options are not part of the cache key
// Changing the asset inline max size must evict the cache
return `${siteMetadata.docusaurusVersion}-${themeAliasesHash}-${browserslistHash}-${ASSET_INLINE_MAX_SIZE}`;
Expand Down
Loading