diff --git a/tests/__snapshots__/esbuild.test.ts.snap b/tests/__snapshots__/esbuild.test.ts.snap index 56aecb4..94e6f8b 100644 --- a/tests/__snapshots__/esbuild.test.ts.snap +++ b/tests/__snapshots__/esbuild.test.ts.snap @@ -3,12 +3,12 @@ exports[`esbuild > generate mode 1`] = ` [ "// -// tests/fixtures/component.tsx +// tests/fixtures/basic/component.tsx function Component() { return /* @__PURE__ */ React.createElement("div", null, "I'm a div in a tsx component!"); } -// tests/fixtures/main.ts +// tests/fixtures/basic/main.ts function hello(s) { return "hello" + s; } diff --git a/tests/__snapshots__/rolldown.test.ts.snap b/tests/__snapshots__/rolldown.test.ts.snap index 54c322d..a2eaffc 100644 --- a/tests/__snapshots__/rolldown.test.ts.snap +++ b/tests/__snapshots__/rolldown.test.ts.snap @@ -5,13 +5,13 @@ exports[`rolldown 1`] = ` "// main.js import { jsx as _jsx } from "react/jsx-runtime"; -//#region tests/fixtures/component.tsx +//#region tests/fixtures/basic/component.tsx function Component() { return _jsx("div", { children: "I'm a div in a tsx component!" }); } //#endregion -//#region tests/fixtures/main.ts +//#region tests/fixtures/basic/main.ts function hello(s) { return "hello" + s; } diff --git a/tests/__snapshots__/rollup.test.ts.snap b/tests/__snapshots__/rollup.test.ts.snap index 6e6193c..6bc5f1d 100644 --- a/tests/__snapshots__/rollup.test.ts.snap +++ b/tests/__snapshots__/rollup.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`rollup 1`] = ` +exports[`rollup > generate basic 1`] = ` [ "// main.js function Component() { @@ -33,3 +33,56 @@ export declare function Component(): React.JSX.Element; ", ] `; + +exports[`rollup > write entry-points 1`] = ` +[ + "// b/index.d.ts +export { ComponentB } from "./ComponentB/ComponentB"; +", + "// b/index.js +export { ComponentB } from './ComponentB/ComponentB/index.js'; +", + "// b/ComponentB/ComponentB/index.d.ts +import React from "react"; +interface ComponentBProps { + test: string; +} +export declare function ComponentB(props: ComponentBProps): React.JSX.Element; +export {}; +", + "// b/ComponentB/ComponentB/index.js +import React from 'react'; + +function ComponentB(props) { + const { test } = props; + return /* @__PURE__ */ React.createElement(React.Fragment, null, "ComponentB: ", test); +} + +export { ComponentB }; +", + "// a/index.d.ts +export { ComponentA } from "./ComponentA/ComponentA"; +", + "// a/index.js +export { ComponentA } from './ComponentA/ComponentA/index.js'; +", + "// a/ComponentA/ComponentA/index.d.ts +import React from "react"; +interface ComponentAProps { + test: string; +} +export declare function ComponentA(props: ComponentAProps): React.JSX.Element; +export {}; +", + "// a/ComponentA/ComponentA/index.js +import React from 'react'; + +function ComponentA(props) { + const { test } = props; + return /* @__PURE__ */ React.createElement(React.Fragment, null, "ComponentA: ", test); +} + +export { ComponentA }; +", +] +`; diff --git a/tests/esbuild.test.ts b/tests/esbuild.test.ts index 924992e..9701b4c 100644 --- a/tests/esbuild.test.ts +++ b/tests/esbuild.test.ts @@ -6,13 +6,13 @@ import { dependencies } from '../package.json' import UnpluginIsolatedDecl from '../src/esbuild' describe('esbuild', () => { - const input = path.resolve(__dirname, 'fixtures/main.ts') + const input = path.resolve(__dirname, 'fixtures/basic/main.ts') test('write mode', async () => { - const dist = path.resolve(__dirname, 'temp') + const dist = path.resolve(__dirname, 'temp/esbuild/basic') await build({ entryPoints: [input], - plugins: [UnpluginIsolatedDecl({ extraOutdir: 'temp' })], + plugins: [UnpluginIsolatedDecl({ extraOutdir: 'extraOutdir' })], logLevel: 'silent', bundle: true, external: Object.keys(dependencies), @@ -21,7 +21,7 @@ describe('esbuild', () => { format: 'esm', }) - const outDir = path.resolve(dist, 'temp') + const outDir = path.resolve(dist, 'extraOutdir') await expect( Promise.all( (await readdir(outDir)) diff --git a/tests/fixtures/component.tsx b/tests/fixtures/basic/component.tsx similarity index 100% rename from tests/fixtures/component.tsx rename to tests/fixtures/basic/component.tsx diff --git a/tests/fixtures/main.ts b/tests/fixtures/basic/main.ts similarity index 100% rename from tests/fixtures/main.ts rename to tests/fixtures/basic/main.ts diff --git a/tests/fixtures/types.ts b/tests/fixtures/basic/types.ts similarity index 100% rename from tests/fixtures/types.ts rename to tests/fixtures/basic/types.ts diff --git a/tests/fixtures/types2.ts b/tests/fixtures/basic/types2.ts similarity index 100% rename from tests/fixtures/types2.ts rename to tests/fixtures/basic/types2.ts diff --git a/tests/fixtures/entry-points/a/ComponentA/ComponentA.tsx b/tests/fixtures/entry-points/a/ComponentA/ComponentA.tsx new file mode 100644 index 0000000..8785e34 --- /dev/null +++ b/tests/fixtures/entry-points/a/ComponentA/ComponentA.tsx @@ -0,0 +1,10 @@ +import React from "react"; + +interface ComponentAProps { + test: string; +} + +export function ComponentA(props: ComponentAProps): React.JSX.Element { + const { test } = props; + return <>ComponentA: {test}; +} diff --git a/tests/fixtures/entry-points/a/index.ts b/tests/fixtures/entry-points/a/index.ts new file mode 100644 index 0000000..649a88c --- /dev/null +++ b/tests/fixtures/entry-points/a/index.ts @@ -0,0 +1 @@ +export { ComponentA } from "./ComponentA/ComponentA"; diff --git a/tests/fixtures/entry-points/b/ComponentB/ComponentB.tsx b/tests/fixtures/entry-points/b/ComponentB/ComponentB.tsx new file mode 100644 index 0000000..166532d --- /dev/null +++ b/tests/fixtures/entry-points/b/ComponentB/ComponentB.tsx @@ -0,0 +1,10 @@ +import React from "react"; + +interface ComponentBProps { + test: string; +} + +export function ComponentB(props: ComponentBProps): React.JSX.Element { + const { test } = props; + return <>ComponentB: {test}; +} diff --git a/tests/fixtures/entry-points/b/index.ts b/tests/fixtures/entry-points/b/index.ts new file mode 100644 index 0000000..65837c8 --- /dev/null +++ b/tests/fixtures/entry-points/b/index.ts @@ -0,0 +1 @@ +export { ComponentB } from "./ComponentB/ComponentB"; diff --git a/tests/rolldown.test.ts b/tests/rolldown.test.ts index c468a26..42438df 100644 --- a/tests/rolldown.test.ts +++ b/tests/rolldown.test.ts @@ -4,8 +4,8 @@ import { expect, test } from 'vitest' import UnpluginIsolatedDecl from '../src/rolldown' test('rolldown', async () => { - const input = path.resolve(__dirname, 'fixtures/main.ts') - const dist = path.resolve(__dirname, 'temp') + const input = path.resolve(__dirname, 'fixtures/basic/main.ts') + const dist = path.resolve(__dirname, 'temp/rolldown/basic') const bundle = await rolldown({ input, diff --git a/tests/rollup.test.ts b/tests/rollup.test.ts index 9108ff7..cc59d8a 100644 --- a/tests/rollup.test.ts +++ b/tests/rollup.test.ts @@ -1,31 +1,88 @@ +import fs from 'node:fs/promises' import path from 'node:path' import { rollup } from 'rollup' import esbuild from 'rollup-plugin-esbuild' -import { expect, test } from 'vitest' +import { describe, expect, test } from 'vitest' import UnpluginIsolatedDecl from '../src/rollup' -test('rollup', async () => { - const input = path.resolve(__dirname, 'fixtures/main.ts') - const dist = path.resolve(__dirname, 'temp') - - const bundle = await rollup({ - input, - plugins: [ - UnpluginIsolatedDecl({ - extraOutdir: 'temp', - }), - esbuild(), - ], - logLevel: 'silent', +describe('rollup', () => { + const TEST_SANDBOX_FOLDER = 'temp/rollup' + + test('generate basic', async () => { + const input = path.resolve(__dirname, 'fixtures/basic/main.ts') + const dist = path.resolve(__dirname, `${TEST_SANDBOX_FOLDER}/basic`) + + const bundle = await rollup({ + input, + plugins: [ + UnpluginIsolatedDecl({ + extraOutdir: 'temp', + }), + esbuild(), + ], + logLevel: 'silent', + }) + + const result = await bundle.generate({ + dir: dist, + }) + + expect( + result.output.map((asset) => + [ + `// ${asset.fileName.replaceAll('\\', '/')}`, + asset.type === 'chunk' ? asset.code : asset.source, + ].join('\n'), + ), + ).toMatchSnapshot() }) - const result = await bundle.generate({ - dir: dist, + test('write entry-points', async () => { + const input = { + a: path.resolve(__dirname, 'fixtures/entry-points/a/index.ts'), + b: path.resolve(__dirname, 'fixtures/entry-points/b/index.ts'), + } + const dist = path.resolve(__dirname, `${TEST_SANDBOX_FOLDER}/entry-points`) + + const bundle = await rollup({ + input, + plugins: [UnpluginIsolatedDecl(), esbuild()], + logLevel: 'silent', + }) + + // https://github.com/unplugin/unplugin-isolated-decl/issues/22 + await bundle.write({ + dir: dist, + entryFileNames: '[name]/index.js', + preserveModules: true, + }) + + /** + * Map written output from file system rather than from bundle due to + * module execution order not consistent + * + * @see https://github.com/rollup/rollup/issues/3888 + */ + const allBundledFiles = ( + await fs.readdir(dist, { + recursive: true, + withFileTypes: true, + }) + ).filter((it) => it.isFile()) + + const fileSystemOutput = allBundledFiles.map((it) => { + return (async () => { + const filePath = path.relative(dist, path.join(it.parentPath, it.name)) + + const content = await fs.readFile(path.join(dist, filePath), 'utf-8') + + return [ + `// ${filePath.replaceAll('\\', '/')}`, + content.toString(), + ].join('\n') + })() + }) + + expect(Promise.all(fileSystemOutput)).resolves.toMatchSnapshot() }) - expect( - result.output.map( - (asset) => - `// ${asset.fileName.replaceAll('\\', '/')}\n${asset.type === 'chunk' ? asset.code : asset.source}`, - ), - ).toMatchSnapshot() })