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
39 changes: 39 additions & 0 deletions packages/docusaurus-bundler/src/__tests__/browserslist.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {afterEach, describe, expect, it, vi} from 'vitest';
import {getTargets} from '../browserslist';

const realNodeVersion = process.versions.node;

function stubNodeVersion(version: string) {
Object.defineProperty(process.versions, 'node', {value: version});
}

describe('getTargets', () => {
describe('server', () => {
afterEach(() => {
stubNodeVersion(realNodeVersion);
vi.unstubAllEnvs();
});

it('targets the current Node.js version', () => {
stubNodeVersion('26.8.1');
expect(getTargets({isServer: true})).toEqual(['node 26.8.1']);
});

it('removes the pre-release tag of the current Node.js version', () => {
stubNodeVersion('27.0.0-rc.1');
expect(getTargets({isServer: true})).toEqual(['node 27.0.0']);
});

it('targets the DOCUSAURUS_SERVER_NODE_TARGET env variable', () => {
vi.stubEnv('DOCUSAURUS_SERVER_NODE_TARGET', '24.18.0');
expect(getTargets({isServer: true})).toEqual(['node 24.18.0']);
});
});
});
48 changes: 8 additions & 40 deletions packages/docusaurus-bundler/src/browserslist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
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
Expand All @@ -18,14 +17,8 @@ const DefaultBrowserslistQueries = ['baseline widely available'];
* The targets the client or server bundle is compiled for, like
* `['chrome 120', 'firefox 115']` or `['node 24.11.1']`
*/
export function getTargets({
isServer,
bundlerName,
}: {
isServer: boolean;
bundlerName: CurrentBundler['name'];
}): string[] {
return isServer ? getServerTargets({bundlerName}) : getClientTargets();
export function getTargets({isServer}: {isServer: boolean}): string[] {
return isServer ? getServerTargets() : getClientTargets();
}

export function getClientQueries(): string[] {
Expand All @@ -42,41 +35,16 @@ function getClientTargets(): string[] {
return browserslist(getClientQueries());
}

export function getServerTargets({
bundlerName,
}: {
bundlerName: CurrentBundler['name'];
}): string[] {
// SWC skips all transforms for Node versions newer than its Browserslist data
// See https://github.com/swc-project/swc/pull/11457
export function getServerTargets(): 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;
// SWC panics on pre-release versions like "27.0.0-rc.1"
const nodeVersion = semver.coerce(process.versions.node)!.version;
return [`node ${nodeVersion}`];
}

// LightningCSS doesn't expose any type for minimizer-webpack-plugin setup
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-bundler/src/loaders/jsLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function createRspackSwcJsLoaderFactory(): ConfigureWebpackUtils['getJSLoader']
return ({isServer}) => {
return {
loader,
options: getSwcLoaderOptions({isServer, bundlerName: 'rspack'}),
options: getSwcLoaderOptions({isServer}),
};
};
}
Expand Down
5 changes: 1 addition & 4 deletions packages/docusaurus-bundler/src/swc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@

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

export function getSwcLoaderOptions({
isServer,
bundlerName,
}: {
isServer: boolean;
bundlerName: CurrentBundler['name'];
}): SwcLoaderOptions {
return {
env: {
// Rspack resolves the client queries with its own Browserslist data
targets: isServer ? getServerTargets({bundlerName}) : getClientQueries(),
targets: isServer ? getServerTargets() : getClientQueries(),
},
jsc: {
parser: {
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus/src/webpack/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export async function createBaseConfig({
// Changing the target browsers or Node.js version must evict the cache
// The same Browserslist queries can match other browsers over time and
// after data upgrades, for example "baseline widely available"
getTargets({isServer, bundlerName: props.currentBundler.name}),
getTargets({isServer}),
// The plugin code computing loader options is not a build dependency
// Upgrading a third-party plugin must evict the cache
siteMetadata.pluginVersions,
Expand Down
Loading