diff --git a/docs/app/globals.css b/docs/app/globals.css index d2bd52fa..113aa473 100644 --- a/docs/app/globals.css +++ b/docs/app/globals.css @@ -42,9 +42,10 @@ pre > code { color: #333; } -a, a:visited { +a, +a:visited { color: #333; } a:hover { color: #999; -} \ No newline at end of file +} diff --git a/package.json b/package.json index 0d28a358..d551a19a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ ], "prettier": { "semi": false, - "singleQuote": true + "singleQuote": true, + "trailingComma": "all" }, "engines": { "node": ">= 18.0.0" @@ -106,7 +107,7 @@ "lint-staged": "^15.2.2", "next": "^15.0.4", "picocolors": "^1.0.0", - "prettier": "^3.0.0", + "prettier": "2.8.8", "react": "^19.0.0", "react-dom": "^19.0.0", "typescript": "^5.7.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4facffc0..c69ab039 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,8 +121,8 @@ importers: specifier: ^1.0.0 version: 1.0.0 prettier: - specifier: ^3.0.0 - version: 3.0.0 + specifier: 2.8.8 + version: 2.8.8 react: specifier: ^19.0.0 version: 19.0.0 @@ -1922,9 +1922,9 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - prettier@3.0.0: - resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} - engines: {node: '>=14'} + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} hasBin: true pretty-bytes@5.6.0: @@ -4234,7 +4234,7 @@ snapshots: picocolors: 1.0.0 source-map-js: 1.2.1 - prettier@3.0.0: {} + prettier@2.8.8: {} pretty-bytes@5.6.0: {} diff --git a/src/bin/index.ts b/src/bin/index.ts index 0e80e93c..a5c63692 100644 --- a/src/bin/index.ts +++ b/src/bin/index.ts @@ -317,7 +317,7 @@ async function run(args: CliArgs) { } if (watch) { - logger.log(`Watching project ${cwd}...`) + logger.log(`Watching changes in the project directory...`) } try { diff --git a/src/plugins/alias-plugin.ts b/src/plugins/alias-plugin.ts index 9385e9e2..e77cb90d 100644 --- a/src/plugins/alias-plugin.ts +++ b/src/plugins/alias-plugin.ts @@ -121,8 +121,9 @@ export function aliasEntries({ let matchedBundlePath: string | undefined if (dts) { // Find the type with format condition first - matchedBundlePath = exportMapEntries.find(findTypesFileCallback) - ?.bundlePath + matchedBundlePath = exportMapEntries.find( + findTypesFileCallback, + )?.bundlePath // If theres no format specific types such as import.types or require.types, // fallback to the general types file. if (!matchedBundlePath) { diff --git a/test/cli/output-in-watch/index.test.ts b/test/cli/output-in-watch/index.test.ts index 3fa3b05c..b89d88f2 100644 --- a/test/cli/output-in-watch/index.test.ts +++ b/test/cli/output-in-watch/index.test.ts @@ -1,19 +1,18 @@ -import { createCliTest } from '../../testing-utils' +import { createJob } from '../../testing-utils' -describe('cli', () => { +describe('cli - output-in-watch', () => { + const { job } = createJob({ + directory: __dirname, + args: ['hello.js', '-w', '-o', 'dist/hello.bundle.js'], + abortTimeout: 3000, + }) it(`cli output-in-watch should work properly`, async () => { - await createCliTest( - { - directory: __dirname, - args: ['hello.js', '-w', '-o', 'dist/hello.bundle.js'], - abortTimeout: 3000, - }, - ({ signal, stdout, stderr }) => { - console.log('stdout', stdout, stderr) - expect(stdout.includes('Watching project')).toBe(true) - expect(stdout.includes('Exports')).toBe(false) - expect(signal).toBe('SIGTERM') // SIGTERM exit code - }, - ) + const { signal, stdout } = job + + expect(stdout).toMatchInlineSnapshot(` + "Watching changes in the project directory... + " + `) + expect(signal).toBe('SIGTERM') // SIGTERM exit code }) }) diff --git a/test/integration/entry-index-index/index.test.ts b/test/integration/entry-index-index/index.test.ts index 966d1bf9..3d8725e2 100644 --- a/test/integration/entry-index-index/index.test.ts +++ b/test/integration/entry-index-index/index.test.ts @@ -1,20 +1,21 @@ -import { createIntegrationTest, assertFilesContent } from '../../testing-utils' +import { + assertFilesContent, + createJob, + stripANSIColor, +} from '../../testing-utils' describe('integration entry-index-index', () => { + const { distDir, job } = createJob({ + directory: __dirname, + }) it('should work with index file inside index directory', async () => { - await createIntegrationTest( - { - directory: __dirname, - }, - async ({ distDir, stdout }) => { - await assertFilesContent(distDir, { - 'default.js': /'index'/, - 'react-server.js': /\'react-server\'/, - }) + await assertFilesContent(distDir, { + 'default.js': /'index'/, + 'react-server.js': /\'react-server\'/, + }) - expect(stdout).toContain('dist/react-server.js') - expect(stdout).toContain('dist/default.js') - }, - ) + const stdout = stripANSIColor(job.stdout) + expect(stdout).toContain('. dist/default.js') + expect(stdout).toContain('. (react-server) dist/react-server.js') }) }) diff --git a/test/integration/mixed-directives/__snapshots__/mixed-directives.test.ts.snap b/test/integration/mixed-directives/__snapshots__/mixed-directives.test.ts.snap deleted file mode 100644 index f71e02f3..00000000 --- a/test/integration/mixed-directives/__snapshots__/mixed-directives.test.ts.snap +++ /dev/null @@ -1,42 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`integration - mixed-directives should work with js only project 1`] = ` -{ - "action-server-DOTFC6td.js": "'use server'; -async function action1() { - return 'action1'; -} - -export { action1 as a }; -", - "client.js": "'use client'; -import { jsx } from 'react/jsx-runtime'; -import { a as action1 } from './action-server-DOTFC6td.js'; - -function Page() { - return /*#__PURE__*/ jsx("button", { - onClick: action1, - children: "Action 1" - }); -} - -export { Page as default }; -", - "inline.js": "import { jsx } from 'react/jsx-runtime'; -import ClientComponent from 'client-component'; - -// @ts-ignore externals -function Page() { - async function inlineAction() { - 'use server'; - return 'inline-action'; - } - return /*#__PURE__*/ jsx(ClientComponent, { - action: inlineAction - }); -} - -export { Page as default }; -", -} -`; diff --git a/test/integration/mixed-directives/mixed-directives.test.ts b/test/integration/mixed-directives/mixed-directives.test.ts index 9f91c465..c33bc16d 100644 --- a/test/integration/mixed-directives/mixed-directives.test.ts +++ b/test/integration/mixed-directives/mixed-directives.test.ts @@ -1,28 +1,51 @@ -import { readFileSync } from 'fs' -import { - createIntegrationTest, - getFileNamesFromDirectory, -} from '../../testing-utils' +import { getFileContents, createJob } from '../../testing-utils' describe('integration - mixed-directives', () => { + const { distDir } = createJob({ + directory: __dirname, + }) it('should work with js only project', async () => { - await createIntegrationTest( + const fileContents = await getFileContents(distDir) + + expect(fileContents).toMatchInlineSnapshot(` { - directory: __dirname, - }, - async ({ distDir }) => { - const distFiles = await getFileNamesFromDirectory(distDir) - const fileContents = distFiles - .map((file) => [file, readFileSync(`${distDir}/${file}`, 'utf-8')]) - .reduce((acc, pair) => { - return { - ...acc, - [pair[0]]: pair[1], - } - }, {}) + "action-server-DOTFC6td.js": "'use server'; + async function action1() { + return 'action1'; + } + + export { action1 as a }; + ", + "client.js": "'use client'; + import { jsx } from 'react/jsx-runtime'; + import { a as action1 } from './action-server-DOTFC6td.js'; + + function Page() { + return /*#__PURE__*/ jsx("button", { + onClick: action1, + children: "Action 1" + }); + } + + export { Page as default }; + ", + "inline.js": "import { jsx } from 'react/jsx-runtime'; + import ClientComponent from 'client-component'; + + // @ts-ignore externals + function Page() { + async function inlineAction() { + 'use server'; + return 'inline-action'; + } + return /*#__PURE__*/ jsx(ClientComponent, { + action: inlineAction + }); + } - expect(fileContents).toMatchSnapshot(``) - }, - ) + export { Page as default }; + ", + } + `) }) }) diff --git a/test/integration/mixed-directives/tsconfig.json b/test/integration/mixed-directives/tsconfig.json index 3e558e56..f0271385 100644 --- a/test/integration/mixed-directives/tsconfig.json +++ b/test/integration/mixed-directives/tsconfig.json @@ -2,5 +2,6 @@ "compilerOptions": { "jsx": "react-jsx", "target": "ES2022" - } -} \ No newline at end of file + }, + "exclude": ["*.test.ts"] +} diff --git a/test/integration/monorepo-composite-no-incremental/index.test.ts b/test/integration/monorepo-composite-no-incremental/index.test.ts index 0e5e1612..70b34082 100644 --- a/test/integration/monorepo-composite-no-incremental/index.test.ts +++ b/test/integration/monorepo-composite-no-incremental/index.test.ts @@ -1,15 +1,9 @@ import { join } from 'path' -import { assertContainFiles, createIntegrationTest } from '../../testing-utils' +import { assertContainFiles, createJob } from '../../testing-utils' describe('integration monorepo-composite-no-incremental', () => { + const { distDir } = createJob({ directory: join(__dirname, 'packages', 'a') }) it('should succeed the build', async () => { - await createIntegrationTest( - { - directory: join(__dirname, 'packages', 'a'), - }, - async ({ distDir }) => { - await assertContainFiles(distDir, ['index.js', 'index.d.ts']) - }, - ) + await assertContainFiles(distDir, ['index.js', 'index.d.ts']) }) }) diff --git a/test/integration/monorepo-composite-no-incremental/tsconfig.json b/test/integration/monorepo-composite-no-incremental/tsconfig.json index 8ca9ad64..363f8a38 100644 --- a/test/integration/monorepo-composite-no-incremental/tsconfig.json +++ b/test/integration/monorepo-composite-no-incremental/tsconfig.json @@ -8,5 +8,6 @@ { "path": "./packages/a" } - ] + ], + "exclude": ["*.test.ts"] } diff --git a/test/integration/multi-entries/index.test.ts b/test/integration/multi-entries/index.test.ts index 8973cff7..7b2deb2c 100644 --- a/test/integration/multi-entries/index.test.ts +++ b/test/integration/multi-entries/index.test.ts @@ -1,52 +1,44 @@ import { assertFilesContent, - createIntegrationTest, - getChunkFileNamesFromLog, - stripANSIColor, + createJob, + getFileNamesFromDirectory, } from '../../testing-utils' -describe('integration multi-entries', () => { +describe('integration - multi-entries', () => { + const { dir, distDir, job } = createJob({ directory: __dirname }) it('should contain files', async () => { - await createIntegrationTest( - { - directory: __dirname, - }, - async ({ dir, stdout }) => { - const contentsRegex = { - './dist/index.js': /'index'/, - './dist/shared/index.mjs': /'shared'/, - './dist/shared/edge-light.mjs': /'shared.edge-light'/, - './dist/server/edge.mjs': /'server.edge-light'/, - './dist/server/react-server.mjs': /'server.react-server'/, - // types - './dist/server/index.d.ts': `export { Client } from '../client/index.js';\nexport { Shared } from '../shared/index.js';`, - './dist/client/index.d.ts': `export { Shared } from '../shared/index.js'`, - } + const contentsRegex = { + './dist/index.js': /'index'/, + './dist/shared/index.mjs': /'shared'/, + './dist/shared/edge-light.mjs': /'shared.edge-light'/, + './dist/server/edge.mjs': /'server.edge-light'/, + './dist/server/react-server.mjs': /'server.react-server'/, + // types + './dist/server/index.d.ts': `export { Client } from '../client/index.js';\nexport { Shared } from '../shared/index.js';`, + './dist/client/index.d.ts': `export { Shared } from '../shared/index.js'`, + } - await assertFilesContent(dir, contentsRegex) + await assertFilesContent(dir, contentsRegex) - const log = `\ - dist/index.js - dist/index.d.ts - dist/lite.js - dist/client/index.mjs - dist/client/index.cjs - dist/client/index.d.ts - dist/server/index.mjs - dist/server/index.d.ts - dist/server/edge.mjs - dist/server/react-server.mjs - dist/shared/index.mjs - dist/shared/index.cjs - dist/shared/index.d.ts - dist/shared/edge-light.mjs - ` + const files = await getFileNamesFromDirectory(distDir) - const rawStdout = stripANSIColor(stdout) - getChunkFileNamesFromLog(log).forEach((chunk: string) => { - expect(rawStdout).toContain(chunk) - }) - }, - ) + expect(files).toMatchInlineSnapshot(` + [ + "client/index.cjs", + "client/index.d.ts", + "client/index.mjs", + "index.d.ts", + "index.js", + "lite.js", + "server/edge.mjs", + "server/index.d.ts", + "server/index.mjs", + "server/react-server.mjs", + "shared/edge-light.mjs", + "shared/index.cjs", + "shared/index.d.ts", + "shared/index.mjs", + ] + `) }) }) diff --git a/test/integration/prepare-js/index.test.ts b/test/integration/prepare-js/index.test.ts index 133a64c8..6e2d91f4 100644 --- a/test/integration/prepare-js/index.test.ts +++ b/test/integration/prepare-js/index.test.ts @@ -2,60 +2,59 @@ import fsp from 'fs/promises' import { join } from 'path' import { assertContainFiles, - createIntegrationTest, + createJob, stripANSIColor, } from '../../testing-utils' describe('integration prepare-js', () => { - const dir = __dirname beforeAll(async () => { - await fsp.writeFile(join(dir, './package.json'), '{ "type": "commonjs" }') + await fsp.writeFile( + join(__dirname, './package.json'), + '{ "type": "commonjs" }', + ) }) + const { dir, job } = createJob({ directory: __dirname, args: ['prepare'] }) + it('should contain correct files', async () => { - await createIntegrationTest( - { - args: ['prepare'], - directory: __dirname, + const { stdout } = job + await assertContainFiles(dir, ['package.json']) + const pkgJson = JSON.parse( + await fsp.readFile(join(dir, './package.json'), 'utf-8'), + ) + expect(pkgJson.main).toBe('./dist/index.js') + expect(pkgJson.module).toBe('./dist/index.mjs') + expect(pkgJson.types).toBeFalsy() + expect(pkgJson.files).toContain('dist') + expect(pkgJson.bin).toBe('./dist/bin/index.js') + expect(pkgJson.exports).toEqual({ + './foo': { + import: './dist/foo.mjs', + require: './dist/foo.js', }, - async ({ dir, stdout }) => { - await assertContainFiles(dir, ['package.json']) - const pkgJson = JSON.parse( - await fsp.readFile(join(dir, './package.json'), 'utf-8'), - ) - expect(pkgJson.main).toBe('./dist/index.js') - expect(pkgJson.module).toBe('./dist/index.mjs') - expect(pkgJson.types).toBeFalsy() - expect(pkgJson.files).toContain('dist') - expect(pkgJson.bin).toBe('./dist/bin/index.js') - expect(pkgJson.exports).toEqual({ - './foo': { - import: './dist/foo.mjs', - require: './dist/foo.js', - }, - '.': { - import: './dist/index.mjs', - require: './dist/index.js', - }, - }) - - /* - Discovered binaries entries: - .: bin.js - Discovered exports entries: - ./foo: foo.js - . : index.js - ✓ Configured `exports` in package.json - */ - expect(stdout).toContain('Discovered binaries entries:') - expect(stdout).toMatch(/.\s*: bin.js/) - expect(stdout).toContain('Discovered exports entries:') - expect(stdout).toMatch(/\.\/foo\s*: foo.js/) - expect(stdout).toMatch(/\.\s*: index.js/) - expect(stripANSIColor(stdout)).toContain( - '✓ Configured `exports` in package.json', - ) + '.': { + import: './dist/index.mjs', + require: './dist/index.js', }, - ) + }) + + /* + Discovered binaries entries: + .: bin.js + Discovered exports entries: + ./foo: foo.js + . : index.js + ✓ Configured `exports` in package.json + */ + + expect(stripANSIColor(stdout)).toMatchInlineSnapshot(` + "Discovered binaries entries: + ./$binary: bin.js + Discovered exports entries: + . : index.js + ./foo: foo.js + ✓ Configured \`exports\` in package.json + " + `) }) }) diff --git a/test/integration/prepare-ts/index.test.ts b/test/integration/prepare-ts/index.test.ts index 14a9bffc..bcb306f0 100644 --- a/test/integration/prepare-ts/index.test.ts +++ b/test/integration/prepare-ts/index.test.ts @@ -2,7 +2,7 @@ import fsp from 'fs/promises' import { join } from 'path' import { assertContainFiles, - createIntegrationTest, + createJob, deleteFile, stripANSIColor, } from '../../testing-utils' @@ -13,71 +13,70 @@ describe('integration prepare-ts', () => { await deleteFile(join(__dirname, './tsconfig.json')) }) + const { dir, job } = createJob({ + args: ['prepare'], + directory: __dirname, + }) + it('should contain files', async () => { - await createIntegrationTest( - { - args: ['prepare'], - directory: __dirname, + const { stdout } = job + await assertContainFiles(dir, ['package.json', 'tsconfig.json']) + const pkgJson = JSON.parse( + await fsp.readFile(join(dir, './package.json'), 'utf-8'), + ) + expect(pkgJson.files).toContain('dist') + expect(pkgJson.bin).toEqual({ + cli: './dist/bin/cli.js', + cmd: './dist/bin/cmd.js', + }) + expect(pkgJson.type).toBe('module') + expect(pkgJson.main).toBe('./dist/es/index.js') + expect(pkgJson.module).toBe('./dist/es/index.js') + expect(pkgJson.exports).toEqual({ + './foo': { + import: { + types: './dist/es/foo.d.ts', + default: './dist/es/foo.js', + }, + require: { + types: './dist/cjs/foo.d.cts', + default: './dist/cjs/foo.cjs', + }, }, - async ({ dir, stdout }) => { - await assertContainFiles(dir, ['package.json', 'tsconfig.json']) - const pkgJson = JSON.parse( - await fsp.readFile(join(dir, './package.json'), 'utf-8'), - ) - expect(pkgJson.files).toContain('dist') - expect(pkgJson.bin).toEqual({ - cli: './dist/bin/cli.js', - cmd: './dist/bin/cmd.js', - }) - expect(pkgJson.type).toBe('module') - expect(pkgJson.main).toBe('./dist/es/index.js') - expect(pkgJson.module).toBe('./dist/es/index.js') - expect(pkgJson.exports).toEqual({ - './foo': { - import: { - types: './dist/es/foo.d.ts', - default: './dist/es/foo.js', - }, - require: { - types: './dist/cjs/foo.d.cts', - default: './dist/cjs/foo.cjs', - }, - }, - '.': { - 'react-server': './dist/es/index-react-server.mjs', - import: { - types: './dist/es/index.d.ts', - default: './dist/es/index.js', - }, - require: { - types: './dist/cjs/index.d.cts', - default: './dist/cjs/index.cjs', - }, - }, - }) - - /* - Discovered binaries entries: - ./cli: cli.ts - ./cmd: cmd.ts - Discovered exports entries: - ./foo: foo.ts - . : index.react-server.ts - . : index.ts - ✓ Configured `exports` in package.json - */ - expect(stripANSIColor(stdout)).toContain( - 'Detected using TypeScript but tsconfig.json is missing, created a tsconfig.json for you.', - ) - expect(stdout).toContain('Discovered binaries entries:') - expect(stdout).toMatch(/\.\s*: index.ts/) - expect(stdout).toContain('Discovered exports entries:') - expect(stdout).toMatch(/\.\/foo\s*: foo.ts/) - expect(stdout).toMatch(/\.\s*: index.react-server.ts/) - expect(stripANSIColor(stdout)).toContain( - '✓ Configured `exports` in package.json', - ) + '.': { + 'react-server': './dist/es/index-react-server.mjs', + import: { + types: './dist/es/index.d.ts', + default: './dist/es/index.js', + }, + require: { + types: './dist/cjs/index.d.cts', + default: './dist/cjs/index.cjs', + }, }, - ) + }) + + /* + Discovered binaries entries: + ./cli: cli.ts + ./cmd: cmd.ts + Discovered exports entries: + ./foo: foo.ts + . : index.react-server.ts + . : index.ts + ✓ Configured `exports` in package.json + */ + expect(stripANSIColor(stdout)).toMatchInlineSnapshot(` + "Detected using TypeScript but tsconfig.json is missing, created a tsconfig.json for you. + Discovered binaries entries: + ./cmd: cmd.ts + ./cli: cli.ts + Discovered exports entries: + . : index.ts + . : index.react-server.ts + ./foo: foo.ts + ✓ Configured \`exports\` in package.json + " + `) }) }) diff --git a/test/testing-utils/helpers.ts b/test/testing-utils/helpers.ts index 28163135..0c97e5f3 100644 --- a/test/testing-utils/helpers.ts +++ b/test/testing-utils/helpers.ts @@ -90,7 +90,7 @@ export const fullExtension = (filename: string) => export function getChunkFileNamesFromLog(log: string) { return log.split('\n').map((line: string) => { - return line.replace(/- \d+ K?B/, '').trim() + return line.replace(/\s*\d+ K?B\s*/, '').trim() }) } diff --git a/test/tsconfig.json b/test/tsconfig.json index a3ca4520..20041b23 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -9,7 +9,7 @@ "baseUrl": "..", "paths": { "bunchee": ["./src/index.ts"], - "testing-utils": ["./test/testing-utils/index.ts"], + "testing-utils": ["./test/testing-utils/index.ts"] } }, "include": [