From 09eb5f51aa0fbd388c268786b2b4a2832f982bfd Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 12:18:42 +0800 Subject: [PATCH 01/10] feat: support autoExternal --- packages/core/src/config.ts | 12 ++++++++++-- packages/core/src/types/config/index.ts | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index c698cf7e7..7bef71626 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -20,6 +20,7 @@ import type { Syntax, } from './types/config'; import { getDefaultExtension } from './utils/extension'; +import { getAutoExternal } from './utils/external'; import { calcLongestCommonPath } from './utils/helper'; import { color } from './utils/helper'; import { nodeBuiltInModules } from './utils/helper'; @@ -386,20 +387,26 @@ async function composeLibRsbuildConfig( configPath: string, ) { const config = mergeRsbuildConfig(rsbuildConfig, libConfig); + const rootPath = dirname(configPath); - const { format, autoExtension = true } = config; + const { format, autoExtension = true, autoExternal = true } = config; const formatConfig = composeFormatConfig(format!); const autoExtensionConfig = composeAutoExtensionConfig( format!, - dirname(configPath), + rootPath, autoExtension, ); + const bundleConfig = composeBundleConfig(config.bundle); const targetConfig = composeTargetConfig(config.output?.target); const syntaxConfig = composeSyntaxConfig( config.output?.syntax, config.output?.target, ); + const autoExternalConfig = getAutoExternal({ + autoExternal, + pkgJson: {}, + }); const entryConfig = await composeEntryConfig( config.source?.entry, config.bundle, @@ -410,6 +417,7 @@ async function composeLibRsbuildConfig( return mergeRsbuildConfig( formatConfig, autoExtensionConfig, + autoExternalConfig, syntaxConfig, bundleConfig, targetConfig, diff --git a/packages/core/src/types/config/index.ts b/packages/core/src/types/config/index.ts index c7486c806..10f7ab558 100644 --- a/packages/core/src/types/config/index.ts +++ b/packages/core/src/types/config/index.ts @@ -31,10 +31,19 @@ export type Dts = } | false; +export type AutoExternal = + | boolean + | { + dependencies: boolean; + devDependencies: boolean; + peerDependencies: boolean; + }; + export interface LibConfig extends RsbuildConfig { bundle?: boolean; format?: Format; autoExtension?: boolean; + autoExternal?: AutoExternal; output?: RsbuildConfig['output'] & { /** Support esX and browserslist query */ syntax?: Syntax; From a2fc8597514242a48d485a7d5885bf173863ccb6 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 16:08:28 +0800 Subject: [PATCH 02/10] feat: support bundle autoExternal --- e2e/cases/auto-external/default/index.test.ts | 15 ++++ e2e/cases/auto-external/default/package.json | 5 ++ .../auto-external/default/rslib.config.ts | 11 +++ e2e/cases/auto-external/default/src/index.ts | 5 ++ e2e/cases/auto-external/false/index.test.ts | 15 ++++ e2e/cases/auto-external/false/package.json | 5 ++ e2e/cases/auto-external/false/rslib.config.ts | 20 +++++ e2e/cases/auto-external/false/src/index.ts | 5 ++ packages/core/__mocks__/rslog.cjs | 5 ++ packages/core/src/config.ts | 25 +++--- packages/core/src/types/config/index.ts | 6 +- packages/core/src/types/index.ts | 2 + packages/core/src/types/utils.ts | 6 ++ packages/core/src/utils/extension.ts | 28 ++----- packages/core/src/utils/external.ts | 46 +++++++++++ packages/core/src/utils/helper.ts | 19 +++++ packages/core/tests/config.test.ts | 4 +- packages/core/tests/extension.test.ts | 24 ++++-- packages/core/tests/external.test.ts | 76 +++++++++++++++++++ packages/core/tests/helper.test.ts | 56 +++----------- packages/core/tests/lcp.test.ts | 53 +++++++++++++ pnpm-lock.yaml | 12 +++ 22 files changed, 352 insertions(+), 91 deletions(-) create mode 100644 e2e/cases/auto-external/default/index.test.ts create mode 100644 e2e/cases/auto-external/default/package.json create mode 100644 e2e/cases/auto-external/default/rslib.config.ts create mode 100644 e2e/cases/auto-external/default/src/index.ts create mode 100644 e2e/cases/auto-external/false/index.test.ts create mode 100644 e2e/cases/auto-external/false/package.json create mode 100644 e2e/cases/auto-external/false/rslib.config.ts create mode 100644 e2e/cases/auto-external/false/src/index.ts create mode 100644 packages/core/__mocks__/rslog.cjs create mode 100644 packages/core/src/types/index.ts create mode 100644 packages/core/src/types/utils.ts create mode 100644 packages/core/src/utils/external.ts create mode 100644 packages/core/tests/external.test.ts create mode 100644 packages/core/tests/lcp.test.ts diff --git a/e2e/cases/auto-external/default/index.test.ts b/e2e/cases/auto-external/default/index.test.ts new file mode 100644 index 000000000..ed41df172 --- /dev/null +++ b/e2e/cases/auto-external/default/index.test.ts @@ -0,0 +1,15 @@ +import { buildAndGetResults } from '@e2e/helper'; +import { expect, test } from 'vitest'; + +test('auto external should works', async () => { + const fixturePath = __dirname; + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', + ); + + expect(entries.cjs).toContain( + 'var external_react_namespaceObject = require("react");', + ); +}); diff --git a/e2e/cases/auto-external/default/package.json b/e2e/cases/auto-external/default/package.json new file mode 100644 index 000000000..e1f4bc97b --- /dev/null +++ b/e2e/cases/auto-external/default/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "react": "^18.3.1" + } +} diff --git a/e2e/cases/auto-external/default/rslib.config.ts b/e2e/cases/auto-external/default/rslib.config.ts new file mode 100644 index 000000000..03252f356 --- /dev/null +++ b/e2e/cases/auto-external/default/rslib.config.ts @@ -0,0 +1,11 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [generateBundleEsmConfig(__dirname), generateBundleCjsConfig(__dirname)], + source: { + entry: { + main: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/auto-external/default/src/index.ts b/e2e/cases/auto-external/default/src/index.ts new file mode 100644 index 000000000..065585aab --- /dev/null +++ b/e2e/cases/auto-external/default/src/index.ts @@ -0,0 +1,5 @@ +import React from 'react'; + +export const foo = () => { + return React.version; +}; diff --git a/e2e/cases/auto-external/false/index.test.ts b/e2e/cases/auto-external/false/index.test.ts new file mode 100644 index 000000000..8a7f2b581 --- /dev/null +++ b/e2e/cases/auto-external/false/index.test.ts @@ -0,0 +1,15 @@ +import { buildAndGetResults } from '@e2e/helper'; +import { expect, test } from 'vitest'; + +test('auto external false should works', async () => { + const fixturePath = __dirname; + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).not.toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', + ); + + expect(entries.cjs).not.toContain( + 'var external_react_namespaceObject = require("react");', + ); +}); diff --git a/e2e/cases/auto-external/false/package.json b/e2e/cases/auto-external/false/package.json new file mode 100644 index 000000000..e1f4bc97b --- /dev/null +++ b/e2e/cases/auto-external/false/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "react": "^18.3.1" + } +} diff --git a/e2e/cases/auto-external/false/rslib.config.ts b/e2e/cases/auto-external/false/rslib.config.ts new file mode 100644 index 000000000..f5d3b7db3 --- /dev/null +++ b/e2e/cases/auto-external/false/rslib.config.ts @@ -0,0 +1,20 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + { + ...generateBundleEsmConfig(__dirname), + autoExternal: false, + }, + { + ...generateBundleCjsConfig(__dirname), + autoExternal: false, + }, + ], + source: { + entry: { + main: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/auto-external/false/src/index.ts b/e2e/cases/auto-external/false/src/index.ts new file mode 100644 index 000000000..065585aab --- /dev/null +++ b/e2e/cases/auto-external/false/src/index.ts @@ -0,0 +1,5 @@ +import React from 'react'; + +export const foo = () => { + return React.version; +}; diff --git a/packages/core/__mocks__/rslog.cjs b/packages/core/__mocks__/rslog.cjs new file mode 100644 index 000000000..a0bcd4bd1 --- /dev/null +++ b/packages/core/__mocks__/rslog.cjs @@ -0,0 +1,5 @@ +module.exports = { + logger: { + warn: () => {}, + }, +}; diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 1c73ffe49..1c27bee65 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -13,17 +13,21 @@ import { DEFAULT_CONFIG_NAME, DEFAULT_EXTENSIONS } from './constant'; import type { Format, LibConfig, + PkgJson, RslibConfig, RslibConfigAsyncFn, RslibConfigExport, RslibConfigSyncFn, Syntax, -} from './types/config'; +} from './types'; import { getDefaultExtension } from './utils/extension'; -import { getAutoExternal } from './utils/external'; -import { calcLongestCommonPath } from './utils/helper'; -import { color } from './utils/helper'; -import { nodeBuiltInModules } from './utils/helper'; +import { applyAutoExternal } from './utils/external'; +import { + calcLongestCommonPath, + color, + nodeBuiltInModules, + readPackageJson, +} from './utils/helper'; import { logger } from './utils/logger'; import { transformSyntaxToBrowserslist } from './utils/syntax'; @@ -167,12 +171,12 @@ const composeFormatConfig = (format: Format): RsbuildConfig => { const composeAutoExtensionConfig = ( format: Format, - root: string, autoExtension: boolean, + pkgJson?: PkgJson, ): RsbuildConfig => { const { jsExtension } = getDefaultExtension({ format, - root, + pkgJson, autoExtension, }); @@ -388,13 +392,14 @@ async function composeLibRsbuildConfig( ) { const config = mergeRsbuildConfig(rsbuildConfig, libConfig); const rootPath = dirname(configPath); + const pkgJson = readPackageJson(rootPath); const { format, autoExtension = true, autoExternal = true } = config; const formatConfig = composeFormatConfig(format!); const autoExtensionConfig = composeAutoExtensionConfig( format!, - rootPath, autoExtension, + pkgJson, ); const bundleConfig = composeBundleConfig(config.bundle); @@ -403,9 +408,9 @@ async function composeLibRsbuildConfig( config.output?.syntax, config.output?.target, ); - const autoExternalConfig = getAutoExternal({ + const autoExternalConfig = applyAutoExternal({ autoExternal, - pkgJson: {}, + pkgJson, }); const entryConfig = await composeEntryConfig( config.source?.entry, diff --git a/packages/core/src/types/config/index.ts b/packages/core/src/types/config/index.ts index 10f7ab558..df08a54f6 100644 --- a/packages/core/src/types/config/index.ts +++ b/packages/core/src/types/config/index.ts @@ -34,9 +34,9 @@ export type Dts = export type AutoExternal = | boolean | { - dependencies: boolean; - devDependencies: boolean; - peerDependencies: boolean; + dependencies?: boolean; + devDependencies?: boolean; + peerDependencies?: boolean; }; export interface LibConfig extends RsbuildConfig { diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts new file mode 100644 index 000000000..1d6a9e831 --- /dev/null +++ b/packages/core/src/types/index.ts @@ -0,0 +1,2 @@ +export * from './config'; +export * from './utils'; diff --git a/packages/core/src/types/utils.ts b/packages/core/src/types/utils.ts new file mode 100644 index 000000000..8b3d31293 --- /dev/null +++ b/packages/core/src/types/utils.ts @@ -0,0 +1,6 @@ +export type PkgJson = { + dependencies?: Record; + peerDependencies?: Record; + devDependencies?: Record; + [key: string]: unknown; +}; diff --git a/packages/core/src/utils/extension.ts b/packages/core/src/utils/extension.ts index fc6b5f500..98e64c2b1 100644 --- a/packages/core/src/utils/extension.ts +++ b/packages/core/src/utils/extension.ts @@ -1,18 +1,16 @@ -import fs from 'node:fs'; -import { resolve } from 'node:path'; -import type { Format } from 'src/types/config'; +import type { Format, PkgJson } from 'src/types'; import { logger } from './logger'; export const getDefaultExtension = (options: { format: Format; - root: string; + pkgJson?: PkgJson; autoExtension: boolean; }): { jsExtension: string; dtsExtension: string; isModule?: boolean; } => { - const { format, root, autoExtension } = options; + const { format, pkgJson, autoExtension } = options; let jsExtension = '.js'; let dtsExtension = '.d.ts'; @@ -24,10 +22,9 @@ export const getDefaultExtension = (options: { }; } - const pkgJsonPath = resolve(root, './package.json'); - if (!fs.existsSync(pkgJsonPath)) { + if (!pkgJson) { logger.warn( - `package.json does not exist in ${pkgJsonPath}, autoExtension will not be applied.`, + 'autoExtension configuration will not be applied due to read package.json failed', ); return { jsExtension, @@ -35,20 +32,7 @@ export const getDefaultExtension = (options: { }; } - let isModule = false; - - try { - const json = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); - isModule = json.type === 'module'; - } catch (e) { - logger.warn( - `Failed to parse ${pkgJsonPath}, it might not be valid JSON, autoExtension will not be applied.`, - ); - return { - jsExtension, - dtsExtension, - }; - } + const isModule = pkgJson.type === 'module'; if (isModule && format === 'cjs') { jsExtension = '.cjs'; diff --git a/packages/core/src/utils/external.ts b/packages/core/src/utils/external.ts new file mode 100644 index 000000000..883766465 --- /dev/null +++ b/packages/core/src/utils/external.ts @@ -0,0 +1,46 @@ +import type { RsbuildConfig } from '@rsbuild/core'; +import type { PkgJson } from '../types'; +import type { AutoExternal } from '../types/config'; +import { logger } from './logger'; + +export const applyAutoExternal = (options: { + autoExternal: AutoExternal; + pkgJson?: PkgJson; +}): RsbuildConfig => { + const { autoExternal, pkgJson } = options; + + if (!autoExternal) { + return {}; + } + + if (!pkgJson) { + logger.warn( + 'autoExternal configuration will not be applied due to read package.json failed', + ); + return {}; + } + + const externalOptions = { + dependencies: true, + peerDependencies: true, + devDependencies: false, + ...(autoExternal === true ? {} : autoExternal), + }; + + const externals = ( + ['dependencies', 'peerDependencies', 'devDependencies'] as const + ).reduce((prev, type) => { + if (externalOptions[type]) { + return pkgJson[type] ? prev.concat(Object.keys(pkgJson[type]!)) : prev; + } + return prev; + }, []); + + return externals.length + ? { + output: { + externals, + }, + } + : {}; +}; diff --git a/packages/core/src/utils/helper.ts b/packages/core/src/utils/helper.ts index 6d522bf76..be18d67fc 100644 --- a/packages/core/src/utils/helper.ts +++ b/packages/core/src/utils/helper.ts @@ -1,6 +1,9 @@ +import fs from 'node:fs'; import fsP from 'node:fs/promises'; import path from 'node:path'; import color from 'picocolors'; +import type { PkgJson } from '../types'; +import { logger } from './logger'; /** * Node.js built-in modules. @@ -99,4 +102,20 @@ async function calcLongestCommonPath( return lca; } +export const readPackageJson = (rootPath: string): undefined | PkgJson => { + const pkgJsonPath = path.resolve(rootPath, './package.json'); + + if (!fs.existsSync(pkgJsonPath)) { + logger.warn(`package.json does not exist in the ${rootPath} directory`); + return; + } + + try { + return JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); + } catch (err) { + logger.warn(`Failed to parse ${pkgJsonPath}, it might not be valid JSON`); + return; + } +}; + export { color, calcLongestCommonPath }; diff --git a/packages/core/tests/config.test.ts b/packages/core/tests/config.test.ts index d64f8bd3c..290d310ea 100644 --- a/packages/core/tests/config.test.ts +++ b/packages/core/tests/config.test.ts @@ -1,8 +1,10 @@ import { join } from 'node:path'; -import { describe, expect, test } from 'vitest'; +import { describe, expect, test, vi } from 'vitest'; import { composeCreateRsbuildConfig, loadConfig } from '../src/config'; import type { RslibConfig } from '../src/types/config'; +vi.mock('rslog'); + describe('Should load config file correctly', () => { test('Load config.js in cjs project', async () => { const fixtureDir = join(__dirname, 'fixtures/config/cjs'); diff --git a/packages/core/tests/extension.test.ts b/packages/core/tests/extension.test.ts index eedadcf68..7e5b05f39 100644 --- a/packages/core/tests/extension.test.ts +++ b/packages/core/tests/extension.test.ts @@ -1,12 +1,13 @@ -import { join } from 'node:path'; -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { getDefaultExtension } from '../src/utils/extension'; +vi.mock('rslog'); + describe('should get extension correctly', () => { it('autoExtension is false', () => { const options = { format: 'cjs', - root: '/path/to/root', + pkgJson: {}, autoExtension: false, }; @@ -21,7 +22,6 @@ describe('should get extension correctly', () => { it('package.json is broken', () => { const options = { format: 'cjs', - root: '/path/to/root', autoExtension: true, }; @@ -36,7 +36,9 @@ describe('should get extension correctly', () => { it('format is cjs and type is module in package.json', () => { const options = { format: 'cjs', - root: join(__dirname, 'fixtures/extension/type-module'), + pkgJson: { + type: 'module', + }, autoExtension: true, }; @@ -52,7 +54,9 @@ describe('should get extension correctly', () => { it('format is cjs and type is commonjs in package.json', () => { const options = { format: 'cjs', - root: join(__dirname, 'fixtures/extension/type-commonjs'), + pkgJson: { + type: 'commonjs', + }, autoExtension: true, }; @@ -68,7 +72,9 @@ describe('should get extension correctly', () => { it('format is esm and type is commonjs in package.json', () => { const options = { format: 'esm', - root: join(__dirname, 'fixtures/extension/type-commonjs'), + pkgJson: { + type: 'commonjs', + }, autoExtension: true, }; @@ -84,7 +90,9 @@ describe('should get extension correctly', () => { it('format is esm and type is module in package.json', () => { const options = { format: 'esm', - root: join(__dirname, 'fixtures/extension/type-module'), + pkgJson: { + type: 'module', + }, autoExtension: true, }; diff --git a/packages/core/tests/external.test.ts b/packages/core/tests/external.test.ts new file mode 100644 index 000000000..a09d31397 --- /dev/null +++ b/packages/core/tests/external.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it, vi } from 'vitest'; +import { applyAutoExternal } from '../src/utils/external'; + +vi.mock('rslog'); + +describe('should applyAutoExternal correctly', () => { + it('autoExternal is true', () => { + const result = applyAutoExternal({ + autoExternal: true, + pkgJson: { + dependencies: { + foo: '1.0.0', + }, + devDependencies: { + bar: '1.0.0', + }, + peerDependencies: { + baz: '1.0.0', + }, + }, + }); + + expect(result).toEqual({ + output: { + externals: ['foo', 'baz'], + }, + }); + }); + + it('autoExternal is object', () => { + const result = applyAutoExternal({ + autoExternal: { + peerDependencies: false, + devDependencies: true, + }, + pkgJson: { + dependencies: { + foo: '1.0.0', + }, + devDependencies: { + bar: '1.0.0', + }, + peerDependencies: { + baz: '1.0.0', + }, + }, + }); + + expect(result).toEqual({ + output: { + externals: ['foo', 'bar'], + }, + }); + }); + + it('autoExternal is false', () => { + const result = applyAutoExternal({ + autoExternal: false, + pkgJson: { + dependencies: { + foo: '1.0.0', + }, + }, + }); + + expect(result).toEqual({}); + }); + + it('read package.json failed', () => { + const result = applyAutoExternal({ + autoExternal: true, + }); + + expect(result).toEqual({}); + }); +}); diff --git a/packages/core/tests/helper.test.ts b/packages/core/tests/helper.test.ts index 4da34e31f..dfbaa3b72 100644 --- a/packages/core/tests/helper.test.ts +++ b/packages/core/tests/helper.test.ts @@ -1,52 +1,14 @@ -import { vol } from 'memfs'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { calcLongestCommonPath } from '../src/utils/helper'; +import { join } from 'node:path'; +import { expect, it, vi } from 'vitest'; +import { readPackageJson } from '../src/utils/helper'; -vi.mock('node:fs'); -vi.mock('node:fs/promises'); +vi.mock('rslog'); -describe('LCA calculate correctly', () => { - beforeEach(() => { - vol.reset(); - }); - - it('empty array', async () => { - const result = await calcLongestCommonPath([]); - expect(result).toBe(null); - }); - - it('correct 1', async () => { - vol.fromJSON({ '/Users/Someone/project-a/src': null }); - - const result = await calcLongestCommonPath([ - '/Users/Someone/project-a/src/helpers', - '/Users/Someone/project-a/src', - '/Users/Someone/project-a/src/utils', - ]); - expect(result).toBe('/Users/Someone/project-a/src'); - }); - - it('correct 2', async () => { - vol.fromJSON({ '/Users/Someone/project-monorepo': null }); - - const result = await calcLongestCommonPath([ - '/Users/Someone/project-monorepo/packages-a/src/index.ts', - '/Users/Someone/project-monorepo/packages-util/src/index.js', - '/Users/Someone/project-monorepo/script.js', - ]); - - expect(result).toBe('/Users/Someone/project-monorepo'); - }); - - it('correct 3', async () => { - vol.fromJSON({ - '/Users/Someone/project/src/index.js': '', - }); - - const result = await calcLongestCommonPath([ - '/Users/Someone/project/src/index.js', - ]); +it('readPackageJson correctly', async () => { + expect(readPackageJson('path/to/root')).toBeUndefined(); + console.log('__dirname', __dirname); - expect(result).toBe('/Users/Someone/project/src'); + expect(readPackageJson(join(__dirname, 'fixtures/config/esm'))).toEqual({ + type: 'module', }); }); diff --git a/packages/core/tests/lcp.test.ts b/packages/core/tests/lcp.test.ts new file mode 100644 index 000000000..97bdcc635 --- /dev/null +++ b/packages/core/tests/lcp.test.ts @@ -0,0 +1,53 @@ +import { vol } from 'memfs'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { calcLongestCommonPath } from '../src/utils/helper'; + +vi.mock('node:fs'); +vi.mock('node:fs/promises'); + +// LCP test mock will affect other tests +describe('LCP calculate correctly', () => { + beforeEach(() => { + vol.reset(); + }); + + it('empty array', async () => { + const result = await calcLongestCommonPath([]); + expect(result).toBe(null); + }); + + it('correct 1', async () => { + vol.fromJSON({ '/Users/Someone/project-a/src': null }); + + const result = await calcLongestCommonPath([ + '/Users/Someone/project-a/src/helpers', + '/Users/Someone/project-a/src', + '/Users/Someone/project-a/src/utils', + ]); + expect(result).toBe('/Users/Someone/project-a/src'); + }); + + it('correct 2', async () => { + vol.fromJSON({ '/Users/Someone/project-monorepo': null }); + + const result = await calcLongestCommonPath([ + '/Users/Someone/project-monorepo/packages-a/src/index.ts', + '/Users/Someone/project-monorepo/packages-util/src/index.js', + '/Users/Someone/project-monorepo/script.js', + ]); + + expect(result).toBe('/Users/Someone/project-monorepo'); + }); + + it('correct 3', async () => { + vol.fromJSON({ + '/Users/Someone/project/src/index.js': '', + }); + + const result = await calcLongestCommonPath([ + '/Users/Someone/project/src/index.js', + ]); + + expect(result).toBe('/Users/Someone/project/src'); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb860755f..0a430a473 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,6 +94,18 @@ importers: specifier: ^11.2.0 version: 11.2.0 + e2e/cases/auto-external/default: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + + e2e/cases/auto-external/false: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + e2e/cases/autoExtension/type-commonjs: {} e2e/cases/autoExtension/type-module: {} From f6c65928fdedf781080f026618292893cf7465c4 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 16:24:15 +0800 Subject: [PATCH 03/10] fix: merge conflict --- CONTRIBUTING.md | 2 +- e2e/cases/auto-external/default/package.json | 1 + e2e/cases/auto-external/false/package.json | 1 + .../dts/__snapshots__/index.test.ts.snap | 2 +- .../dts/bundle-false/autoExtension.config.ts | 21 ++++ e2e/cases/dts/bundle-false/package.json | 6 + e2e/cases/dts/bundle/autoExtension.config.ts | 18 +++ e2e/cases/dts/index.test.ts | 54 ++++++++- examples/express-plugin/rslib.config.ts | 1 - examples/react-component/rslib.config.ts | 1 - package.json | 2 +- packages/core/src/config.ts | 30 ++--- .../tests/__snapshots__/config.test.ts.snap | 2 +- packages/core/tests/helper.test.ts | 1 - packages/plugin-dts/package.json | 1 + packages/plugin-dts/src/apiExtractor.ts | 19 +++- packages/plugin-dts/src/dts.ts | 20 +++- packages/plugin-dts/src/index.ts | 1 + packages/plugin-dts/src/tsc.ts | 26 +++-- packages/plugin-dts/src/utils.ts | 31 +++++- pnpm-lock.yaml | 105 +++++++++--------- 21 files changed, 250 insertions(+), 95 deletions(-) create mode 100644 e2e/cases/dts/bundle-false/autoExtension.config.ts create mode 100644 e2e/cases/dts/bundle-false/package.json create mode 100644 e2e/cases/dts/bundle/autoExtension.config.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 197ebcb35..2fd3a484b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,4 +123,4 @@ The project is still in its early stages and under active development, so it pos | Package | Link | | ------------ | ------------------------------------------------------- | -| @rspack/core | [PR](https://github.com/web-infra-dev/rspack/pull/7394) | +| @rspack/core | [PR](https://github.com/web-infra-dev/rspack/pull/7493) | diff --git a/e2e/cases/auto-external/default/package.json b/e2e/cases/auto-external/default/package.json index e1f4bc97b..fff959298 100644 --- a/e2e/cases/auto-external/default/package.json +++ b/e2e/cases/auto-external/default/package.json @@ -1,4 +1,5 @@ { + "name": "@e2e/auto-externals-default", "dependencies": { "react": "^18.3.1" } diff --git a/e2e/cases/auto-external/false/package.json b/e2e/cases/auto-external/false/package.json index e1f4bc97b..16b427781 100644 --- a/e2e/cases/auto-external/false/package.json +++ b/e2e/cases/auto-external/false/package.json @@ -1,4 +1,5 @@ { + "name": "@e2e/auto-externals-false", "dependencies": { "react": "^18.3.1" } diff --git a/e2e/cases/dts/__snapshots__/index.test.ts.snap b/e2e/cases/dts/__snapshots__/index.test.ts.snap index 099f93cc9..4bce88be6 100644 --- a/e2e/cases/dts/__snapshots__/index.test.ts.snap +++ b/e2e/cases/dts/__snapshots__/index.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`dts when bundle: false > basic 1`] = ` +exports[`dts when bundle: false > basic 2`] = ` { "./dist/esm/index.d.ts": "export * from './utils/numbers'; export * from './utils/strings'; diff --git a/e2e/cases/dts/bundle-false/autoExtension.config.ts b/e2e/cases/dts/bundle-false/autoExtension.config.ts new file mode 100644 index 000000000..39499785f --- /dev/null +++ b/e2e/cases/dts/bundle-false/autoExtension.config.ts @@ -0,0 +1,21 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig(__dirname, { + bundle: false, + }), + generateBundleCjsConfig(__dirname, { + bundle: false, + dts: { + bundle: false, + }, + }), + ], + source: { + entry: { + main: ['./src/**'], + }, + }, +}); diff --git a/e2e/cases/dts/bundle-false/package.json b/e2e/cases/dts/bundle-false/package.json new file mode 100644 index 000000000..aa0ce962e --- /dev/null +++ b/e2e/cases/dts/bundle-false/package.json @@ -0,0 +1,6 @@ +{ + "name": "dts-bundle-false-test", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/e2e/cases/dts/bundle/autoExtension.config.ts b/e2e/cases/dts/bundle/autoExtension.config.ts new file mode 100644 index 000000000..c58dcca06 --- /dev/null +++ b/e2e/cases/dts/bundle/autoExtension.config.ts @@ -0,0 +1,18 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [ + generateBundleEsmConfig(__dirname), + generateBundleCjsConfig(__dirname, { + dts: { + bundle: true, + }, + }), + ], + source: { + entry: { + main: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/dts/index.test.ts b/e2e/cases/dts/index.test.ts index 7c7cad48b..08a8f5ae2 100644 --- a/e2e/cases/dts/index.test.ts +++ b/e2e/cases/dts/index.test.ts @@ -11,8 +11,14 @@ describe('dts when bundle: false', () => { 'dts', ); - expect(files.esm?.length).toBe(4); - expect(files.esm?.[0]!.endsWith('.d.ts')).toEqual(true); + expect(files.esm).toMatchInlineSnapshot(` + [ + "./dist/esm/index.d.ts", + "./dist/esm/sum.d.ts", + "./dist/esm/utils/numbers.d.ts", + "./dist/esm/utils/strings.d.ts", + ] + `); expect(contents.esm).toMatchSnapshot(); }); @@ -34,8 +40,15 @@ describe('dts when bundle: false', () => { 'distPath.config.ts', 'dts', ); - expect(files.esm?.length).toBe(4); - expect(files.esm?.[0]!.startsWith('./dist/custom')).toEqual(true); + + expect(files.esm).toMatchInlineSnapshot(` + [ + "./dist/custom/index.d.ts", + "./dist/custom/sum.d.ts", + "./dist/custom/utils/numbers.d.ts", + "./dist/custom/utils/strings.d.ts", + ] + `); }); test('abortOnError: false', async () => { @@ -48,6 +61,24 @@ describe('dts when bundle: false', () => { expect(isSuccess).toBe(true); }); + + test('autoExtension: true', async () => { + const fixturePath = join(__dirname, 'bundle-false'); + const { files } = await buildAndGetResults( + fixturePath, + 'autoExtension.config.ts', + 'dts', + ); + + expect(files.cjs).toMatchInlineSnapshot(` + [ + "./dist/cjs/index.d.cts", + "./dist/cjs/sum.d.cts", + "./dist/cjs/utils/numbers.d.cts", + "./dist/cjs/utils/strings.d.cts", + ] + `); + }); }); describe('dts when bundle: true', () => { @@ -59,7 +90,7 @@ describe('dts when bundle: true', () => { 'dts', ); - expect(entryFiles.esm!.endsWith('index.d.ts')).toEqual(true); + expect(entryFiles.esm).toEqual('./dist/esm/index.d.ts'); expect(entries).toMatchSnapshot(); }); @@ -82,7 +113,7 @@ describe('dts when bundle: true', () => { 'dts', ); - expect(entryFiles.esm!.startsWith('./dist/custom')).toEqual(true); + expect(entryFiles.esm).toEqual('./dist/custom/index.d.ts'); }); test('abortOnError: false', async () => { @@ -95,4 +126,15 @@ describe('dts when bundle: true', () => { expect(isSuccess).toBe(true); }); + + test('autoExtension: true', async () => { + const fixturePath = join(__dirname, 'bundle'); + const { entryFiles } = await buildAndGetResults( + fixturePath, + 'autoExtension.config.ts', + 'dts', + ); + + expect(entryFiles.cjs).toEqual('./dist/cjs/index.d.cts'); + }); }); diff --git a/examples/express-plugin/rslib.config.ts b/examples/express-plugin/rslib.config.ts index 3d5b07565..f4d96ea59 100644 --- a/examples/express-plugin/rslib.config.ts +++ b/examples/express-plugin/rslib.config.ts @@ -1,7 +1,6 @@ import { defineConfig } from '@rslib/core'; const shared = { - autoExtension: true, dts: { bundle: false, }, diff --git a/examples/react-component/rslib.config.ts b/examples/react-component/rslib.config.ts index db1d311d7..d97011009 100644 --- a/examples/react-component/rslib.config.ts +++ b/examples/react-component/rslib.config.ts @@ -2,7 +2,6 @@ import { pluginReact } from '@rsbuild/plugin-react'; import { defineConfig } from '@rslib/core'; const shared = { - autoExtension: true, dts: { bundle: false, }, diff --git a/package.json b/package.json index edc4f7b72..7cf5eb35c 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ }, "pnpm": { "overrides": { - "@rspack/core": "npm:@rspack/core-canary@1.0.0-canary-338cfbe-20240731183605" + "@rspack/core": "npm:@rspack/core-canary@1.0.0-canary-af0452f-20240808052639" } } } diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 1c27bee65..492230359 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -119,7 +119,7 @@ const composeFormatConfig = (format: Format): RsbuildConfig => { return { tools: { rspack: { - externalsType: 'module', + externalsType: 'module-import', output: { module: true, chunkFormat: 'module', @@ -173,19 +173,25 @@ const composeAutoExtensionConfig = ( format: Format, autoExtension: boolean, pkgJson?: PkgJson, -): RsbuildConfig => { - const { jsExtension } = getDefaultExtension({ +): { + config: RsbuildConfig; + dtsExtension: string; +} => { + const { jsExtension, dtsExtension } = getDefaultExtension({ format, pkgJson, autoExtension, }); return { - output: { - filename: { - js: `[name]${jsExtension}`, + config: { + output: { + filename: { + js: `[name]${jsExtension}`, + }, }, }, + dtsExtension, }; }; @@ -330,6 +336,7 @@ const composeBundleConfig = (bundle = true): RsbuildConfig => { const composeDtsConfig = async ( libConfig: LibConfig, + dtsExtension: string, ): Promise => { const { dts, bundle, output } = libConfig; @@ -342,6 +349,7 @@ const composeDtsConfig = async ( bundle: dts?.bundle ?? bundle, distPath: dts?.distPath ?? output?.distPath?.root ?? './dist', abortOnError: dts?.abortOnError ?? true, + dtsExtension, }), ], }; @@ -396,12 +404,8 @@ async function composeLibRsbuildConfig( const { format, autoExtension = true, autoExternal = true } = config; const formatConfig = composeFormatConfig(format!); - const autoExtensionConfig = composeAutoExtensionConfig( - format!, - autoExtension, - pkgJson, - ); - + const { config: autoExtensionConfig, dtsExtension } = + composeAutoExtensionConfig(format!, autoExtension, pkgJson); const bundleConfig = composeBundleConfig(config.bundle); const targetConfig = composeTargetConfig(config.output?.target); const syntaxConfig = composeSyntaxConfig( @@ -417,7 +421,7 @@ async function composeLibRsbuildConfig( config.bundle, dirname(configPath), ); - const dtsConfig = await composeDtsConfig(config); + const dtsConfig = await composeDtsConfig(config, dtsExtension); return mergeRsbuildConfig( formatConfig, diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index 5534b8aea..e7ac347d6 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -41,7 +41,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 "experiments": { "outputModule": true, }, - "externalsType": "module", + "externalsType": "module-import", "optimization": { "concatenateModules": true, }, diff --git a/packages/core/tests/helper.test.ts b/packages/core/tests/helper.test.ts index dfbaa3b72..15fd5fdc1 100644 --- a/packages/core/tests/helper.test.ts +++ b/packages/core/tests/helper.test.ts @@ -6,7 +6,6 @@ vi.mock('rslog'); it('readPackageJson correctly', async () => { expect(readPackageJson('path/to/root')).toBeUndefined(); - console.log('__dirname', __dirname); expect(readPackageJson(join(__dirname, 'fixtures/config/esm'))).toEqual({ type: 'module', diff --git a/packages/plugin-dts/package.json b/packages/plugin-dts/package.json index 7e3523e03..e7fd94536 100644 --- a/packages/plugin-dts/package.json +++ b/packages/plugin-dts/package.json @@ -30,6 +30,7 @@ "dev": "modern build --watch" }, "dependencies": { + "fast-glob": "^3.3.2", "picocolors": "1.0.1" }, "devDependencies": { diff --git a/packages/plugin-dts/src/apiExtractor.ts b/packages/plugin-dts/src/apiExtractor.ts index 58a5ec4bd..a92e1a00a 100644 --- a/packages/plugin-dts/src/apiExtractor.ts +++ b/packages/plugin-dts/src/apiExtractor.ts @@ -5,23 +5,34 @@ import { type ExtractorResult, } from '@microsoft/api-extractor'; import { logger } from '@rsbuild/core'; +import color from 'picocolors'; +import { getTimeCost } from './utils'; export type BundleOptions = { + name: string; cwd: string; outDir: string; + dtsExtension: string; entry?: string; tsconfigPath?: string; }; -export function bundleDts(options: BundleOptions): void { +export async function bundleDts(options: BundleOptions): Promise { const { + name, cwd, outDir, + dtsExtension, entry = 'index.d.ts', tsconfigPath = 'tsconfig.json', } = options; try { - const untrimmedFilePath = join(cwd, relative(cwd, outDir), 'index.d.ts'); + const start = Date.now(); + const untrimmedFilePath = join( + cwd, + relative(cwd, outDir), + `index${dtsExtension}`, + ); const internalConfig = { mainEntryPointFilePath: entry, // TODO: use !externals @@ -49,11 +60,11 @@ export function bundleDts(options: BundleOptions): void { }); if (!extractorResult.succeeded) { - throw new Error('API Extractor rollup error'); + throw new Error(`API Extractor error. ${color.gray(`(${name})`)}`); } logger.info( - `API Extractor writing package typings succeeded: ${untrimmedFilePath}`, + `API Extractor bundle DTS succeeded: ${color.cyan(untrimmedFilePath)} in ${getTimeCost(start)} ${color.gray(`(${name})`)}`, ); } catch (e) { logger.error('API Extractor', e); diff --git a/packages/plugin-dts/src/dts.ts b/packages/plugin-dts/src/dts.ts index aa4cb59d3..d6babe2e2 100644 --- a/packages/plugin-dts/src/dts.ts +++ b/packages/plugin-dts/src/dts.ts @@ -7,8 +7,16 @@ import { emitDts } from './tsc'; import { ensureTempDeclarationDir, loadTsconfig } from './utils'; export async function generateDts(data: DtsGenOptions): Promise { - const { tsconfigPath, distPath, bundle, entryPath, cwd, isWatch, name } = - data; + const { + bundle, + distPath, + entryPath, + tsconfigPath, + name, + cwd, + isWatch, + dtsExtension = '.d.ts', + } = data; logger.start(`Generating DTS... ${color.gray(`(${name})`)}`); const configPath = ts.findConfigFile(cwd, ts.sys.fileExists, tsconfigPath); if (!configPath) { @@ -47,11 +55,13 @@ export async function generateDts(data: DtsGenOptions): Promise { const bundleDtsIfNeeded = async () => { if (bundle === true) { const { bundleDts } = await import('./apiExtractor'); - bundleDts({ + await bundleDts({ + name, cwd, outDir, entry, tsconfigPath, + dtsExtension, }); } }; @@ -62,15 +72,17 @@ export async function generateDts(data: DtsGenOptions): Promise { } }; - emitDts( + await emitDts( { name, cwd, configPath, rootDir, declarationDir, + dtsExtension, }, onComplete, + bundle, isWatch, ); diff --git a/packages/plugin-dts/src/index.ts b/packages/plugin-dts/src/index.ts index c9fe0fad1..648c506bd 100644 --- a/packages/plugin-dts/src/index.ts +++ b/packages/plugin-dts/src/index.ts @@ -6,6 +6,7 @@ export type PluginDtsOptions = { bundle?: boolean; distPath?: string; abortOnError?: boolean; + dtsExtension?: string; }; export type DtsGenOptions = PluginDtsOptions & { diff --git a/packages/plugin-dts/src/tsc.ts b/packages/plugin-dts/src/tsc.ts index bc8584d10..3ee73b0fa 100644 --- a/packages/plugin-dts/src/tsc.ts +++ b/packages/plugin-dts/src/tsc.ts @@ -1,7 +1,12 @@ import { logger } from '@rsbuild/core'; import color from 'picocolors'; import * as ts from 'typescript'; -import { getFileLoc, loadTsconfig } from './utils'; +import { + getFileLoc, + getTimeCost, + loadTsconfig, + processDtsFiles, +} from './utils'; export type emitDtsOptions = { name: string; @@ -9,18 +14,17 @@ export type emitDtsOptions = { configPath: string; rootDir: string; declarationDir: string; + dtsExtension: string; }; -export function emitDts( +export async function emitDts( options: emitDtsOptions, onComplete: (isSuccess: boolean) => void, + bundle = false, isWatch = false, -): void { +): Promise { const start = Date.now(); - const getTimeCost = () => { - return `${Math.floor(Date.now() - start)}ms`; - }; - const { configPath, declarationDir, name } = options; + const { configPath, declarationDir, name, dtsExtension } = options; const { options: rawCompilerOptions, fileNames } = loadTsconfig(configPath); const compilerOptions = { @@ -57,6 +61,8 @@ export function emitDts( diagnosticMessages.push(message); } + await processDtsFiles(bundle, declarationDir, dtsExtension); + if (diagnosticMessages.length) { logger.error( `Failed to emit declaration files. ${color.gray(`(${name})`)}`, @@ -70,7 +76,7 @@ export function emitDts( } logger.info( - `DTS generation succeeded in ${getTimeCost()} ${color.gray(`(${name})`)}`, + `DTS generation succeeded in ${getTimeCost(start)} ${color.gray(`(${name})`)}`, ); } else { const createProgram = ts.createSemanticDiagnosticsBuilderProgram; @@ -92,7 +98,7 @@ export function emitDts( ); }; - const reportWatchStatusChanged: ts.WatchStatusReporter = ( + const reportWatchStatusChanged: ts.WatchStatusReporter = async ( diagnostic: ts.Diagnostic, _newLine: string, _options: ts.CompilerOptions, @@ -117,11 +123,13 @@ export function emitDts( } else { logger.error(message); } + await processDtsFiles(bundle, declarationDir, dtsExtension); } // 6193: 1 error if (diagnostic.code === 6193) { logger.error(message); + await processDtsFiles(bundle, declarationDir, dtsExtension); } }; diff --git a/packages/plugin-dts/src/utils.ts b/packages/plugin-dts/src/utils.ts index 90168c4ff..320adef90 100644 --- a/packages/plugin-dts/src/utils.ts +++ b/packages/plugin-dts/src/utils.ts @@ -1,5 +1,7 @@ -import fs, { writeFileSync } from 'node:fs'; +import fs from 'node:fs'; import path from 'node:path'; +import { logger } from '@rsbuild/core'; +import fg from 'fast-glob'; import color from 'picocolors'; import * as ts from 'typescript'; @@ -27,7 +29,7 @@ export function ensureTempDeclarationDir(cwd: string): string { fs.mkdirSync(dirPath, { recursive: true }); const gitIgnorePath = path.join(cwd, `${TEMP_FOLDER}/.gitignore`); - writeFileSync(gitIgnorePath, '**/*\n'); + fs.writeFileSync(gitIgnorePath, '**/*\n'); return dirPath; } @@ -43,3 +45,28 @@ export function getFileLoc(diagnostic: ts.Diagnostic): string { return ''; } + +export function getTimeCost(start: number): string { + return `${Math.floor(Date.now() - start)}ms`; +} + +export async function processDtsFiles( + bundle: boolean, + dir: string, + dtsExtension: string, +): Promise { + if (bundle) { + return; + } + + const dtsFiles = await fg(`${dir}/**/*.d.ts`); + + for (const file of dtsFiles) { + try { + const newFile = file.replace('.d.ts', dtsExtension); + fs.renameSync(file, newFile); + } catch (error) { + logger.error(`Error renaming DTS file ${file}: ${error}`); + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a430a473..d33259e3e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@rspack/core': npm:@rspack/core-canary@1.0.0-canary-338cfbe-20240731183605 + '@rspack/core': npm:@rspack/core-canary@1.0.0-canary-af0452f-20240808052639 importers: @@ -112,6 +112,8 @@ importers: e2e/cases/dts/bundle: {} + e2e/cases/dts/bundle-false: {} + e2e/scripts: {} examples/express-plugin: @@ -189,6 +191,9 @@ importers: packages/plugin-dts: dependencies: + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 picocolors: specifier: 1.0.1 version: 1.0.1 @@ -1239,56 +1244,56 @@ packages: peerDependencies: '@rsbuild/core': ^1.0.1-beta.9 - '@rspack/binding-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-lFl8Xt8QcNX0I1Kb/NfJYOa3B8iLBqw9T6CGylWbu0wQQ5TUnspGPfL7MIzi+mZ/eOaEcpIafUlCk+mcd5nC9Q==} + '@rspack/binding-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-VayW6Eytqn7TzoKvTeVR8k29JgEPOmnUFPRyoaf+QlATDR0pht4vwHeHCEYL587yxMw7pZ+DxfXgB1ReIViesA==} - '@rspack/binding-darwin-arm64-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-tO1ps4zfEk+3Sn4vKdn4RNcFqWl5IaNyYXZRHQtQXzJNAEBuSYeL9EDZMngjHQ7ymVfgwKR5Q+Tm0+SfPqO3cA==} + '@rspack/binding-darwin-arm64-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-rPS4GCOHbgXSociPieE5X2i2IXeADA+/1RD4grg+vvgKYzoZa8oVP4Nz6n67tj8jR7P6/eXjmbGwg8tXShFpyQ==} cpu: [arm64] os: [darwin] - '@rspack/binding-darwin-x64-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-puZ3ShmJZfj+wanaD6QX0sE3DFYDiSr3tHopLUPtDi2ogPR4EhhFmrHMHhZYcUetAxo9EDCVNolGn3hxIrpwcw==} + '@rspack/binding-darwin-x64-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-p7D2y7tYPReV6SNPB2FYv3OZeMnwU0WwlIinSDC0YJYZLwo5303zAnVY09s3R9t1Il86Du5wd9wRusSJKGN1/Q==} cpu: [x64] os: [darwin] - '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-JHh3W3l3dIbOtB8raKANqHn8L60IBTXx5CvjgoWHxqVlHeH8Szp7Uwnzf/7obWUbwONafOB9TBgqsKiRXtEn3w==} + '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-91KjddUlW5cFgE/Xy+l/KUkK/nMoKJjldeYvxUk7AyWpPW19vpP1kUpdpFmbjfinaAeXHCl0CiwIEMR3aVL1vw==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-/hkCF7w2ijmn260uPb49e3aaPjH/QWxymfLPI5nvC4+/Bk1XdYawIiy4A35Bv8kOuZciYYH3TMgkbXblqdamFA==} + '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-BT8PmQiCtEVTDWjZFur4ju7QoLhULZ2Qqfk7ZMA42TBFv2qpKpN0+Xpz/ZbiO+PEsjUrk2wib+MKppTGXOg2AA==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-Vpnqu3knK6YTmgvgIEFvEs1DbyVjyghdIrzIdkiJwhRF4AntZe3kxuM+x8fN94iDFHfRhWHTb1OkAooySaEGaw==} + '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-S9kb1X/xhPmyuNWr+VOW8gOZP0UKD0pyDOF/scaqdTxIsdq8x2Udpk9NG+GpJqsfJQq6qOnbN/4o/POi9dK3Bw==} cpu: [x64] os: [linux] - '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-ALlBgaoRXzYLeBfJLjVF9BpegYDD3wFk7Dtfnk/Ij9kTbzPmhYN5+5FIlTpANBbXfrknp+XqYoPRLsXI1EXtog==} + '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-JzzFQHKnXMEz5pC8fMYNK2w3v+WagOQGZ2cgeQzofa3DxCGFBN8xkcjTByTITXHK9FxIkP5AxbmDwruEPr1ovw==} cpu: [x64] os: [linux] - '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-ZH1F1zDnjRBPjfO1JzEwa9Wivy8oH81VFQVny0EWhqkzybjldrecAAp51+tsHcEiq8Tuc4c6BhJMfk2QWzQ+BQ==} + '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-QKYbZ7g1GeTn2HU+mK4UL9cMb1HZXsS2Bvp2Tkwqp4bXq+XYWVEtEy1t3veOhz+tx0NRvZ4R9F+XByE/eGRHHg==} cpu: [arm64] os: [win32] - '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-ww0uq30GTb33UpQ5fP07elvfCedlH+CM9BKpNidPci97/mSLcn823/jCBW2yzLauxFbcAdTWabaV5UhvmTfkAQ==} + '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-efyygQRoZ1ZDfKNn54DVAPtf4FFg6O3pkPlUUI9nj4HJd1S3NIjeMeKSCH77O6Ypqrs0uAILoalRnbGrh+oeZw==} cpu: [ia32] os: [win32] - '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-W2rL0V0S2KL9yUKSy493In/gWBPCcNIn9Ry1xegTbpNMU/++F5T9ZqI/whHets0uQMU9cKWFfQZmsSzCrIXiTg==} + '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-9XMPNGDPYQRfL9fPiCZKuKnC9sXNV0xJ2SDGJ+XZ0VQcGZ9z6810jUHAQX2gHSg8p6kUAtSXh68HsNWsSBlF9w==} cpu: [x64] os: [win32] - '@rspack/core-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-gPjYRA29rstYJHkcWmLuIgRq2mCknj22A1E65tg4i/K5yI6nCUxi+nvGVBBvNWKky+5ikGZxWK5O2I0IyH7hsQ==} + '@rspack/core-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-zuZ2FEYZy6ePZv2YPyT71BUJr6h5ZG6W8/s6rUXzMUzEmT6wlF073QvM8AWk9xUAXyv3NPdh3Ql5Kvf1/2RaBw==} engines: {node: '>=16.0.0'} peerDependencies: '@swc/helpers': '>=0.5.1' @@ -1296,8 +1301,8 @@ packages: '@swc/helpers': optional: true - '@rspack/lite-tapable-canary@1.0.0-canary-338cfbe-20240731183605': - resolution: {integrity: sha512-emikuiIbELsdO28IxMgjkcw8sovk9/BF+L7V3Ix75NLFc2+5MZ8LGteUFrhxfuXr/7eFY1eje858ZmeRPNr4fw==} + '@rspack/lite-tapable-canary@1.0.0-canary-af0452f-20240808052639': + resolution: {integrity: sha512-YpKLntATp0tML6ILrUmANCC6geUosgRK71xy78Vo1v2urSV1v2MB08VL6sbrjy99GnDWzf5f/bzrtmeC78GOVw==} engines: {node: '>=16.0.0'} '@rspack/lite-tapable@1.0.0-beta.2': @@ -4160,7 +4165,7 @@ snapshots: '@rsbuild/core@1.0.1-beta.10': dependencies: - '@rspack/core': '@rspack/core-canary@1.0.0-canary-338cfbe-20240731183605(@swc/helpers@0.5.11)' + '@rspack/core': '@rspack/core-canary@1.0.0-canary-af0452f-20240808052639(@swc/helpers@0.5.11)' '@rspack/lite-tapable': 1.0.0-beta.2 '@swc/helpers': 0.5.11 caniuse-lite: 1.0.30001649 @@ -4174,55 +4179,55 @@ snapshots: '@rspack/plugin-react-refresh': 1.0.0-beta.1(react-refresh@0.14.2) react-refresh: 0.14.2 - '@rspack/binding-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-canary@1.0.0-canary-af0452f-20240808052639': optionalDependencies: - '@rspack/binding-darwin-arm64': '@rspack/binding-darwin-arm64-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-darwin-x64': '@rspack/binding-darwin-x64-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-linux-arm64-gnu': '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-linux-arm64-musl': '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-linux-x64-gnu': '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-linux-x64-musl': '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-win32-arm64-msvc': '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-win32-ia32-msvc': '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/binding-win32-x64-msvc': '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-338cfbe-20240731183605' - - '@rspack/binding-darwin-arm64-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-darwin-arm64': '@rspack/binding-darwin-arm64-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-darwin-x64': '@rspack/binding-darwin-x64-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-linux-arm64-gnu': '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-linux-arm64-musl': '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-linux-x64-gnu': '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-linux-x64-musl': '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-win32-arm64-msvc': '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-win32-ia32-msvc': '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/binding-win32-x64-msvc': '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-af0452f-20240808052639' + + '@rspack/binding-darwin-arm64-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-darwin-x64-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-darwin-x64-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-linux-arm64-gnu-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-linux-arm64-musl-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-linux-x64-gnu-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-linux-x64-musl-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-win32-arm64-msvc-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-win32-ia32-msvc-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-338cfbe-20240731183605': + '@rspack/binding-win32-x64-msvc-canary@1.0.0-canary-af0452f-20240808052639': optional: true - '@rspack/core-canary@1.0.0-canary-338cfbe-20240731183605(@swc/helpers@0.5.11)': + '@rspack/core-canary@1.0.0-canary-af0452f-20240808052639(@swc/helpers@0.5.11)': dependencies: '@module-federation/runtime-tools': 0.2.3 - '@rspack/binding': '@rspack/binding-canary@1.0.0-canary-338cfbe-20240731183605' - '@rspack/lite-tapable': '@rspack/lite-tapable-canary@1.0.0-canary-338cfbe-20240731183605' + '@rspack/binding': '@rspack/binding-canary@1.0.0-canary-af0452f-20240808052639' + '@rspack/lite-tapable': '@rspack/lite-tapable-canary@1.0.0-canary-af0452f-20240808052639' caniuse-lite: 1.0.30001649 optionalDependencies: '@swc/helpers': 0.5.11 - '@rspack/lite-tapable-canary@1.0.0-canary-338cfbe-20240731183605': {} + '@rspack/lite-tapable-canary@1.0.0-canary-af0452f-20240808052639': {} '@rspack/lite-tapable@1.0.0-beta.2': {} From f332f9f837f3b01eafb895d0f4238fb368d513e5 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 16:52:44 +0800 Subject: [PATCH 04/10] feat: externals configuration has higher priority than autoExternal --- e2e/cases/auto-external/default/package.json | 2 +- e2e/cases/auto-external/false/package.json | 2 +- .../with-externals/index.test.ts | 15 ++++++++ .../auto-external/with-externals/package.json | 6 ++++ .../with-externals/rslib.config.ts | 16 +++++++++ .../auto-external/with-externals/src/index.ts | 5 +++ packages/core/src/config.ts | 5 +-- packages/core/src/utils/external.ts | 28 ++++++++++----- packages/core/tests/external.test.ts | 36 +++++++++++++++---- pnpm-lock.yaml | 6 ++++ 10 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 e2e/cases/auto-external/with-externals/index.test.ts create mode 100644 e2e/cases/auto-external/with-externals/package.json create mode 100644 e2e/cases/auto-external/with-externals/rslib.config.ts create mode 100644 e2e/cases/auto-external/with-externals/src/index.ts diff --git a/e2e/cases/auto-external/default/package.json b/e2e/cases/auto-external/default/package.json index fff959298..7dfa7c46f 100644 --- a/e2e/cases/auto-external/default/package.json +++ b/e2e/cases/auto-external/default/package.json @@ -1,5 +1,5 @@ { - "name": "@e2e/auto-externals-default", + "name": "@e2e/auto-external-default", "dependencies": { "react": "^18.3.1" } diff --git a/e2e/cases/auto-external/false/package.json b/e2e/cases/auto-external/false/package.json index 16b427781..6fe114ccc 100644 --- a/e2e/cases/auto-external/false/package.json +++ b/e2e/cases/auto-external/false/package.json @@ -1,5 +1,5 @@ { - "name": "@e2e/auto-externals-false", + "name": "@e2e/auto-external-false", "dependencies": { "react": "^18.3.1" } diff --git a/e2e/cases/auto-external/with-externals/index.test.ts b/e2e/cases/auto-external/with-externals/index.test.ts new file mode 100644 index 000000000..b39416c31 --- /dev/null +++ b/e2e/cases/auto-external/with-externals/index.test.ts @@ -0,0 +1,15 @@ +import { buildAndGetResults } from '@e2e/helper'; +import { expect, test } from 'vitest'; + +test('auto external false should works', async () => { + const fixturePath = __dirname; + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react1__ from "react1"', + ); + + expect(entries.cjs).toContain( + 'var external_react1_namespaceObject = require("react1");', + ); +}); diff --git a/e2e/cases/auto-external/with-externals/package.json b/e2e/cases/auto-external/with-externals/package.json new file mode 100644 index 000000000..9d79d0669 --- /dev/null +++ b/e2e/cases/auto-external/with-externals/package.json @@ -0,0 +1,6 @@ +{ + "name": "@e2e/auto-external-with-externals", + "dependencies": { + "react": "^18.3.1" + } +} diff --git a/e2e/cases/auto-external/with-externals/rslib.config.ts b/e2e/cases/auto-external/with-externals/rslib.config.ts new file mode 100644 index 000000000..c1c76c586 --- /dev/null +++ b/e2e/cases/auto-external/with-externals/rslib.config.ts @@ -0,0 +1,16 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [generateBundleEsmConfig(__dirname), generateBundleCjsConfig(__dirname)], + output: { + externals: { + react: 'react1', + }, + }, + source: { + entry: { + main: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/auto-external/with-externals/src/index.ts b/e2e/cases/auto-external/with-externals/src/index.ts new file mode 100644 index 000000000..065585aab --- /dev/null +++ b/e2e/cases/auto-external/with-externals/src/index.ts @@ -0,0 +1,5 @@ +import React from 'react'; + +export const foo = () => { + return React.version; +}; diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 492230359..9d3ed02c9 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -21,7 +21,7 @@ import type { Syntax, } from './types'; import { getDefaultExtension } from './utils/extension'; -import { applyAutoExternal } from './utils/external'; +import { composeAutoExternal } from './utils/external'; import { calcLongestCommonPath, color, @@ -412,9 +412,10 @@ async function composeLibRsbuildConfig( config.output?.syntax, config.output?.target, ); - const autoExternalConfig = applyAutoExternal({ + const autoExternalConfig = composeAutoExternal({ autoExternal, pkgJson, + userExternals: rsbuildConfig.output?.externals, }); const entryConfig = await composeEntryConfig( config.source?.entry, diff --git a/packages/core/src/utils/external.ts b/packages/core/src/utils/external.ts index 883766465..1b0d0d5e2 100644 --- a/packages/core/src/utils/external.ts +++ b/packages/core/src/utils/external.ts @@ -3,11 +3,12 @@ import type { PkgJson } from '../types'; import type { AutoExternal } from '../types/config'; import { logger } from './logger'; -export const applyAutoExternal = (options: { +export const composeAutoExternal = (options: { autoExternal: AutoExternal; pkgJson?: PkgJson; + userExternals?: NonNullable['externals']; }): RsbuildConfig => { - const { autoExternal, pkgJson } = options; + const { autoExternal, pkgJson, userExternals } = options; if (!autoExternal) { return {}; @@ -27,14 +28,25 @@ export const applyAutoExternal = (options: { ...(autoExternal === true ? {} : autoExternal), }; + // User externals configuration has higher priority than autoExternal + // eg: autoExternal: ['react'], user: output: { externals: { react: 'react-1' } } + // Only handle the case where the externals type is object, string / string[] does not need to be processed, other types are too complex. + const userExternalKeys = + userExternals && + Object.prototype.toString.call(userExternals) === '[object Object]' + ? Object.keys(userExternals) + : []; + const externals = ( ['dependencies', 'peerDependencies', 'devDependencies'] as const - ).reduce((prev, type) => { - if (externalOptions[type]) { - return pkgJson[type] ? prev.concat(Object.keys(pkgJson[type]!)) : prev; - } - return prev; - }, []); + ) + .reduce((prev, type) => { + if (externalOptions[type]) { + return pkgJson[type] ? prev.concat(Object.keys(pkgJson[type]!)) : prev; + } + return prev; + }, []) + .filter((name) => !userExternalKeys.includes(name)); return externals.length ? { diff --git a/packages/core/tests/external.test.ts b/packages/core/tests/external.test.ts index a09d31397..3b65fe7bb 100644 --- a/packages/core/tests/external.test.ts +++ b/packages/core/tests/external.test.ts @@ -1,15 +1,16 @@ import { describe, expect, it, vi } from 'vitest'; -import { applyAutoExternal } from '../src/utils/external'; +import { composeAutoExternal } from '../src/utils/external'; vi.mock('rslog'); -describe('should applyAutoExternal correctly', () => { +describe('should composeAutoExternal correctly', () => { it('autoExternal is true', () => { - const result = applyAutoExternal({ + const result = composeAutoExternal({ autoExternal: true, pkgJson: { dependencies: { foo: '1.0.0', + foo1: '1.0.0', }, devDependencies: { bar: '1.0.0', @@ -22,13 +23,13 @@ describe('should applyAutoExternal correctly', () => { expect(result).toEqual({ output: { - externals: ['foo', 'baz'], + externals: ['foo', 'foo1', 'baz'], }, }); }); it('autoExternal is object', () => { - const result = applyAutoExternal({ + const result = composeAutoExternal({ autoExternal: { peerDependencies: false, devDependencies: true, @@ -54,7 +55,7 @@ describe('should applyAutoExternal correctly', () => { }); it('autoExternal is false', () => { - const result = applyAutoExternal({ + const result = composeAutoExternal({ autoExternal: false, pkgJson: { dependencies: { @@ -66,8 +67,29 @@ describe('should applyAutoExternal correctly', () => { expect(result).toEqual({}); }); + it('autoExternal with user externals object', () => { + const result = composeAutoExternal({ + autoExternal: true, + pkgJson: { + dependencies: { + foo: '1.0.0', + bar: '1.0.0', + }, + }, + userExternals: { + foo: 'foo-1', + }, + }); + + expect(result).toEqual({ + output: { + externals: ['bar'], + }, + }); + }); + it('read package.json failed', () => { - const result = applyAutoExternal({ + const result = composeAutoExternal({ autoExternal: true, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d33259e3e..fe4d20c29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,12 @@ importers: specifier: ^18.3.1 version: 18.3.1 + e2e/cases/auto-external/with-externals: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + e2e/cases/autoExtension/type-commonjs: {} e2e/cases/autoExtension/type-module: {} From 4894093fee68bb693ae775ee062ce40a701c9f11 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 17:22:35 +0800 Subject: [PATCH 05/10] fix: reuse test file --- e2e/cases/auto-external/default/index.test.ts | 15 ------- .../auto-external/default/rslib.config.ts | 2 +- e2e/cases/auto-external/false/index.test.ts | 15 ------- e2e/cases/auto-external/false/rslib.config.ts | 2 +- e2e/cases/auto-external/false/src/index.ts | 5 --- .../{default => fixtures}/src/index.ts | 0 e2e/cases/auto-external/index.test.ts | 42 +++++++++++++++++++ .../with-externals/index.test.ts | 15 ------- .../with-externals/rslib.config.ts | 2 +- packages/core/src/config.ts | 4 +- packages/core/src/utils/external.ts | 2 +- packages/core/tests/external.test.ts | 14 +++---- .../extension/type-commonjs/package.json | 3 -- .../extension/type-module/package.json | 3 -- 14 files changed, 55 insertions(+), 69 deletions(-) delete mode 100644 e2e/cases/auto-external/default/index.test.ts delete mode 100644 e2e/cases/auto-external/false/index.test.ts delete mode 100644 e2e/cases/auto-external/false/src/index.ts rename e2e/cases/auto-external/{default => fixtures}/src/index.ts (100%) create mode 100644 e2e/cases/auto-external/index.test.ts delete mode 100644 e2e/cases/auto-external/with-externals/index.test.ts delete mode 100644 packages/core/tests/fixtures/extension/type-commonjs/package.json delete mode 100644 packages/core/tests/fixtures/extension/type-module/package.json diff --git a/e2e/cases/auto-external/default/index.test.ts b/e2e/cases/auto-external/default/index.test.ts deleted file mode 100644 index ed41df172..000000000 --- a/e2e/cases/auto-external/default/index.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { buildAndGetResults } from '@e2e/helper'; -import { expect, test } from 'vitest'; - -test('auto external should works', async () => { - const fixturePath = __dirname; - const { entries } = await buildAndGetResults(fixturePath); - - expect(entries.esm).toContain( - 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', - ); - - expect(entries.cjs).toContain( - 'var external_react_namespaceObject = require("react");', - ); -}); diff --git a/e2e/cases/auto-external/default/rslib.config.ts b/e2e/cases/auto-external/default/rslib.config.ts index 03252f356..6f1252ecf 100644 --- a/e2e/cases/auto-external/default/rslib.config.ts +++ b/e2e/cases/auto-external/default/rslib.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ lib: [generateBundleEsmConfig(__dirname), generateBundleCjsConfig(__dirname)], source: { entry: { - main: './src/index.ts', + main: '../fixtures/src/index.ts', }, }, }); diff --git a/e2e/cases/auto-external/false/index.test.ts b/e2e/cases/auto-external/false/index.test.ts deleted file mode 100644 index 8a7f2b581..000000000 --- a/e2e/cases/auto-external/false/index.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { buildAndGetResults } from '@e2e/helper'; -import { expect, test } from 'vitest'; - -test('auto external false should works', async () => { - const fixturePath = __dirname; - const { entries } = await buildAndGetResults(fixturePath); - - expect(entries.esm).not.toContain( - 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', - ); - - expect(entries.cjs).not.toContain( - 'var external_react_namespaceObject = require("react");', - ); -}); diff --git a/e2e/cases/auto-external/false/rslib.config.ts b/e2e/cases/auto-external/false/rslib.config.ts index f5d3b7db3..3a82365bd 100644 --- a/e2e/cases/auto-external/false/rslib.config.ts +++ b/e2e/cases/auto-external/false/rslib.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ ], source: { entry: { - main: './src/index.ts', + main: '../fixtures/src/index.ts', }, }, }); diff --git a/e2e/cases/auto-external/false/src/index.ts b/e2e/cases/auto-external/false/src/index.ts deleted file mode 100644 index 065585aab..000000000 --- a/e2e/cases/auto-external/false/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -export const foo = () => { - return React.version; -}; diff --git a/e2e/cases/auto-external/default/src/index.ts b/e2e/cases/auto-external/fixtures/src/index.ts similarity index 100% rename from e2e/cases/auto-external/default/src/index.ts rename to e2e/cases/auto-external/fixtures/src/index.ts diff --git a/e2e/cases/auto-external/index.test.ts b/e2e/cases/auto-external/index.test.ts new file mode 100644 index 000000000..223a93009 --- /dev/null +++ b/e2e/cases/auto-external/index.test.ts @@ -0,0 +1,42 @@ +import { join } from 'node:path'; +import { buildAndGetResults } from '@e2e/helper'; +import { expect, test } from 'vitest'; + +test('auto external default should works', async () => { + const fixturePath = join(__dirname, 'default'); + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', + ); + + expect(entries.cjs).toContain( + 'var external_react_namespaceObject = require("react");', + ); +}); + +test('auto external false should works', async () => { + const fixturePath = join(__dirname, 'false'); + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).not.toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', + ); + + expect(entries.cjs).not.toContain( + 'var external_react_namespaceObject = require("react");', + ); +}); + +test('externals should overrides auto external', async () => { + const fixturePath = join(__dirname, 'with-externals'); + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react1__ from "react1"', + ); + + expect(entries.cjs).toContain( + 'var external_react1_namespaceObject = require("react1");', + ); +}); diff --git a/e2e/cases/auto-external/with-externals/index.test.ts b/e2e/cases/auto-external/with-externals/index.test.ts deleted file mode 100644 index b39416c31..000000000 --- a/e2e/cases/auto-external/with-externals/index.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { buildAndGetResults } from '@e2e/helper'; -import { expect, test } from 'vitest'; - -test('auto external false should works', async () => { - const fixturePath = __dirname; - const { entries } = await buildAndGetResults(fixturePath); - - expect(entries.esm).toContain( - 'import * as __WEBPACK_EXTERNAL_MODULE_react1__ from "react1"', - ); - - expect(entries.cjs).toContain( - 'var external_react1_namespaceObject = require("react1");', - ); -}); diff --git a/e2e/cases/auto-external/with-externals/rslib.config.ts b/e2e/cases/auto-external/with-externals/rslib.config.ts index c1c76c586..96d469e63 100644 --- a/e2e/cases/auto-external/with-externals/rslib.config.ts +++ b/e2e/cases/auto-external/with-externals/rslib.config.ts @@ -10,7 +10,7 @@ export default defineConfig({ }, source: { entry: { - main: './src/index.ts', + main: '../fixtures/src/index.ts', }, }, }); diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 9d3ed02c9..528fbce5c 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -21,7 +21,7 @@ import type { Syntax, } from './types'; import { getDefaultExtension } from './utils/extension'; -import { composeAutoExternal } from './utils/external'; +import { composeAutoExternalConfig } from './utils/external'; import { calcLongestCommonPath, color, @@ -412,7 +412,7 @@ async function composeLibRsbuildConfig( config.output?.syntax, config.output?.target, ); - const autoExternalConfig = composeAutoExternal({ + const autoExternalConfig = composeAutoExternalConfig({ autoExternal, pkgJson, userExternals: rsbuildConfig.output?.externals, diff --git a/packages/core/src/utils/external.ts b/packages/core/src/utils/external.ts index 1b0d0d5e2..c066fbb08 100644 --- a/packages/core/src/utils/external.ts +++ b/packages/core/src/utils/external.ts @@ -3,7 +3,7 @@ import type { PkgJson } from '../types'; import type { AutoExternal } from '../types/config'; import { logger } from './logger'; -export const composeAutoExternal = (options: { +export const composeAutoExternalConfig = (options: { autoExternal: AutoExternal; pkgJson?: PkgJson; userExternals?: NonNullable['externals']; diff --git a/packages/core/tests/external.test.ts b/packages/core/tests/external.test.ts index 3b65fe7bb..6e194d33b 100644 --- a/packages/core/tests/external.test.ts +++ b/packages/core/tests/external.test.ts @@ -1,11 +1,11 @@ import { describe, expect, it, vi } from 'vitest'; -import { composeAutoExternal } from '../src/utils/external'; +import { composeAutoExternalConfig } from '../src/utils/external'; vi.mock('rslog'); -describe('should composeAutoExternal correctly', () => { +describe('should composeAutoExternalConfig correctly', () => { it('autoExternal is true', () => { - const result = composeAutoExternal({ + const result = composeAutoExternalConfig({ autoExternal: true, pkgJson: { dependencies: { @@ -29,7 +29,7 @@ describe('should composeAutoExternal correctly', () => { }); it('autoExternal is object', () => { - const result = composeAutoExternal({ + const result = composeAutoExternalConfig({ autoExternal: { peerDependencies: false, devDependencies: true, @@ -55,7 +55,7 @@ describe('should composeAutoExternal correctly', () => { }); it('autoExternal is false', () => { - const result = composeAutoExternal({ + const result = composeAutoExternalConfig({ autoExternal: false, pkgJson: { dependencies: { @@ -68,7 +68,7 @@ describe('should composeAutoExternal correctly', () => { }); it('autoExternal with user externals object', () => { - const result = composeAutoExternal({ + const result = composeAutoExternalConfig({ autoExternal: true, pkgJson: { dependencies: { @@ -89,7 +89,7 @@ describe('should composeAutoExternal correctly', () => { }); it('read package.json failed', () => { - const result = composeAutoExternal({ + const result = composeAutoExternalConfig({ autoExternal: true, }); diff --git a/packages/core/tests/fixtures/extension/type-commonjs/package.json b/packages/core/tests/fixtures/extension/type-commonjs/package.json deleted file mode 100644 index 5bbefffba..000000000 --- a/packages/core/tests/fixtures/extension/type-commonjs/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "commonjs" -} diff --git a/packages/core/tests/fixtures/extension/type-module/package.json b/packages/core/tests/fixtures/extension/type-module/package.json deleted file mode 100644 index 3dbc1ca59..000000000 --- a/packages/core/tests/fixtures/extension/type-module/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} From 6babfee20e03c3ba62534facab93525ce5f7566d Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 17:26:37 +0800 Subject: [PATCH 06/10] fix: update --- e2e/cases/auto-external/with-externals/src/index.ts | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 e2e/cases/auto-external/with-externals/src/index.ts diff --git a/e2e/cases/auto-external/with-externals/src/index.ts b/e2e/cases/auto-external/with-externals/src/index.ts deleted file mode 100644 index 065585aab..000000000 --- a/e2e/cases/auto-external/with-externals/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -export const foo = () => { - return React.version; -}; From 6fce2ed26e8eb03ea53b811e4f3dea4b7dafd9dd Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 8 Aug 2024 19:23:43 +0800 Subject: [PATCH 07/10] chore: dedup & merge composeAutoExternalConfig to config.ts --- packages/core/src/config.ts | 56 ++++++++++++++++++++++++++- packages/core/src/utils/external.ts | 58 ---------------------------- packages/core/tests/external.test.ts | 28 +++++++++++++- 3 files changed, 82 insertions(+), 60 deletions(-) delete mode 100644 packages/core/src/utils/external.ts diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 528fbce5c..69062d73a 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -11,6 +11,7 @@ import { import glob from 'fast-glob'; import { DEFAULT_CONFIG_NAME, DEFAULT_EXTENSIONS } from './constant'; import type { + AutoExternal, Format, LibConfig, PkgJson, @@ -21,7 +22,6 @@ import type { Syntax, } from './types'; import { getDefaultExtension } from './utils/extension'; -import { composeAutoExternalConfig } from './utils/external'; import { calcLongestCommonPath, color, @@ -82,6 +82,60 @@ export async function loadConfig( return content as RslibConfig; } +export const composeAutoExternalConfig = (options: { + autoExternal: AutoExternal; + pkgJson?: PkgJson; + userExternals?: NonNullable['externals']; +}): RsbuildConfig => { + const { autoExternal, pkgJson, userExternals } = options; + + if (!autoExternal) { + return {}; + } + + if (!pkgJson) { + logger.warn( + 'autoExternal configuration will not be applied due to read package.json failed', + ); + return {}; + } + + const externalOptions = { + dependencies: true, + peerDependencies: true, + devDependencies: false, + ...(autoExternal === true ? {} : autoExternal), + }; + + // User externals configuration has higher priority than autoExternal + // eg: autoExternal: ['react'], user: output: { externals: { react: 'react-1' } } + // Only handle the case where the externals type is object, string / string[] does not need to be processed, other types are too complex. + const userExternalKeys = + userExternals && + Object.prototype.toString.call(userExternals) === '[object Object]' + ? Object.keys(userExternals) + : []; + + const externals = ( + ['dependencies', 'peerDependencies', 'devDependencies'] as const + ) + .reduce((prev, type) => { + if (externalOptions[type]) { + return pkgJson[type] ? prev.concat(Object.keys(pkgJson[type]!)) : prev; + } + return prev; + }, []) + .filter((name) => !userExternalKeys.includes(name)); + + return externals.length + ? { + output: { + externals: Array.from(new Set(externals)), + }, + } + : {}; +}; + export async function createInternalRsbuildConfig(): Promise { return defineRsbuildConfig({ dev: { diff --git a/packages/core/src/utils/external.ts b/packages/core/src/utils/external.ts deleted file mode 100644 index c066fbb08..000000000 --- a/packages/core/src/utils/external.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { RsbuildConfig } from '@rsbuild/core'; -import type { PkgJson } from '../types'; -import type { AutoExternal } from '../types/config'; -import { logger } from './logger'; - -export const composeAutoExternalConfig = (options: { - autoExternal: AutoExternal; - pkgJson?: PkgJson; - userExternals?: NonNullable['externals']; -}): RsbuildConfig => { - const { autoExternal, pkgJson, userExternals } = options; - - if (!autoExternal) { - return {}; - } - - if (!pkgJson) { - logger.warn( - 'autoExternal configuration will not be applied due to read package.json failed', - ); - return {}; - } - - const externalOptions = { - dependencies: true, - peerDependencies: true, - devDependencies: false, - ...(autoExternal === true ? {} : autoExternal), - }; - - // User externals configuration has higher priority than autoExternal - // eg: autoExternal: ['react'], user: output: { externals: { react: 'react-1' } } - // Only handle the case where the externals type is object, string / string[] does not need to be processed, other types are too complex. - const userExternalKeys = - userExternals && - Object.prototype.toString.call(userExternals) === '[object Object]' - ? Object.keys(userExternals) - : []; - - const externals = ( - ['dependencies', 'peerDependencies', 'devDependencies'] as const - ) - .reduce((prev, type) => { - if (externalOptions[type]) { - return pkgJson[type] ? prev.concat(Object.keys(pkgJson[type]!)) : prev; - } - return prev; - }, []) - .filter((name) => !userExternalKeys.includes(name)); - - return externals.length - ? { - output: { - externals, - }, - } - : {}; -}; diff --git a/packages/core/tests/external.test.ts b/packages/core/tests/external.test.ts index 6e194d33b..95ab8288a 100644 --- a/packages/core/tests/external.test.ts +++ b/packages/core/tests/external.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest'; -import { composeAutoExternalConfig } from '../src/utils/external'; +import { composeAutoExternalConfig } from '../src/config'; vi.mock('rslog'); @@ -28,6 +28,32 @@ describe('should composeAutoExternalConfig correctly', () => { }); }); + it('autoExternal will deduplication ', () => { + const result = composeAutoExternalConfig({ + autoExternal: true, + pkgJson: { + dependencies: { + foo: '1.0.0', + foo1: '1.0.0', + }, + devDependencies: { + bar: '1.0.0', + }, + peerDependencies: { + baz: '1.0.0', + foo: '1.0.0', + foo1: '1.0.0', + }, + }, + }); + + expect(result).toEqual({ + output: { + externals: ['foo', 'foo1', 'baz'], + }, + }); + }); + it('autoExternal is object', () => { const result = composeAutoExternalConfig({ autoExternal: { From 3f24d59729cb1d5e935e6fa6c0955254498e1515 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Fri, 9 Aug 2024 11:03:25 +0800 Subject: [PATCH 08/10] chore: add isObject util --- packages/core/src/config.ts | 6 ++---- packages/core/src/utils/helper.ts | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 69062d73a..4c5a150f3 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -25,6 +25,7 @@ import { getDefaultExtension } from './utils/extension'; import { calcLongestCommonPath, color, + isObject, nodeBuiltInModules, readPackageJson, } from './utils/helper'; @@ -111,10 +112,7 @@ export const composeAutoExternalConfig = (options: { // eg: autoExternal: ['react'], user: output: { externals: { react: 'react-1' } } // Only handle the case where the externals type is object, string / string[] does not need to be processed, other types are too complex. const userExternalKeys = - userExternals && - Object.prototype.toString.call(userExternals) === '[object Object]' - ? Object.keys(userExternals) - : []; + userExternals && isObject(userExternals) ? Object.keys(userExternals) : []; const externals = ( ['dependencies', 'peerDependencies', 'devDependencies'] as const diff --git a/packages/core/src/utils/helper.ts b/packages/core/src/utils/helper.ts index be18d67fc..ca36e081b 100644 --- a/packages/core/src/utils/helper.ts +++ b/packages/core/src/utils/helper.ts @@ -118,4 +118,7 @@ export const readPackageJson = (rootPath: string): undefined | PkgJson => { } }; +export const isObject = (obj: unknown): obj is Record => + Object.prototype.toString.call(obj) === '[object Object]'; + export { color, calcLongestCommonPath }; From 9548448239308dc62dab2212e8c831676cc7a1f4 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Fri, 9 Aug 2024 12:25:30 +0800 Subject: [PATCH 09/10] feat: support external sub path --- .../external-sub-path/package.json | 6 +++++ .../external-sub-path/rslib.config.ts | 11 ++++++++++ .../external-sub-path/src/index.ts | 6 +++++ e2e/cases/auto-external/index.test.ts | 19 ++++++++++++++++ examples/react-component/rslib.config.ts | 6 ----- packages/core/src/config.ts | 8 ++++++- packages/core/tests/external.test.ts | 22 +++++++++++++++---- pnpm-lock.yaml | 6 +++++ 8 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 e2e/cases/auto-external/external-sub-path/package.json create mode 100644 e2e/cases/auto-external/external-sub-path/rslib.config.ts create mode 100644 e2e/cases/auto-external/external-sub-path/src/index.ts diff --git a/e2e/cases/auto-external/external-sub-path/package.json b/e2e/cases/auto-external/external-sub-path/package.json new file mode 100644 index 000000000..5c98adea0 --- /dev/null +++ b/e2e/cases/auto-external/external-sub-path/package.json @@ -0,0 +1,6 @@ +{ + "name": "@e2e/auto-external-with-sub-path", + "dependencies": { + "react": "^18.3.1" + } +} diff --git a/e2e/cases/auto-external/external-sub-path/rslib.config.ts b/e2e/cases/auto-external/external-sub-path/rslib.config.ts new file mode 100644 index 000000000..03252f356 --- /dev/null +++ b/e2e/cases/auto-external/external-sub-path/rslib.config.ts @@ -0,0 +1,11 @@ +import { generateBundleCjsConfig, generateBundleEsmConfig } from '@e2e/helper'; +import { defineConfig } from '@rslib/core'; + +export default defineConfig({ + lib: [generateBundleEsmConfig(__dirname), generateBundleCjsConfig(__dirname)], + source: { + entry: { + main: './src/index.ts', + }, + }, +}); diff --git a/e2e/cases/auto-external/external-sub-path/src/index.ts b/e2e/cases/auto-external/external-sub-path/src/index.ts new file mode 100644 index 000000000..25bd88687 --- /dev/null +++ b/e2e/cases/auto-external/external-sub-path/src/index.ts @@ -0,0 +1,6 @@ +import React from 'react'; +import ReactJsx from 'react/jsx-runtime'; + +export const foo = () => { + return [React.version, ReactJsx.jsx]; +}; diff --git a/e2e/cases/auto-external/index.test.ts b/e2e/cases/auto-external/index.test.ts index 223a93009..c47715f00 100644 --- a/e2e/cases/auto-external/index.test.ts +++ b/e2e/cases/auto-external/index.test.ts @@ -15,6 +15,25 @@ test('auto external default should works', async () => { ); }); +test('auto external sub path should works', async () => { + const fixturePath = join(__dirname, 'external-sub-path'); + const { entries } = await buildAndGetResults(fixturePath); + + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"', + ); + expect(entries.esm).toContain( + 'import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__ from "react/jsx-runtime"', + ); + + expect(entries.cjs).toContain( + 'var external_react_namespaceObject = require("react");', + ); + expect(entries.cjs).toContain( + 'var jsx_runtime_namespaceObject = require("react/jsx-runtime");', + ); +}); + test('auto external false should works', async () => { const fixturePath = join(__dirname, 'false'); const { entries } = await buildAndGetResults(fixturePath); diff --git a/examples/react-component/rslib.config.ts b/examples/react-component/rslib.config.ts index d97011009..561d3c6e3 100644 --- a/examples/react-component/rslib.config.ts +++ b/examples/react-component/rslib.config.ts @@ -33,11 +33,5 @@ export default defineConfig({ main: './src/index.tsx', }, }, - output: { - externals: { - react: 'react', - 'react/jsx-runtime': 'react/jsx-runtime', - }, - }, plugins: [pluginReact()], }); diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 4c5a150f3..98fa4e3a1 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -125,10 +125,16 @@ export const composeAutoExternalConfig = (options: { }, []) .filter((name) => !userExternalKeys.includes(name)); + const uniqueExternals = Array.from(new Set(externals)); + return externals.length ? { output: { - externals: Array.from(new Set(externals)), + externals: [ + // Exclude dependencies, e.g. `react`, `react/jsx-runtime` + ...uniqueExternals.map((dep) => new RegExp(`^${dep}($|\\/|\\\\)`)), + ...uniqueExternals, + ], }, } : {}; diff --git a/packages/core/tests/external.test.ts b/packages/core/tests/external.test.ts index 95ab8288a..343b35d71 100644 --- a/packages/core/tests/external.test.ts +++ b/packages/core/tests/external.test.ts @@ -23,7 +23,14 @@ describe('should composeAutoExternalConfig correctly', () => { expect(result).toEqual({ output: { - externals: ['foo', 'foo1', 'baz'], + externals: [ + /^foo($|\/|\\)/, + /^foo1($|\/|\\)/, + /^baz($|\/|\\)/, + 'foo', + 'foo1', + 'baz', + ], }, }); }); @@ -49,7 +56,14 @@ describe('should composeAutoExternalConfig correctly', () => { expect(result).toEqual({ output: { - externals: ['foo', 'foo1', 'baz'], + externals: [ + /^foo($|\/|\\)/, + /^foo1($|\/|\\)/, + /^baz($|\/|\\)/, + 'foo', + 'foo1', + 'baz', + ], }, }); }); @@ -75,7 +89,7 @@ describe('should composeAutoExternalConfig correctly', () => { expect(result).toEqual({ output: { - externals: ['foo', 'bar'], + externals: [/^foo($|\/|\\)/, /^bar($|\/|\\)/, 'foo', 'bar'], }, }); }); @@ -109,7 +123,7 @@ describe('should composeAutoExternalConfig correctly', () => { expect(result).toEqual({ output: { - externals: ['bar'], + externals: [/^bar($|\/|\\)/, 'bar'], }, }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe4d20c29..aea969d95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,6 +100,12 @@ importers: specifier: ^18.3.1 version: 18.3.1 + e2e/cases/auto-external/external-sub-path: + dependencies: + react: + specifier: ^18.3.1 + version: 18.3.1 + e2e/cases/auto-external/false: dependencies: react: From a33e26ea6702ca4025969c5678dd586509d80959 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Fri, 9 Aug 2024 12:29:30 +0800 Subject: [PATCH 10/10] fix: example --- examples/express-plugin/rslib.config.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/express-plugin/rslib.config.ts b/examples/express-plugin/rslib.config.ts index f4d96ea59..e71c9b75c 100644 --- a/examples/express-plugin/rslib.config.ts +++ b/examples/express-plugin/rslib.config.ts @@ -33,9 +33,6 @@ export default defineConfig({ }, }, output: { - externals: { - express: 'express', - }, target: 'node', }, });