diff --git a/package.json b/package.json index 8bc7aa7..58afd9e 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "dependencies": { "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.2", + "@rollup/plugin-dynamic-import-vars": "^2.1.5", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 458244f..3677ab2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@rollup/plugin-commonjs': specifier: ^28.0.2 version: 28.0.2(rollup@4.29.1) + '@rollup/plugin-dynamic-import-vars': + specifier: ^2.1.5 + version: 2.1.5(rollup@4.29.1) '@rollup/plugin-inject': specifier: ^5.0.5 version: 5.0.5(rollup@4.29.1) @@ -530,6 +533,15 @@ packages: rollup: optional: true + '@rollup/plugin-dynamic-import-vars@2.1.5': + resolution: {integrity: sha512-Mymi24fd9hlRifdZV/jYIFj1dn99F34imiYu3KzlAcgBcRi3i9SucgW/VRo5SQ9K4NuQ7dCep6pFWgNyhRdFHQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/plugin-inject@5.0.5': resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} @@ -879,6 +891,10 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -3159,6 +3175,16 @@ snapshots: optionalDependencies: rollup: 4.29.1 + '@rollup/plugin-dynamic-import-vars@2.1.5(rollup@4.29.1)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.29.1) + astring: 1.9.0 + estree-walker: 2.0.2 + fast-glob: 3.3.2 + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.29.1 + '@rollup/plugin-inject@5.0.5(rollup@4.29.1)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.29.1) @@ -3532,6 +3558,8 @@ snapshots: get-intrinsic: 1.2.6 is-array-buffer: 3.0.5 + astring@1.9.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 diff --git a/src/utils/get-rollup-configs.ts b/src/utils/get-rollup-configs.ts index ac0f9cc..c45c7c9 100644 --- a/src/utils/get-rollup-configs.ts +++ b/src/utils/get-rollup-configs.ts @@ -7,6 +7,7 @@ import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import alias from '@rollup/plugin-alias'; import replace from '@rollup/plugin-replace'; +import dynamicImportVars from '@rollup/plugin-dynamic-import-vars'; import type { PackageJson } from 'type-fest'; import type { TsConfigResult } from 'get-tsconfig'; import type { ExportEntry, AliasMap } from '../types.js'; @@ -137,6 +138,7 @@ const getConfig = { json(), esbuildTransform(esbuildConfig), createRequire(), + dynamicImportVars(), ...( options.minify ? [esbuildMinify(esbuildConfig)] diff --git a/tests/fixtures.ts b/tests/fixtures.ts index b927de3..cef610a 100644 --- a/tests/fixtures.ts +++ b/tests/fixtures.ts @@ -234,3 +234,26 @@ export const fixtureDependencyImportsMap: FileTree = { }), }, }; + +export const fixtureDynamicImports: FileTree = { + 'package.json': createPackageJson({ + main: './dist/dynamic-imports.js', + }), + src: { + 'dynamic-imports.js': outdent` + const files = [ + 'aaa', + 'bbb', + 'ccc', + ]; + const randomFile = files[Math.floor(Math.random() * files.length)]; + import(\`./files/\${randomFile}.js\`) + `, + + files: { + 'aaa.js': 'console.log(111)', + 'bbb.js': 'console.log(222)', + 'ccc.js': 'console.log(333)', + }, + }, +}; diff --git a/tests/specs/builds/output-commonjs.ts b/tests/specs/builds/output-commonjs.ts index 623ac4e..b72954f 100644 --- a/tests/specs/builds/output-commonjs.ts +++ b/tests/specs/builds/output-commonjs.ts @@ -1,7 +1,10 @@ +import fs from 'node:fs/promises'; import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; import { pkgroll } from '../../utils.js'; -import { packageFixture, createPackageJson, createTsconfigJson } from '../../fixtures.js'; +import { + packageFixture, createPackageJson, createTsconfigJson, fixtureDynamicImports, +} from '../../fixtures.js'; export default testSuite(({ describe }, nodePath: string) => { describe('output: commonjs', ({ test }) => { @@ -175,5 +178,31 @@ export default testSuite(({ describe }, nodePath: string) => { const content = await fixture.readFile('dist/nested/index.js', 'utf8'); expect(content).toMatch('nested entry point'); }); + + test('dynamic imports', async () => { + await using fixture = await createFixture({ + ...fixtureDynamicImports, + 'package.json': createPackageJson({ + exports: './dist/dynamic-imports.cjs', + }), + }); + + const pkgrollProcess = await pkgroll([], { + cwd: fixture.path, + nodePath, + }); + + expect(pkgrollProcess.exitCode).toBe(0); + expect(pkgrollProcess.stderr).toBe(''); + + const content = await fixture.readFile('dist/dynamic-imports.cjs', 'utf8'); + expect(content).toMatch('require('); + + const files = await fs.readdir(fixture.getPath('dist')); + files.sort(); + expect(files[0]).toMatch(/^aaa-/); + expect(files[1]).toMatch(/^bbb-/); + expect(files[2]).toMatch(/^ccc-/); + }); }); }); diff --git a/tests/specs/builds/output-module.ts b/tests/specs/builds/output-module.ts index d6b85ee..428b4a1 100644 --- a/tests/specs/builds/output-module.ts +++ b/tests/specs/builds/output-module.ts @@ -1,7 +1,10 @@ +import fs from 'node:fs/promises'; import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; import { pkgroll } from '../../utils.js'; -import { packageFixture, createPackageJson, createTsconfigJson } from '../../fixtures.js'; +import { + packageFixture, createPackageJson, createTsconfigJson, fixtureDynamicImports, +} from '../../fixtures.js'; export default testSuite(({ describe }, nodePath: string) => { describe('output: module', ({ test }) => { @@ -243,5 +246,31 @@ export default testSuite(({ describe }, nodePath: string) => { const [, createRequireMangledVariable] = content.toString().match(/createRequire as (\w+)/)!; expect(content).not.toMatch(`${createRequireMangledVariable}(`); }); + + test('dynamic imports', async () => { + await using fixture = await createFixture({ + ...fixtureDynamicImports, + 'package.json': createPackageJson({ + exports: './dist/dynamic-imports.mjs', + }), + }); + + const pkgrollProcess = await pkgroll([], { + cwd: fixture.path, + nodePath, + }); + + expect(pkgrollProcess.exitCode).toBe(0); + expect(pkgrollProcess.stderr).toBe(''); + + const content = await fixture.readFile('dist/dynamic-imports.mjs', 'utf8'); + expect(content).toMatch('import('); + + const files = await fs.readdir(fixture.getPath('dist')); + files.sort(); + expect(files[0]).toMatch(/^aaa-/); + expect(files[1]).toMatch(/^bbb-/); + expect(files[2]).toMatch(/^ccc-/); + }); }); });