App;
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/esm-pkg-cjs-main-field/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { createJob, assertContainFiles } from '../../testing-utils'
3 |
4 | describe('integration esm-pkg-cjs-main-field', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should work with ESM package with CJS main field ', async () => {
8 | const distFiles = ['index.cjs', 'index.mjs']
9 | assertContainFiles(distDir, distFiles)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/integration/esm-pkg-cjs-main-field/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "esm-pkg-cjs-main-field",
3 | "type": "module",
4 | "main": "./dist/index.cjs",
5 | "exports": {
6 | ".": {
7 | "import": "./dist/index.mjs",
8 | "require": "./dist/index.cjs"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/integration/esm-pkg-cjs-main-field/src/index.js:
--------------------------------------------------------------------------------
1 | export const value = 'cjs'
2 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertFilesContent,
4 | getFileContents,
5 | createJob,
6 | } from '../../testing-utils'
7 |
8 | describe('integration esm-shims', () => {
9 | const { distDir } = createJob({ directory: __dirname })
10 |
11 | it('should work with ESM shims', async () => {
12 | const requirePolyfill =
13 | 'const require = __node_cjsModule.createRequire(import.meta.url)'
14 | const filenamePolyfill =
15 | 'const __filename = __node_cjsUrl.fileURLToPath(import.meta.url)'
16 | const dirnamePolyfill =
17 | 'const __dirname = __node_cjsPath.dirname(__filename)'
18 |
19 | await assertFilesContent(distDir, {
20 | 'filename.mjs': filenamePolyfill,
21 | 'dirname.mjs': dirnamePolyfill,
22 | 'custom-require.mjs': (code) => !code.includes(requirePolyfill),
23 | 'require.js': /require\(/,
24 | 'filename.js': /__filename/,
25 | 'dirname.js': /__dirname/,
26 | 'custom-require.js': (code) => !code.includes(requirePolyfill),
27 | })
28 |
29 | const contents = await getFileContents(distDir, ['require.mjs'])
30 | expect(contents['require.mjs']).not.toContain(requirePolyfill)
31 | expect(contents['require.mjs']).toContain('function getRequireModule')
32 | expect(contents['require.mjs']).toContain('import.meta.url')
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "exports": {
3 | "./require": {
4 | "import": "./dist/require.mjs",
5 | "require": "./dist/require.js"
6 | },
7 | "./dirname": {
8 | "import": "./dist/dirname.mjs",
9 | "require": "./dist/dirname.js"
10 | },
11 | "./filename": {
12 | "import": "./dist/filename.mjs",
13 | "require": "./dist/filename.js"
14 | },
15 | "./custom-require": {
16 | "import": "./dist/custom-require.mjs",
17 | "require": "./dist/custom-require.js"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/src/custom-require.js:
--------------------------------------------------------------------------------
1 | const __getOwnPropNames = Object.getOwnPropertyNames
2 | var __commonJS = (cb, mod) =>
3 | function __require() {
4 | return (
5 | mod ||
6 | (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod),
7 | mod.exports
8 | )
9 | }
10 |
11 | export const a = 1
12 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/src/dirname.js:
--------------------------------------------------------------------------------
1 | export function getDirname() {
2 | return __dirname
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/src/filename.js:
--------------------------------------------------------------------------------
1 | export function getFilename() {
2 | return __filename
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/esm-shims/src/require.js:
--------------------------------------------------------------------------------
1 | export function getRequireModule() {
2 | return require('node:fs')
3 | }
4 |
5 | export function esmImport() {
6 | return import.meta.url
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/exports-order/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exports-order",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "edge-light": {
7 | "types": "./dist/index.edge-light.d.ts",
8 | "default": "./dist/index.edge-light.js"
9 | },
10 | "require": {
11 | "types": "./dist/index.d.cts",
12 | "default": "./dist/index.cjs"
13 | },
14 | "import": {
15 | "types": "./dist/index.d.ts",
16 | "default": "./dist/index.js"
17 | }
18 | },
19 | "./a": {
20 | "edge-light": {
21 | "types": "./dist/a.edge-light.d.ts",
22 | "default": "./dist/a.edge-light.js"
23 | },
24 | "require": {
25 | "types": "./dist/a.d.cts",
26 | "default": "./dist/a.cjs"
27 | },
28 | "import": {
29 | "types": "./dist/a.d.ts",
30 | "default": "./dist/a.js"
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/integration/exports-order/src/a.ts:
--------------------------------------------------------------------------------
1 | import './utils.js'
2 | export const foo = 'foo'
3 |
--------------------------------------------------------------------------------
/test/integration/exports-order/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './a.js'
2 |
--------------------------------------------------------------------------------
/test/integration/exports-order/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const goo = 'goo'
2 |
--------------------------------------------------------------------------------
/test/integration/externals/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { readFile } from 'fs/promises'
3 | import { createJob } from '../../testing-utils'
4 |
5 | describe('integration externals', () => {
6 | const { distDir } = createJob({ directory: __dirname })
7 |
8 | it('should handle externals', async () => {
9 | const distFile = `${distDir}/index.js`
10 | const content = await readFile(distFile, { encoding: 'utf-8' })
11 | expect(content).toMatch(/['"]peer-dep['"]/)
12 | expect(content).toMatch(/['"]peer-dep-meta['"]/)
13 | })
14 | })
15 |
--------------------------------------------------------------------------------
/test/integration/externals/node_modules/.modules.yaml:
--------------------------------------------------------------------------------
1 | hoistPattern:
2 | - '*'
3 | hoistedDependencies: {}
4 | included:
5 | dependencies: true
6 | devDependencies: true
7 | optionalDependencies: true
8 | layoutVersion: 5
9 | packageManager: pnpm@8.8.0
10 | pendingBuilds: []
11 | prunedAt: Fri, 20 Oct 2023 19:37:17 GMT
12 | publicHoistPattern:
13 | - '*eslint*'
14 | - '*prettier*'
15 | registries:
16 | default: https://registry.npmjs.org/
17 | skipped: []
18 | storeDir: /Users/kdy1/Library/pnpm/store/v3
19 | virtualStoreDir: .pnpm
20 |
--------------------------------------------------------------------------------
/test/integration/externals/node_modules/peer-dep-meta/index.js:
--------------------------------------------------------------------------------
1 | export default 'peer-dep-meta'
2 |
--------------------------------------------------------------------------------
/test/integration/externals/node_modules/peer-dep/index.js:
--------------------------------------------------------------------------------
1 | export default 'peer-dep'
2 |
--------------------------------------------------------------------------------
/test/integration/externals/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "externals",
3 | "exports": "./dist/index.js",
4 | "peerDependencies": {
5 | "peer-dep": "*"
6 | },
7 | "peerDependenciesMeta": {
8 | "peer-dep-meta": {
9 | "optional": true
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/integration/externals/src/index.js:
--------------------------------------------------------------------------------
1 | import a from 'peer-dep'
2 | import b from 'peer-dep-meta'
3 |
4 | export default a + b
5 |
--------------------------------------------------------------------------------
/test/integration/externals/sub-export.js:
--------------------------------------------------------------------------------
1 | import main from 'externals'
2 |
3 | export default 'sub-export' + main
4 |
--------------------------------------------------------------------------------
/test/integration/import-fallback/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { readFile } from 'fs/promises'
3 | import { createJob } from '../../testing-utils'
4 |
5 | describe('integration import fallback', () => {
6 | const { distDir } = createJob({ directory: __dirname })
7 |
8 | it('should handle import fallback', async () => {
9 | const aEdgeLightFile = `${distDir}/a.edge-light.js`
10 | const content = await readFile(aEdgeLightFile, { encoding: 'utf-8' })
11 | expect(content).toMatch(/import '.\/b.js'/)
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/test/integration/import-fallback/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "exports": {
4 | "./a": {
5 | "edge-light": "./dist/a.edge-light.js"
6 | },
7 | "./b": {
8 | "default": "./dist/b.js"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/integration/import-fallback/src/a/index.edge-light.js:
--------------------------------------------------------------------------------
1 | import '../b'
2 |
--------------------------------------------------------------------------------
/test/integration/import-fallback/src/b.js:
--------------------------------------------------------------------------------
1 | console.log('this is b')
2 |
--------------------------------------------------------------------------------
/test/integration/js-bad-configured-types/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../testing-utils'
3 |
4 | describe('integration js-bad-configured-types', () => {
5 | const { job } = createJob({ directory: __dirname })
6 |
7 | it('should error when types is not correctly configured', async () => {
8 | const { code, stderr } = job
9 | expect(code).toBe(0)
10 |
11 | expect(stderr).toContain(
12 | `Bad export types field with import.require in ./dist/index.d.mts, use "types" export condition for it`,
13 | )
14 | expect(stderr).toContain(
15 | `Bad export types field with require in ./dist/index.d.ts, use "types" export condition for it`,
16 | )
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/test/integration/js-bad-configured-types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "types": "./dist/index.d.ts",
3 | "exports": {
4 | ".": {
5 | "import": {
6 | "require": "./dist/index.d.mts",
7 | "default": "./dist/index.mjs"
8 | },
9 | "require": {
10 | "require": "./dist/index.d.ts",
11 | "default": "./dist/index.js"
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test/integration/js-bad-configured-types/src/index.js:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return 'foo'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/js-only/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'
2 | import { createJob, existsFile } from '../../testing-utils'
3 |
4 | describe('integration - js-only', () => {
5 | beforeEach(() => {
6 | // Mock the 'typescript' module to throw an error on import
7 | vi.mock('typescript', () => {
8 | throw new Error('typescript module should not be imported')
9 | })
10 | })
11 |
12 | afterEach(() => {
13 | // Restore the original module and clear mocks after each test
14 | vi.resetModules() // Reset the module registry to ensure clean state
15 | vi.clearAllMocks() // Clear mocks after each test
16 | })
17 |
18 | const { distDir } = createJob({ directory: __dirname })
19 |
20 | it('should work with js only project', async () => {
21 | const distFile = `${distDir}/index.js`
22 | expect(await existsFile(distFile)).toBe(true)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/test/integration/js-only/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "exports": "./dist/index.js"
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/js-only/src/index.js:
--------------------------------------------------------------------------------
1 | module.exports = `pure js file doesn't require 'typescript' installed`
2 |
--------------------------------------------------------------------------------
/test/integration/lint/cjs-pkg-esm-main-field/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../../testing-utils'
3 |
4 | describe('integration cjs-pkg-esm-main-field', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['lint'],
8 | })
9 | it('should warn if main field with .mjs extension in CJS package', async () => {
10 | const { stderr } = job
11 | expect(stderr).toContain(
12 | 'Cannot export `main` field with .mjs extension in CJS package, only .js extension is allowed',
13 | )
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/lint/cjs-pkg-esm-main-field/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs",
3 | "main": "./dist/index.mjs"
4 | }
5 |
--------------------------------------------------------------------------------
/test/integration/lint/cjs-pkg-esm-main-field/src/index.js:
--------------------------------------------------------------------------------
1 | export const value = 'cjs'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-cjs/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../../testing-utils'
3 |
4 | describe('integration invalid-exports-cjs', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['lint'],
8 | })
9 |
10 | it('should warn on invalid exports as CJS', () => {
11 | const { stderr } = job
12 | expect(stderr).toContain('Missing package name')
13 | expect(stderr).toContain(
14 | 'Cannot export `require` field with .mjs extension in CJS package, only .cjs and .js extensions are allowed',
15 | )
16 | expect(stderr).toContain('./dist/index.mjs')
17 | expect(stderr).toContain(
18 | 'Cannot export `import` field with .js or .cjs extension in CJS package, only .mjs extensions are allowed',
19 | )
20 | expect(stderr).toContain('./dist/foo.js')
21 | expect(stderr).not.toContain('./dist/index.esm.js')
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-cjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "module": "./dist/index.esm.js",
3 | "exports": {
4 | ".": {
5 | "require": "./dist/index.mjs"
6 | },
7 | "./foo": {
8 | "import": "./dist/foo.js"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-cjs/src/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-cjs/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-esm/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../../testing-utils'
3 |
4 | describe('integration invalid-exports-esm', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['lint'],
8 | })
9 |
10 | it('should warn on invalid exports as ESM', async () => {
11 | const { stderr } = job
12 | expect(stderr).not.toContain('Missing package name')
13 | expect(stderr).toContain(
14 | 'Cannot export `require` field with .js or .mjs extension in ESM package, only .cjs extensions are allowed',
15 | )
16 | expect(stderr).toContain('./dist/index.js')
17 | expect(stderr).toContain(
18 | 'Cannot export `import` field with .cjs extension in ESM package, only .js and .mjs extensions are allowed',
19 | )
20 | expect(stderr).toContain('./dist/foo.cjs')
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-esm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "invalid-exports-esm",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "require": "./dist/index.js"
7 | },
8 | "./foo": {
9 | "import": "./dist/foo.cjs"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-esm/src/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/invalid-exports-esm/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-exports/foo/index.js:
--------------------------------------------------------------------------------
1 | const foo = 'foo'
2 |
3 | exports.foo = foo
4 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-exports/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../../testing-utils'
3 |
4 | describe('integration - lint - missing-files-exports', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['lint'],
8 | })
9 |
10 | it('should warn on missing files', async () => {
11 | const { stderr } = job
12 | expect(stderr).toContain('Missing files in package.json')
13 | expect(stderr).toContain('foo/index.js')
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-exports/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "missing-files-exports",
3 | "exports": {
4 | ".": "./dist/index.js",
5 | "./foo": "./foo/index.js"
6 | },
7 | "files": [
8 | "dist"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-exports/src/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-exports/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-main/index.js:
--------------------------------------------------------------------------------
1 | const index = 'index'
2 |
3 | exports.index = index
4 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-main/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../../testing-utils'
3 |
4 | describe('integration - lint - missing-files-main', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['lint'],
8 | })
9 |
10 | it('should warn on missing files', () => {
11 | const { stderr } = job
12 | expect(stderr).toContain('Missing files in package.json')
13 | expect(stderr).toContain('index.js')
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-main/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "missing-files-main",
3 | "main": "index.js",
4 | "files": [
5 | "dist"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/lint/missing-files-main/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/lint/single-entry/.gitignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 |
--------------------------------------------------------------------------------
/test/integration/lint/single-entry/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertContainFiles,
4 | assertFilesContent,
5 | createJob,
6 | stripANSIColor,
7 | } from '../../../testing-utils'
8 |
9 | describe('integration - single-entry', () => {
10 | const { job, distDir } = createJob({
11 | directory: __dirname,
12 | })
13 | it('should warn on invalid exports as CJS', async () => {
14 | const { stdout, stderr } = job
15 | const distFiles = ['index.js', 'index.d.ts']
16 |
17 | await assertContainFiles(distDir, distFiles)
18 | await assertFilesContent(distDir, {
19 | 'index.js': `Object.defineProperty(exports, '__esModule', { value: true });`,
20 | 'index.d.ts': 'declare const _default: () => string;',
21 | })
22 |
23 | const log = `\
24 | dist/index.d.ts
25 | dist/index.js`
26 |
27 | expect(stderr).not.toContain('Cannot export `exports` field with')
28 |
29 | const rawStdout = stripANSIColor(stdout)
30 | log.split('\n').forEach((line: string) => {
31 | expect(rawStdout).toContain(line.trim())
32 | })
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/test/integration/lint/single-entry/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "single-entry",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/lint/single-entry/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/missing-entry-file/missing-entry-file.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils'
3 |
4 | describe('integration - missing-entry-file', () => {
5 | const { distDir, job } = createJob({
6 | directory: __dirname,
7 | })
8 | it('should work', async () => {
9 | const files = await getFileNamesFromDirectory(distDir)
10 | expect(files).toEqual(['index.js'])
11 |
12 | const { stderr } = job
13 | expect(stderr).toContain(
14 | 'The following exports are defined in package.json but missing source files:',
15 | )
16 | // missing ./foo and ./bar
17 | expect(stderr).toContain('⨯ ./foo')
18 | expect(stderr).toContain('⨯ ./bar')
19 | expect(stderr).not.toContain('⨯ ./index')
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/test/integration/missing-entry-file/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "error-bad-entry",
3 | "main": "./dist/index.js",
4 | "type": "module",
5 | "exports": {
6 | ".": "./dist/index.js",
7 | "./foo": "./dist/foo.js",
8 | "./bar": "./dist/bar.js"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/missing-entry-file/src/bar.js.missing:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/missing-entry-file/src/bar.js.missing
--------------------------------------------------------------------------------
/test/integration/missing-entry-file/src/foo.js.missing:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/missing-entry-file/src/foo.js.missing
--------------------------------------------------------------------------------
/test/integration/missing-entry-file/src/index.js:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return 'foo'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/mixed-directives/.gitignore:
--------------------------------------------------------------------------------
1 | !tsconfig.json
--------------------------------------------------------------------------------
/test/integration/mixed-directives/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mixed-directives",
3 | "type": "module",
4 | "exports": {
5 | "./inline": {
6 | "types": "./dist/inline.d.ts",
7 | "default": "./dist/inline.js"
8 | },
9 | "./client": {
10 | "types": "./dist/client.d.ts",
11 | "default": "./dist/client.js"
12 | }
13 | },
14 | "dependencies": {
15 | "react": "*"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/integration/mixed-directives/src/action.ts:
--------------------------------------------------------------------------------
1 | 'use server'
2 |
3 | export async function action1() {
4 | return 'action1'
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/mixed-directives/src/client.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { action1 } from './action'
4 |
5 | export default function Page() {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/mixed-directives/src/inline.tsx:
--------------------------------------------------------------------------------
1 | // @ts-ignore externals
2 | import ClientComponent from 'client-component'
3 |
4 | export default function Page() {
5 | async function inlineAction() {
6 | 'use server'
7 | return 'inline-action'
8 | }
9 |
10 | return
11 | }
12 |
--------------------------------------------------------------------------------
/test/integration/mixed-directives/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ES6",
4 | "moduleResolution": "node",
5 | "jsx": "react-jsx",
6 | "target": "ES2022"
7 | },
8 | "exclude": ["*.test.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { join } from 'path'
3 | import { assertContainFiles, createJob } from '../../testing-utils'
4 |
5 | describe('integration monorepo-composite-no-incremental', () => {
6 | const { distDir } = createJob({ directory: join(__dirname, 'packages', 'a') })
7 | it('should succeed the build', async () => {
8 | await assertContainFiles(distDir, ['index.js', 'index.d.ts'])
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "monorepo-composite-no-incremental",
3 | "dependencies": {
4 | "package": "link:./packages/a"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/packages/a/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a",
3 | "main": "./dist/index.js",
4 | "types": "./dist/index.d.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/packages/a/src/index.ts:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return 'bar'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/packages/a/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "module": "ESNext",
5 | "moduleResolution": "bundler"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite-no-incremental/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "incremental": false
5 | },
6 | "files": [],
7 | "references": [
8 | {
9 | "path": "./packages/a"
10 | }
11 | ],
12 | "exclude": ["*.test.ts"]
13 | }
14 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { join } from 'path'
3 | import { assertContainFiles, createJob } from '../../testing-utils'
4 |
5 | describe('integration monorepo-composite', () => {
6 | const { distDir } = createJob({
7 | directory: join(__dirname, 'packages', 'a'),
8 | })
9 |
10 | it('should succeed the build', async () => {
11 | await assertContainFiles(distDir, ['index.js', 'index.d.ts'])
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "monorepo-composite",
3 | "dependencies": {
4 | "package": "link:./packages/a"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/packages/a/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "package",
3 | "main": "./dist/index.js",
4 | "types": "./dist/index.d.ts"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/packages/a/src/index.ts:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return 'bar'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/packages/a/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "module": "ESNext",
5 | "moduleResolution": "bundler"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/monorepo-composite/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "incremental": true
5 | },
6 | "references": [
7 | {
8 | "path": "./packages/a"
9 | }
10 | ],
11 | "exclude": ["*.test.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertFilesContent,
4 | createJob,
5 | getFileNamesFromDirectory,
6 | } from '../../testing-utils'
7 |
8 | describe('integration - multi-entries', () => {
9 | const { dir, distDir, job } = createJob({ directory: __dirname })
10 | it('should contain files', async () => {
11 | const contentsRegex = {
12 | './dist/index.js': /'index'/,
13 | './dist/shared/index.mjs': /'shared'/,
14 | './dist/shared/edge-light.mjs': /'shared.edge-light'/,
15 | './dist/server/edge.mjs': /'server.edge-light'/,
16 | './dist/server/react-server.mjs': /'server.react-server'/,
17 | // types
18 | './dist/server/index.d.ts': `export { Client } from '../client/index.js';\nexport { Shared } from '../shared/index.js';`,
19 | './dist/client/index.d.ts': `export { Shared } from '../shared/index.js'`,
20 | }
21 |
22 | await assertFilesContent(dir, contentsRegex)
23 |
24 | const files = await getFileNamesFromDirectory(distDir)
25 |
26 | expect(files).toMatchInlineSnapshot(`
27 | [
28 | "client/index.cjs",
29 | "client/index.d.ts",
30 | "client/index.mjs",
31 | "index.d.ts",
32 | "index.js",
33 | "lite.js",
34 | "server/edge.mjs",
35 | "server/index.d.ts",
36 | "server/index.mjs",
37 | "server/react-server.mjs",
38 | "shared/edge-light.mjs",
39 | "shared/index.cjs",
40 | "shared/index.d.ts",
41 | "shared/index.mjs",
42 | ]
43 | `)
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-entries",
3 | "version": "0.0.0",
4 | "types": "./dist/index.d.ts",
5 | "exports": {
6 | "./package.json": "./package.json",
7 | ".": "./dist/index.js",
8 | "./lite": "./dist/lite.js",
9 | "./client": {
10 | "types": "./dist/client/index.d.ts",
11 | "require": "./dist/client/index.cjs",
12 | "import": "./dist/client/index.mjs"
13 | },
14 | "./shared": {
15 | "types": "./dist/shared/index.d.ts",
16 | "import": "./dist/shared/index.mjs",
17 | "require": "./dist/shared/index.cjs",
18 | "edge-light": "./dist/shared/edge-light.mjs"
19 | },
20 | "./server": {
21 | "types": "./dist/server/index.d.ts",
22 | "react-server": "./dist/server/react-server.mjs",
23 | "edge-light": "./dist/server/edge.mjs",
24 | "import": "./dist/server/index.mjs"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/client.ts:
--------------------------------------------------------------------------------
1 | import { type Shared } from './shared'
2 |
3 | export default function client(c: string) {
4 | return 'client' + c
5 | }
6 |
7 | export type Client = string
8 | export { Shared }
9 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/index.ts:
--------------------------------------------------------------------------------
1 | export default 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/lite.ts:
--------------------------------------------------------------------------------
1 | export default function lite(c: string) {
2 | return 'lite' + c
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/server/index.edge-light.ts:
--------------------------------------------------------------------------------
1 | export const name = 'server.edge-light'
2 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/server/index.react-server.ts:
--------------------------------------------------------------------------------
1 | export const name = 'server.react-server'
2 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/server/index.ts:
--------------------------------------------------------------------------------
1 | import { type Client } from '../client'
2 | import { type Shared } from '../shared'
3 |
4 | export const name = 'server.index'
5 | export const main = true
6 |
7 | export { Client, Shared }
8 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/shared.edge-light.ts:
--------------------------------------------------------------------------------
1 | export default 'shared.edge-light'
2 |
--------------------------------------------------------------------------------
/test/integration/multi-entries/src/shared.ts:
--------------------------------------------------------------------------------
1 | export default 'shared'
2 |
3 | export type Shared = string
4 |
--------------------------------------------------------------------------------
/test/integration/multi-exports-ts/.gitignore:
--------------------------------------------------------------------------------
1 | foo/
2 | dist/
3 |
--------------------------------------------------------------------------------
/test/integration/multi-exports-ts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-exports-ts",
3 | "version": "0.0.1",
4 | "exports": {
5 | ".": {
6 | "import": {
7 | "types": "./dist/es/index.d.mts",
8 | "default": "./dist/es/index.mjs"
9 | },
10 | "require": {
11 | "types": "./dist/cjs/index.d.cts",
12 | "default": "./dist/cjs/index.js"
13 | }
14 | },
15 | "./foo": {
16 | "import": {
17 | "types": "./foo/es/index.d.mts",
18 | "default": "./foo/es/index.mjs"
19 | },
20 | "require": {
21 | "types": "./foo/cjs/index.d.cts",
22 | "default": "./foo/cjs/index.js"
23 | }
24 | },
25 | "./types": {
26 | "types": "./dist/types/types.d.ts",
27 | "default": "./dist/types/types.js"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/test/integration/multi-exports-ts/src/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 | export type Foo = typeof foo
3 |
--------------------------------------------------------------------------------
/test/integration/multi-exports-ts/src/index.ts:
--------------------------------------------------------------------------------
1 | import { foo, type Foo } from './foo'
2 |
3 | export const index = 'index'
4 | export const fooIndex = foo
5 | export type FooIndex = Foo
6 |
--------------------------------------------------------------------------------
/test/integration/multi-exports-ts/src/types.ts:
--------------------------------------------------------------------------------
1 | export type SharedType = {
2 | value: string
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/multi-types/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | createJob,
4 | assertFilesContent,
5 | getChunkFileNamesFromLog,
6 | stripANSIColor,
7 | } from '../../testing-utils'
8 |
9 | describe('integration multi-types', () => {
10 | const { distDir, job } = createJob({ directory: __dirname })
11 |
12 | it('should contain files', async () => {
13 | const { stdout } = job
14 | const contentsRegex = {
15 | 'index.js': /'index'/,
16 | // types
17 | 'index.d.ts': `declare const index`,
18 | 'index.d.mts': `declare const index`,
19 | 'index.d.cts': `declare const index`,
20 | }
21 |
22 | await assertFilesContent(distDir, contentsRegex)
23 |
24 | const log = `\
25 | dist/index.cjs
26 | dist/index.js
27 | dist/index.mjs
28 | dist/index.d.mts
29 | dist/index.d.cts
30 | `
31 |
32 | const rawStdout = stripANSIColor(stdout)
33 | getChunkFileNamesFromLog(log).forEach((chunk: string) => {
34 | expect(rawStdout).toContain(chunk)
35 | })
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/test/integration/multi-types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-entries-multi-types",
3 | "types": "./dist/index.d.ts",
4 | "exports": {
5 | "./package.json": "./package.json",
6 | ".": {
7 | "import": {
8 | "types": "./dist/index.d.mts",
9 | "default": "./dist/index.mjs"
10 | },
11 | "require": {
12 | "types": "./dist/index.d.cts",
13 | "default": "./dist/index.cjs"
14 | },
15 | "default": "./dist/index.js"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/integration/multi-types/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/nested-exports/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration nested-exports', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should work with nested path in exports', async () => {
8 | await assertFilesContent(distDir, {
9 | 'foo/bar.js': "'foo.bar'",
10 | })
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/test/integration/nested-exports/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nested-name",
3 | "exports": {
4 | "./foo/bar": "./dist/foo/bar.js"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/nested-exports/src/foo/bar.js:
--------------------------------------------------------------------------------
1 | export const value = 'foo.bar'
2 |
--------------------------------------------------------------------------------
/test/integration/no-clean/.gitignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 |
--------------------------------------------------------------------------------
/test/integration/no-clean/index.test.ts:
--------------------------------------------------------------------------------
1 | import { beforeAll, describe, expect, it } from 'vitest'
2 | import fsp from 'fs/promises'
3 | import { join } from 'path'
4 | import { execSync } from 'child_process'
5 | import {
6 | assertContainFiles,
7 | assertFilesContent,
8 | createJob,
9 | } from '../../testing-utils'
10 | import { existsSync } from 'fs'
11 |
12 | describe('integration - no-clean flag', () => {
13 | const distDir = join(__dirname, 'dist')
14 | beforeAll(async () => {
15 | execSync(`rm -rf ${distDir}`)
16 | await fsp.mkdir(distDir)
17 | await fsp.writeFile(join(distDir, 'no-clean.json'), '{}')
18 | })
19 |
20 | createJob({
21 | directory: __dirname,
22 | args: ['--no-clean'],
23 | })
24 |
25 | it('should not clean dist with --no-clean flag', async () => {
26 | const distFiles = ['index.js', 'index.d.ts']
27 | await assertContainFiles(distDir, distFiles)
28 | await assertFilesContent(distDir, {
29 | 'index.d.ts': 'declare const _default: () => string;',
30 | })
31 |
32 | await assertContainFiles(distDir, distFiles.concat(['no-clean.json']))
33 | })
34 | })
35 |
36 | describe('integration - no-clean default', () => {
37 | const distDir = join(__dirname, 'dist')
38 |
39 | beforeAll(async () => {
40 | execSync(`rm -rf ${distDir}`)
41 | await fsp.mkdir(distDir)
42 | await fsp.writeFile(join(distDir, 'no-clean.json'), '{}')
43 | })
44 |
45 | createJob({
46 | directory: __dirname,
47 | })
48 |
49 | it('should clean dist by default', async () => {
50 | expect(existsSync(join(distDir, 'no-clean.json'))).toBe(false)
51 | expect(existsSync(join(distDir, 'index.js'))).toBe(true)
52 | })
53 | })
54 |
--------------------------------------------------------------------------------
/test/integration/no-clean/no-clean.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/test/integration/no-clean/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "no-clean",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/no-clean/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/no-entry/src/no-entry.txt:
--------------------------------------------------------------------------------
1 | no-entry
--------------------------------------------------------------------------------
/test/integration/no-entry/src/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/no-entry/src/style.css
--------------------------------------------------------------------------------
/test/integration/node-mixed-legacy-modern-entries/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, assertContainFiles } from '../../testing-utils'
3 |
4 | describe('node-mixed-legacy-modern-entries', () => {
5 | const { distDir, job } = createJob({ directory: __dirname })
6 |
7 | it('should deduplicate entries', async () => {
8 | const { stdout } = job
9 | const distFiles = ['index.js', 'index.mjs', 'index.d.ts', 'index.d.mts']
10 | assertContainFiles(distDir, distFiles)
11 | for (const filename of distFiles) {
12 | // only contain file name once
13 | expect(stdout.split(filename).length).toBe(2)
14 | }
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/test/integration/node-mixed-legacy-modern-entries/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-mixed-legacy-modern-entries",
3 | "main": "./dist/index.js",
4 | "module": "./dist/index.mjs",
5 | "types": "./dist/index.d.ts",
6 | "exports": {
7 | "import": {
8 | "types": "./dist/index.d.mts",
9 | "default": "./dist/index.mjs"
10 | },
11 | "require": {
12 | "types": "./dist/index.d.ts",
13 | "default": "./dist/index.js"
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/integration/node-mixed-legacy-modern-entries/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/output-short/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, stripANSIColor } from '../../testing-utils'
3 |
4 | const getOutputSizeColumnIndex = (line: string): number => {
5 | let match
6 | if ((match = /\d+\sK?B/g.exec(line)) !== null) {
7 | return match.index
8 | }
9 | return -1
10 | }
11 |
12 | describe('integration output-short', () => {
13 | const { job } = createJob({ directory: __dirname })
14 |
15 | it('should match output with exports', async () => {
16 | const { stdout } = job
17 | /*
18 | output:
19 |
20 | Exports File Size
21 | . dist/index.js 30 B
22 | */
23 | const [tableHeads, indexLine] = stripANSIColor(stdout).split('\n')
24 | expect(tableHeads).toContain('Exports')
25 | expect(tableHeads).toContain('File')
26 | expect(tableHeads).toContain('Size')
27 |
28 | expect(indexLine).toContain('.')
29 | expect(indexLine).toContain('dist/index.js')
30 |
31 | const [exportsIndex, fileIndex, sizeIndex] = [
32 | tableHeads.indexOf('Exports'),
33 | tableHeads.indexOf('File'),
34 | tableHeads.indexOf('Size'),
35 | ]
36 |
37 | expect(indexLine.indexOf('.')).toEqual(exportsIndex)
38 | expect(indexLine.indexOf('dist/index.js')).toEqual(fileIndex)
39 | expect(getOutputSizeColumnIndex(indexLine)).toEqual(sizeIndex)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/test/integration/output-short/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "output-short",
3 | "exports": {
4 | ".": {
5 | "require": "./dist/index.js"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/output-short/src/index.js:
--------------------------------------------------------------------------------
1 | export const o = 'o'
2 |
--------------------------------------------------------------------------------
/test/integration/output/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@scope/output-app",
3 | "bin": {
4 | "cli": "./dist/cli.js"
5 | },
6 | "exports": {
7 | ".": {
8 | "import": "./dist/index.js",
9 | "react-server": "./dist/index.react-server.js"
10 | },
11 | "./foo": "./dist/foo.js"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/integration/output/src/bin/cli.js:
--------------------------------------------------------------------------------
1 | export const cli = 'cli'
2 |
--------------------------------------------------------------------------------
/test/integration/output/src/foo.js:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 |
--------------------------------------------------------------------------------
/test/integration/output/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/output/src/index.react-server.js:
--------------------------------------------------------------------------------
1 | export const index = 'index.react-server'
2 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-default/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { promises as fsp } from 'fs'
3 | import { join } from 'path'
4 | import { assertContainFiles, createJob } from '../../testing-utils'
5 |
6 | describe('integration pkg-exports-default', () => {
7 | const { distDir } = createJob({ directory: __dirname })
8 |
9 | it('should generate proper assets with js', async () => {
10 | const distFiles = ['index.cjs', 'index.mjs']
11 | await assertContainFiles(distDir, distFiles)
12 | const cjsFile = await fsp.readFile(join(distDir, 'index.cjs'), {
13 | encoding: 'utf-8',
14 | })
15 | expect(cjsFile).toContain(
16 | `function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }`,
17 | )
18 | expect(cjsFile).toContain(
19 | `Object.defineProperty(exports, '__esModule', { value: true });`,
20 | )
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-default/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkg-export-default",
3 | "exports": {
4 | "default": "./dist/index.mjs",
5 | "node": "./dist/index.cjs"
6 | },
7 | "dependencies": {
8 | "my-mod": "*"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-default/src/index.js:
--------------------------------------------------------------------------------
1 | import myMod from 'my-mod'
2 |
3 | export default 'exports-sugar-default'
4 |
5 | export function method() {
6 | return myMod.test()
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-js/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertContainFiles, createJob } from '../../testing-utils'
3 |
4 | describe('integration pkg-exports-js', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should generate proper assets with js', async () => {
8 | const distFiles = ['index.cjs', 'index.mjs', 'index.esm.js']
9 | assertContainFiles(distDir, distFiles)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkg-export-js",
3 | "exports": {
4 | "import": "./dist/index.mjs",
5 | "require": "./dist/index.cjs",
6 | "module": "./dist/index.esm.js"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-js/src/index.js:
--------------------------------------------------------------------------------
1 | export default 'exports-sugar'
2 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/.gitignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration pkg-exports-ts-rsc', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should generate proper assets for rsc condition with ts', async () => {
8 | await assertFilesContent(distDir, {
9 | './index.mjs': /const shared = true/,
10 | './react-server.mjs': /'react-server'/,
11 | './react-native.js': /'react-native'/,
12 | './index.d.ts': /declare const shared = true/,
13 | './api.mjs': `'./index.mjs'`,
14 | './api.react-server.mjs': (content) => {
15 | return (
16 | content.includes('api:react-server') &&
17 | content.includes('./index.mjs')
18 | )
19 | },
20 | })
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pkg-export-ts-rsc",
3 | "exports": {
4 | ".": {
5 | "types": "./dist/index.d.ts",
6 | "react-server": "./dist/react-server.mjs",
7 | "react-native": "./dist/react-native.js",
8 | "import": "./dist/index.mjs",
9 | "require": "./dist/index.cjs"
10 | },
11 | "./api": {
12 | "react-server": "./dist/api.react-server.mjs",
13 | "import": "./dist/api.mjs",
14 | "require": "./dist/api.cjs"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/src/api/index.react-server.ts:
--------------------------------------------------------------------------------
1 | import index, { type IString } from '../index'
2 |
3 | export default 'api:react-server' + index
4 | export { IString }
5 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import index, { type IString } from '../index'
2 |
3 | export default 'api:' + index
4 | export { IString }
5 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/src/index.react-native.ts:
--------------------------------------------------------------------------------
1 | export default 'react-native'
2 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/src/index.react-server.ts:
--------------------------------------------------------------------------------
1 | export default 'react-server'
2 |
--------------------------------------------------------------------------------
/test/integration/pkg-exports-ts-rsc/src/index.ts:
--------------------------------------------------------------------------------
1 | export default 'index'
2 | export const shared = true
3 |
4 | export type IString = string
5 |
--------------------------------------------------------------------------------
/test/integration/prepare-js/.gitignore:
--------------------------------------------------------------------------------
1 | package.json
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-js/src/bin.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/prepare-js/src/bin.js
--------------------------------------------------------------------------------
/test/integration/prepare-js/src/foo.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/prepare-js/src/foo.js
--------------------------------------------------------------------------------
/test/integration/prepare-js/src/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/prepare-js/src/index.js
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-pkg-json/.gitignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 | package.json
3 |
4 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-pkg-json/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 1
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-test-file/.gitignore:
--------------------------------------------------------------------------------
1 | package.json
2 | tsconfig.json
3 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-test-file/index.test.ts:
--------------------------------------------------------------------------------
1 | import { beforeAll, describe, expect, it } from 'vitest'
2 | import fsp from 'fs/promises'
3 | import { join } from 'path'
4 | import { assertContainFiles, createJob, deleteFile } from '../../testing-utils'
5 |
6 | describe('integration prepare-ts-with-test-file', () => {
7 | const dir = __dirname
8 | beforeAll(async () => {
9 | await deleteFile(join(dir, './package.json'))
10 | await deleteFile(join(dir, './tsconfig.json'))
11 | })
12 | createJob({
13 | args: ['prepare'],
14 | directory: __dirname,
15 | })
16 | it('should contain files', async () => {
17 | assertContainFiles(dir, ['package.json'])
18 | const pkgJson = JSON.parse(
19 | await fsp.readFile(join(dir, './package.json'), 'utf-8'),
20 | )
21 | expect(pkgJson.files).toContain('dist')
22 | expect(pkgJson.main).toBe('./dist/es/index.js')
23 | expect(pkgJson.module).toBe('./dist/es/index.js')
24 | expect(Object.keys(pkgJson.exports)).toEqual(['.'])
25 | expect(Object.keys(pkgJson.exports['.'])).not.toContain('./test')
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-test-file/src/foo.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | describe('foo', () => {
3 | it('bar', () => {
4 | expect(true).toBe(true)
5 | })
6 | })
7 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-test-file/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | describe('foo', () => {
3 | it('bar', () => {
4 | expect(true).toBe(true)
5 | })
6 | })
7 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts-with-test-file/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/.gitignore:
--------------------------------------------------------------------------------
1 | package.json
2 | tsconfig.json
3 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/src/bin/cli.ts:
--------------------------------------------------------------------------------
1 | export const cli = 'cli'
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/src/bin/cmd.ts:
--------------------------------------------------------------------------------
1 | export const cmd = 'cmd'
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/src/foo.ts:
--------------------------------------------------------------------------------
1 | export const foo = 'foo'
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/src/index.react-server.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index.react-server'
2 |
--------------------------------------------------------------------------------
/test/integration/prepare-ts/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/raw-data/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { existsSync } from 'fs'
3 | import { assertFilesContent, createJob } from '../../testing-utils'
4 | import { join } from 'path'
5 |
6 | describe('integration - raw-data', () => {
7 | const { distDir } = createJob({ directory: __dirname })
8 |
9 | it('should generate proper assets', async () => {
10 | const distFile = join(distDir, 'index.js')
11 | expect(existsSync(distFile)).toBe(true)
12 | await assertFilesContent(distDir, {
13 | 'index.js': '"thisismydata"',
14 | })
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/test/integration/raw-data/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "exports": "./dist/index.js"
4 | }
5 |
--------------------------------------------------------------------------------
/test/integration/raw-data/src/content.txt:
--------------------------------------------------------------------------------
1 | thisismydata
--------------------------------------------------------------------------------
/test/integration/raw-data/src/index.js:
--------------------------------------------------------------------------------
1 | import content from './content.txt'
2 |
3 | export const data = content
4 |
--------------------------------------------------------------------------------
/test/integration/relative-entry/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "relative-entry",
3 | "type": "module",
4 | "exports": {
5 | ".": "./dist/index.js",
6 | "./relative": "./dist/relative.js"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/relative-entry/relative-entry.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration relative-entry', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should generate proper assets for each exports', async () => {
8 | await assertFilesContent(distDir, {
9 | 'index.js': `from './relative.js'`,
10 | })
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/test/integration/relative-entry/src/index.js:
--------------------------------------------------------------------------------
1 | import { relative } from './relative'
2 |
3 | export function index() {
4 | return 'index' + relative
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/relative-entry/src/relative.js:
--------------------------------------------------------------------------------
1 | export const relative = 'relative'
2 |
--------------------------------------------------------------------------------
/test/integration/server-components-same-layer/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { promises as fsp } from 'fs'
3 | import { join } from 'path'
4 | import { createJob } from '../../testing-utils'
5 |
6 | describe('integration server-components-same-layer', () => {
7 | const { distDir } = createJob({ directory: __dirname })
8 |
9 | it('should generate proper assets for each exports', async () => {
10 | const distFiles = await fsp.readdir(distDir)
11 | const clientChunkFiles = distFiles.filter((f) =>
12 | f.includes('client-client-'),
13 | )
14 | expect(clientChunkFiles.length).toBe(0)
15 |
16 | // index doesn't have "use client" directive
17 | const indexCjs = await fsp.readFile(join(distDir, 'index.cjs'), 'utf-8')
18 | const indexEsm = await fsp.readFile(join(distDir, 'index.js'), 'utf-8')
19 | expect(indexCjs).toContain('use client')
20 | expect(indexEsm).toContain('use client')
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/test/integration/server-components-same-layer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-components-split",
3 | "exports": {
4 | ".": {
5 | "import": "./dist/index.js",
6 | "require": "./dist/index.cjs"
7 | }
8 | },
9 | "peerDependencies": {
10 | "react": "*"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/integration/server-components-same-layer/src/_client.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export function Client() {
4 | return 'client-module'
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/server-components-same-layer/src/index.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React, { useState } from 'react'
4 |
5 | export function Button() {
6 | const [count] = useState(0)
7 | return React.createElement('button', `count: ${count}`)
8 | }
9 |
10 | export { Client } from './_client'
11 |
--------------------------------------------------------------------------------
/test/integration/server-components/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils'
3 |
4 | describe('integration server-components', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should generate proper assets for each exports', async () => {
8 | const jsFiles = await getFileNamesFromDirectory(distDir)
9 |
10 | expect(jsFiles).toEqual([
11 | 'cc-BU0zEyYq.js',
12 | 'cc-DF6UvQmH.cjs',
13 | 'index.cjs',
14 | 'index.js',
15 | 'mod_actions-12x-B8bHfyua.cjs',
16 | 'mod_actions-12x-MaoLVK3i.js',
17 | 'mod_client-12s-BO96FYFA.js',
18 | 'mod_client-12s-DAeHkA4H.cjs',
19 | 'ui.cjs',
20 | 'ui.js',
21 | ])
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/integration/server-components/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server-components",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "import": "./dist/index.js",
7 | "require": "./dist/index.cjs"
8 | },
9 | "./ui": {
10 | "import": "./dist/ui.js",
11 | "require": "./dist/ui.cjs"
12 | }
13 | },
14 | "peerDependencies": {
15 | "react": "*"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/integration/server-components/src/index.js:
--------------------------------------------------------------------------------
1 | export { Button, Client as UIClient } from './ui'
2 | export { action } from './mod_actions'
3 | export { Client } from './mod_client'
4 |
--------------------------------------------------------------------------------
/test/integration/server-components/src/mod_actions.js:
--------------------------------------------------------------------------------
1 | 'use server'
2 |
3 | export async function action() {
4 | return 'server-action'
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/server-components/src/mod_asset.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export const asset = 'asset-module'
4 |
--------------------------------------------------------------------------------
/test/integration/server-components/src/mod_client.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | export function Client() {
4 | return 'client-module'
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/server-components/src/ui.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React, { useState } from 'react'
4 |
5 | export function Button() {
6 | const [count] = useState(0)
7 | return React.createElement('button', `count: ${count}`)
8 | }
9 |
10 | export { Client } from './mod_client'
11 | export { asset } from './mod_asset'
12 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertFilesContent,
4 | createJob,
5 | getFileNamesFromDirectory,
6 | } from '../../testing-utils'
7 |
8 | describe('integration shared-module', () => {
9 | const { distDir } = createJob({ directory: __dirname })
10 |
11 | it('should split all shared module into different chunks', async () => {
12 | const jsFiles = await getFileNamesFromDirectory(distDir)
13 | expect(jsFiles).toEqual([
14 | '_internal/util-a.cjs',
15 | '_internal/util-a.d.ts',
16 | '_internal/util-a.js',
17 | '_internal/util-b.cjs',
18 | '_internal/util-b.d.ts',
19 | '_internal/util-b.js',
20 | 'export-a.js',
21 | 'export-b.js',
22 | 'export-c.js',
23 | 'private/_nested/util-c.cjs',
24 | 'private/_nested/util-c.d.ts',
25 | 'private/_nested/util-c.js',
26 | ])
27 |
28 | await assertFilesContent(distDir, {
29 | 'export-a.js': `'./_internal/util-a.js'`,
30 | 'export-b.js': `'./_internal/util-b.js'`,
31 | 'export-c.js': `'./private/_nested/util-c.js'`,
32 | })
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-module",
3 | "type": "module",
4 | "exports": {
5 | "./export-a": "./dist/export-a.js",
6 | "./export-b": "./dist/export-b.js",
7 | "./export-c": "./dist/export-c.js"
8 | },
9 | "dependencies": {
10 | "react": "*"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/_internal/__mocks__/a.mock.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/integration/shared-any-module/src/_internal/__mocks__/a.mock.js
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/_internal/run-tests.spec.js:
--------------------------------------------------------------------------------
1 | // stub
2 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/_internal/util-a.ts:
--------------------------------------------------------------------------------
1 | export const utilA = 'utilA'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/_internal/util-b.ts:
--------------------------------------------------------------------------------
1 | export const utilB = 'utilB'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/export-a.js:
--------------------------------------------------------------------------------
1 | import { utilA } from './_internal/util-a'
2 | import { utilB } from './_internal/util-b'
3 |
4 | export const getName = () => {
5 | return 'export-a' + utilA + utilB
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/export-b.js:
--------------------------------------------------------------------------------
1 | import { utilB } from './_internal/util-b'
2 | import { utilC } from './private/_nested/util-c'
3 |
4 | export const getName = () => {
5 | return 'export-b' + utilB + utilC
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/export-c.js:
--------------------------------------------------------------------------------
1 | import { utilA } from './_internal/util-a'
2 | import { utilC } from './private/_nested/util-c'
3 |
4 | export const getName = () => {
5 | return 'export-c' + utilA + utilC
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/shared-any-module/src/private/_nested/util-c.ts:
--------------------------------------------------------------------------------
1 | export const utilC = 'utilC'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { promises as fsp } from 'fs'
3 | import { join } from 'path'
4 | import { assertContainFiles, createJob } from '../../testing-utils'
5 |
6 | describe('integration shared-entry', () => {
7 | const { dir } = createJob({ directory: __dirname })
8 |
9 | it('should split shared module into one chunk layer', async () => {
10 | const distFiles = [
11 | './dist/index.js',
12 | './dist/index.mjs',
13 | './dist/shared.js',
14 | './dist/shared.mjs',
15 | ]
16 | assertContainFiles(dir, distFiles)
17 |
18 | // ESM bundle imports from
19 | const indexEsm = await fsp.readFile(join(dir, './dist/index.mjs'), 'utf-8')
20 | expect(indexEsm).toContain(`'./shared.mjs'`)
21 | expect(indexEsm).toContain('index-export')
22 | expect(indexEsm).not.toMatch(/['"]\.\/shared['"]/)
23 | expect(indexEsm).not.toContain('shared-export')
24 |
25 | // CJS bundle imports from
26 | const indexCjs = await fsp.readFile(join(dir, './dist/index.js'), 'utf-8')
27 | expect(indexCjs).toContain(`require('./shared.js')`)
28 | expect(indexCjs).toContain('index-export')
29 | expect(indexCjs).not.toMatch(/['"]\.\/shared['"]/)
30 |
31 | // shared entry contains its own content
32 | const sharedEsm = await fsp.readFile(
33 | join(dir, './dist/shared.mjs'),
34 | 'utf-8',
35 | )
36 | expect(sharedEsm).toContain('shared-export')
37 |
38 | // shared entry contains its own content
39 | const sharedCjs = await fsp.readFile(join(dir, './dist/shared.js'), 'utf-8')
40 | expect(sharedCjs).toContain('shared-export')
41 | })
42 | })
43 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-entry",
3 | "exports": {
4 | ".": {
5 | "import": "./dist/index.mjs",
6 | "require": "./dist/index.js"
7 | },
8 | "./shared": {
9 | "import": "./dist/shared.mjs",
10 | "require": "./dist/shared.js"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/script.js:
--------------------------------------------------------------------------------
1 | const mod = require('shared-entry')
2 | console.log(mod.shared())
3 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index-export'
2 | export { shared } from './shared'
3 | export { foo } from './sub/foo'
4 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/src/shared.js:
--------------------------------------------------------------------------------
1 | export function shared() {
2 | return 'shared-export'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/shared-entry/src/sub/foo.js:
--------------------------------------------------------------------------------
1 | export { shared as foo } from '../shared'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module-special-condition/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-module-special-condition",
3 | "main": "./dist/index.js",
4 | "type": "module",
5 | "exports": {
6 | ".": {
7 | "import": "./dist/index.js",
8 | "development": "./dist/index.development.js",
9 | "production": "./dist/index.production.js",
10 | "browser": "./dist/index.browser.js"
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/integration/shared-module-special-condition/shared-module-special-condition.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, getFileContents } from '../../testing-utils'
3 |
4 | describe('integration - shared-module-special-condition', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | })
8 | it('should work', async () => {
9 | const contents = await getFileContents(distDir)
10 | const files = [
11 | 'index.development.js',
12 | 'index.production.js',
13 | 'index.browser.js',
14 | ]
15 | files.forEach((file) => {
16 | expect(contents[file]).toContain('./_util.js')
17 | expect(contents[file]).not.toContain('./_util.ts')
18 | })
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/test/integration/shared-module-special-condition/src/_util.ts:
--------------------------------------------------------------------------------
1 | export const sharedValue = 'shared-value-text'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module-special-condition/src/index.ts:
--------------------------------------------------------------------------------
1 | import { sharedValue } from './_util'
2 |
3 | export function index() {
4 | return process.env.NODE_ENV + sharedValue
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts-esm/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils'
3 |
4 | describe('integration shared-module-ts-esm', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should contain correct type file path of shared chunks', async () => {
8 | const files = await getFileNamesFromDirectory(distDir)
9 | expect(files).toEqual([
10 | '_util.d.ts',
11 | '_util.js',
12 | '_util.mjs',
13 | 'cjs/index.d.ts',
14 | 'cjs/index.js',
15 | 'es/index.mjs',
16 | ])
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts-esm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-module-ts-esm",
3 | "exports": {
4 | ".": {
5 | "import": {
6 | "types": "./dist/es/index.d.mts",
7 | "default": "./dist/es/index.mjs"
8 | },
9 | "require": {
10 | "types": "./dist/cjs/index.d.ts",
11 | "default": "./dist/cjs/index.js"
12 | }
13 | }
14 | },
15 | "dependencies": {
16 | "react": "*"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts-esm/src/_util.ts:
--------------------------------------------------------------------------------
1 | export function sharedApi() {
2 | return 'common:shared'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts-esm/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 | export { sharedApi } from './_util'
3 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils'
3 |
4 | describe('integration shared-module-ts', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should contain correct type file path of shared chunks', async () => {
8 | const jsFiles = await getFileNamesFromDirectory(distDir)
9 | expect(jsFiles).toEqual([
10 | 'another.cjs',
11 | 'another.d.ts',
12 | 'another.js',
13 | 'index.cjs',
14 | 'index.d.ts',
15 | 'index.js',
16 | 'index.react-server.js',
17 | 'lib/_app-context.cjs',
18 | 'lib/_app-context.d.ts',
19 | 'lib/_app-context.js',
20 | 'lib/_util.cjs',
21 | 'lib/_util.d.ts',
22 | 'lib/_util.js',
23 | ])
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-module-ts",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "types": "./dist/index.d.ts",
7 | "react-server": "./dist/index.react-server.js",
8 | "import": "./dist/index.js",
9 | "default": "./dist/index.cjs"
10 | },
11 | "./another": {
12 | "types": "./dist/another.d.ts",
13 | "import": "./dist/another.js",
14 | "default": "./dist/another.cjs"
15 | }
16 | },
17 | "dependencies": {
18 | "react": "*"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/src/another.ts:
--------------------------------------------------------------------------------
1 | export { sharedApi as anotherSharedApi } from './lib/_util'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/src/index.react-server.ts:
--------------------------------------------------------------------------------
1 | export { AppContext } from './lib/_app-context'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/src/index.ts:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 | export { sharedApi } from './lib/_util'
3 | export { AppContext } from './lib/_app-context'
4 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/src/lib/_app-context.ts:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React from 'react'
4 |
5 | export const AppContext = React.createContext(null)
6 |
--------------------------------------------------------------------------------
/test/integration/shared-module-ts/src/lib/_util.ts:
--------------------------------------------------------------------------------
1 | export function sharedApi() {
2 | return 'common:shared'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/shared-module-with-suffix/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mixed-export-conditions",
3 | "exports": {
4 | "./client": {
5 | "import": {
6 | "default": "./dist/client.mjs"
7 | }
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/shared-module-with-suffix/shared-module-with-suffix.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | // TODO: this is not available as browser cannot be the fallback condition
5 | // Until later we can use chunk split to create shared entry then it will be easier.
6 | describe.skip('integration - shared-module-with-suffix', () => {
7 | const { distDir } = createJob({
8 | directory: __dirname,
9 | })
10 | it('should alias correctly for the shared module with special suffix', async () => {
11 | await assertFilesContent(distDir, {
12 | 'client.mjs': `./_private/util.browser.mjs`,
13 | })
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/shared-module-with-suffix/src/_private/util.browser.ts:
--------------------------------------------------------------------------------
1 | export const util = 'index:browser'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module-with-suffix/src/client/index.ts:
--------------------------------------------------------------------------------
1 | import { util } from '../_private/util.browser'
2 |
3 | export function getClient() {
4 | return 'client' + util
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/shared-module/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertFilesContent,
4 | createJob,
5 | getFileNamesFromDirectory,
6 | } from '../../testing-utils'
7 |
8 | describe('integration shared-module', () => {
9 | const { distDir, job } = createJob({ directory: __dirname })
10 |
11 | it('should split shared module into one chunk layer', async () => {
12 | const jsFiles = await getFileNamesFromDirectory(distDir)
13 | expect(jsFiles).toEqual([
14 | '_internal/index.cjs',
15 | '_internal/index.js',
16 | '_internal/index.react-server.cjs',
17 | '_internal/index.react-server.js',
18 | 'another.cjs',
19 | 'another.js',
20 | 'client.cjs',
21 | 'client.js',
22 | 'index.cjs',
23 | 'index.js',
24 | 'index.react-server.js',
25 | 'lib/_app-context.cjs',
26 | 'lib/_app-context.js',
27 | 'lib/_util.cjs',
28 | 'lib/_util.js',
29 | ])
30 |
31 | // In index.react-server.js, it should refers to _internal/index.react-server.js
32 | await assertFilesContent(distDir, {
33 | 'index.react-server.js': `'./_internal/index.react-server.js'`,
34 | './_internal/index.react-server.js': 'internal:react-server',
35 | })
36 |
37 | // Hide private shared module
38 | expect(job.stdout).not.toContain('./lib/_util')
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/test/integration/shared-module/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shared-module",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "react-server": "./dist/index.react-server.js",
7 | "import": "./dist/index.js",
8 | "default": "./dist/index.cjs"
9 | },
10 | "./another": {
11 | "import": "./dist/another.js",
12 | "default": "./dist/another.cjs"
13 | },
14 | "./client": {
15 | "import": "./dist/client.js",
16 | "default": "./dist/client.cjs"
17 | }
18 | },
19 | "dependencies": {
20 | "react": "*"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/_internal/index.js:
--------------------------------------------------------------------------------
1 | export const internal = 'internal:default'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/_internal/index.react-server.js:
--------------------------------------------------------------------------------
1 | export const internal = 'internal:react-server'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/another.js:
--------------------------------------------------------------------------------
1 | export { sharedApi as anotherSharedApi } from './lib/_util'
2 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/client.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { sharedClient } from './lib/_util'
4 |
5 | export function Client() {
6 | return sharedClient()
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/index.js:
--------------------------------------------------------------------------------
1 | export const index = 'index'
2 | export { sharedApi } from './lib/_util'
3 | export { AppContext } from './lib/_app-context'
4 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/index.react-server.js:
--------------------------------------------------------------------------------
1 | export { AppContext } from './lib/_app-context'
2 | export { internal } from './_internal/index.react-server'
3 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/lib/_app-context.js:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React from 'react'
4 |
5 | export const AppContext = React.createContext(null)
6 |
--------------------------------------------------------------------------------
/test/integration/shared-module/src/lib/_util.js:
--------------------------------------------------------------------------------
1 | export function sharedApi() {
2 | return 'common:shared'
3 | }
4 |
5 | export function sharedClient() {
6 | return 'common:shared-client'
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/sourcemap-dts/index.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, describe, it } from 'vitest'
2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils'
3 |
4 | describe('integration - sourcemap-dts', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | args: ['--sourcemap'],
8 | })
9 | it('should not generate sourcemap for types', async () => {
10 | const files = await getFileNamesFromDirectory(distDir)
11 | expect(files).toEqual(['index.d.ts', 'index.js', 'index.js.map'])
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/test/integration/sourcemap-dts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sourcemap-dts",
3 | "main": "./dist/index.js",
4 | "type": "module",
5 | "exports": {
6 | ".": {
7 | "types": "./dist/index.d.ts",
8 | "default": "./dist/index.js"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/integration/sourcemap-dts/src/index.ts:
--------------------------------------------------------------------------------
1 | export function foo() {
2 | return 'foo'
3 | }
4 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/.gitignore:
--------------------------------------------------------------------------------
1 | !tsconfig.json
2 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "default-ts-target",
3 | "main": "./dist/index.js",
4 | "type": "module",
5 | "exports": {
6 | ".": {
7 | "import": "./dist/index.js",
8 | "require": "./dist/index.cjs"
9 | },
10 | "./foo": {
11 | "import": "./dist/foo.js"
12 | },
13 | "./bar": {
14 | "import": "./dist/bar.js",
15 | "require": "./dist/bar.cjs"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/src/bar.ts:
--------------------------------------------------------------------------------
1 | export class Bar {
2 | method() {
3 | const getResource = () => {
4 | return {
5 | [Symbol.dispose]: () => {
6 | console.log('Hooray!')
7 | },
8 | }
9 | }
10 |
11 | using resource = getResource()
12 | console.log('using resource', resource)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/src/foo.ts:
--------------------------------------------------------------------------------
1 | export class Foo {
2 | async foo() {
3 | return 'async-foo'
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/src/index.ts:
--------------------------------------------------------------------------------
1 | export class Index {
2 | async method() {
3 | const x = { a: 1 }
4 | const y = { b: 2 }
5 | const z = { ...x, ...y }
6 | console.log(z, Object.assign({}, x, y))
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/split-common-chunks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2016",
4 | "module": "ESNext",
5 | "moduleResolution": "bundler"
6 | },
7 | "include": [
8 | "src"
9 | ]
10 | }
--------------------------------------------------------------------------------
/test/integration/stage3-decorator/.gitignore:
--------------------------------------------------------------------------------
1 | tsconfig.json
2 |
--------------------------------------------------------------------------------
/test/integration/stage3-decorator/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { assertContainFiles, stripANSIColor } from '../../testing-utils'
3 | import { createJob } from '../../testing-utils'
4 |
5 | describe('integration stage3-decorator', () => {
6 | const { distDir, job } = createJob({ directory: __dirname })
7 |
8 | it('should build success when enable decorator', async () => {
9 | const { stdout } = job
10 | const distFiles = ['index.js', 'index.d.ts']
11 |
12 | await assertContainFiles(distDir, distFiles)
13 |
14 | const log = `\
15 | dist/index.d.ts
16 | dist/index.js`
17 |
18 | const rawStdout = stripANSIColor(stdout)
19 | log.split('\n').forEach((line: string) => {
20 | expect(rawStdout).toContain(line.trim())
21 | })
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/integration/stage3-decorator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stage3-decorator",
3 | "type": "module",
4 | "types": "./dist/index.d.ts",
5 | "exports": "./dist/index.js"
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/stage3-decorator/src/index.ts:
--------------------------------------------------------------------------------
1 | export function logged(value, { kind, name }: ClassMethodDecoratorContext) {
2 | if (kind === 'method') {
3 | return function (...args) {
4 | console.log(`starting fn with arguments ${args.join(', ')}`)
5 | const ret = value.call(this, ...args)
6 | console.log(`ending fn`)
7 | return ret
8 | }
9 | }
10 | }
11 |
12 | export class C {
13 | @logged
14 | m() {}
15 | }
16 |
--------------------------------------------------------------------------------
/test/integration/subpath-imports/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration shared-module', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | })
8 | it('should split shared module into one chunk layer', async () => {
9 | await assertFilesContent(distDir, {
10 | 'index.js': `const dep = 'polyfill-dep'`,
11 | })
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/test/integration/subpath-imports/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "subpath-imports",
3 | "imports": {
4 | "#dep": "./src/lib/polyfill.js"
5 | },
6 | "exports": "./dist/index.js"
7 | }
8 |
--------------------------------------------------------------------------------
/test/integration/subpath-imports/src/index.js:
--------------------------------------------------------------------------------
1 | import { dep } from '#dep'
2 |
3 | export const value = dep
4 |
--------------------------------------------------------------------------------
/test/integration/subpath-imports/src/lib/polyfill.js:
--------------------------------------------------------------------------------
1 | export const dep = 'polyfill-dep'
2 |
--------------------------------------------------------------------------------
/test/integration/success-cmd/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { createJob } from '../../testing-utils'
3 |
4 | describe('integration - success arg', () => {
5 | const { job } = createJob({
6 | directory: __dirname,
7 | args: ['--success', 'node dist/index.js'],
8 | })
9 |
10 | it('should work', async () => {
11 | console.log(job.stdout + job.stderr)
12 | expect(job.code).toBe(0)
13 | expect(job.stdout).toContain('Log from --success')
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/success-cmd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "on-success",
3 | "main": "./dist/index.js",
4 | "type": "module"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/success-cmd/src/index.js:
--------------------------------------------------------------------------------
1 | function main() {
2 | console.log('Log from --success')
3 | }
4 |
5 | main()
6 |
--------------------------------------------------------------------------------
/test/integration/ts-allow-js/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import {
3 | assertContainFiles,
4 | assertFilesContent,
5 | createJob,
6 | } from '../../testing-utils'
7 |
8 | describe('integration - ts-allow-js', () => {
9 | const { distDir } = createJob({ directory: __dirname })
10 |
11 | it('should generate proper assets', async () => {
12 | const distFiles = ['index.js', 'index.d.ts']
13 | await assertContainFiles(distDir, distFiles)
14 | await assertFilesContent(distDir, {
15 | 'index.d.ts': 'declare function _default(): string;',
16 | })
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/test/integration/ts-allow-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-allow-js",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-allow-js/src/index.js:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-allow-js/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-module/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { createJob, assertContainFiles } from '../../testing-utils'
3 |
4 | describe('integration ts-dual-package-module', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should ensure generated assets', async () => {
8 | const distFiles = ['index.js', 'index.cjs']
9 | assertContainFiles(distDir, distFiles)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-module/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-dual-esm-cjs-type-module",
3 | "main": "./dist/index.js",
4 | "type": "module",
5 | "exports": {
6 | "import": "./dist/index.js",
7 | "require": "./dist/index.cjs"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-module/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-module/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-type-cjs/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { createJob, assertContainFiles } from '../../testing-utils'
3 |
4 | describe('integration ts-dual-package-type-cjs', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should ensure generated assets', async () => {
8 | await assertContainFiles(distDir, ['index.js', 'index.mjs'])
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-type-cjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-dual-package-type-cjs",
3 | "main": "./dist/index.js",
4 | "exports": {
5 | "import": "./dist/index.mjs",
6 | "require": "./dist/index.js"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-type-cjs/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-dual-package-type-cjs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-error/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { join } from 'path'
3 | import { existsSync } from 'fs'
4 | import { createJob } from '../../testing-utils'
5 |
6 | describe('integration ts-error', () => {
7 | const { distDir, job } = createJob({ directory: __dirname })
8 |
9 | it('should error when ts is not properly resolved', async () => {
10 | const { stderr } = job
11 | const distFile = join(distDir, './index.js')
12 | expect(existsSync(distFile)).toBe(false)
13 | expect(stderr).toMatch(/Could not load TypeScript compiler/)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/integration/ts-error/node_modules/typescript/index.js:
--------------------------------------------------------------------------------
1 | // typescript is not able to be loaded, expect to be warned
2 |
3 | throw new Error(`Typescript doesn't exists`)
--------------------------------------------------------------------------------
/test/integration/ts-error/src/index.ts:
--------------------------------------------------------------------------------
1 | export const a: number = 1
2 |
--------------------------------------------------------------------------------
/test/integration/ts-error/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "ESNext",
4 | "moduleResolution": "bundler"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import {
3 | assertContainFiles,
4 | createJob,
5 | assertFilesContent,
6 | } from '../../testing-utils'
7 |
8 | describe('integration - ts-exports-multiple-conditions', () => {
9 | const { distDir } = createJob({ directory: __dirname })
10 |
11 | it('should generate proper assets', async () => {
12 | const distFiles = [
13 | // entry files
14 | 'index.js',
15 | 'index.cjs',
16 | 'index.browser.js',
17 | 'index.workerd.js',
18 | 'index.edge-light.js',
19 | // types
20 | 'index.d.cts',
21 | 'index.d.ts',
22 | 'index.browser.d.ts',
23 | 'index.workerd.d.ts',
24 | 'index.edge-light.d.ts',
25 | ]
26 | assertContainFiles(distDir, distFiles)
27 | await assertFilesContent(distDir, {
28 | 'index.js': (code) => code.includes("const runtime = 'node'"),
29 | 'index.cjs': (code) => code.includes("const runtime = 'node'"),
30 | 'index.browser.js': (code) => code.includes("const runtime = 'browser'"),
31 | 'index.workerd.js': (code) => code.includes("const runtime = 'workerd'"),
32 | 'index.edge-light.js': (code) =>
33 | code.includes("const runtime = 'edge-light'"),
34 | })
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-exports-multiple-conditions",
3 | "type": "module",
4 | "types": "dist/index.d.ts",
5 | "module": "dist/index.js",
6 | "main": "dist/index.cjs",
7 | "exports": {
8 | ".": {
9 | "node": {
10 | "types": "./dist/index.d.ts",
11 | "import": "./dist/index.js",
12 | "default": "./dist/index.cjs"
13 | },
14 | "workerd": {
15 | "types": "./dist/index.workerd.d.ts",
16 | "default": "./dist/index.workerd.js"
17 | },
18 | "edge-light": {
19 | "types": "./dist/index.edge-light.d.ts",
20 | "default": "./dist/index.edge-light.js"
21 | },
22 | "browser": {
23 | "types": "./dist/index.browser.d.ts",
24 | "default": "./dist/index.browser.js"
25 | },
26 | "import": {
27 | "types": "./dist/index.d.ts",
28 | "default": "./dist/index.js"
29 | },
30 | "require": {
31 | "types": "./dist/index.d.cts",
32 | "default": "./dist/index.cjs"
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/src/index.browser.ts:
--------------------------------------------------------------------------------
1 | export const runtime = 'browser'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/src/index.edge-light.ts:
--------------------------------------------------------------------------------
1 | export const runtime = 'edge-light'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/src/index.ts:
--------------------------------------------------------------------------------
1 | export const runtime = 'node'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-multiple-conditions/src/index.workerd.ts:
--------------------------------------------------------------------------------
1 | export const runtime = 'workerd'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-types/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertContainFiles, createJob } from '../../testing-utils'
3 |
4 | describe('integration - ts-exports-types', () => {
5 | const { distDir } = createJob({ directory: __dirname })
6 |
7 | it('should generate proper assets', async () => {
8 | const distFiles = ['index.mjs', 'index.cjs', 'index.d.ts']
9 | await assertContainFiles(distDir, distFiles)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-dual-esm-cjs",
3 | "exports": {
4 | "types": "./dist/index.d.ts",
5 | "import": "./dist/index.mjs",
6 | "require": "./dist/index.cjs"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-types/src/index.ts:
--------------------------------------------------------------------------------
1 | function index(): string {
2 | return 'index'
3 | }
4 |
5 | export default index
6 |
--------------------------------------------------------------------------------
/test/integration/ts-exports-types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-condition/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration - ts-import-json-exports-condition', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | })
8 | it('should output correct bundles and types import json with export condition', async () => {
9 | await assertFilesContent(distDir, {
10 | 'index.js': '0.0.1',
11 | 'index.d.ts': 'declare const version: string',
12 | })
13 | })
14 | })
15 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-condition/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.0.1",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "types": "./dist/index.d.ts",
7 | "default": "./dist/index.js"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-condition/src/index.ts:
--------------------------------------------------------------------------------
1 | import pkgJson from '../package.json'
2 |
3 | export const version = pkgJson.version
4 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-string/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration - ts-import-json-exports-condition', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | })
8 | it('should output correct bundles and types import json with export condition', async () => {
9 | await assertFilesContent(distDir, {
10 | 'index.js': '0.0.1',
11 | 'index.d.ts': 'declare const version: string',
12 | })
13 | })
14 | })
15 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-string/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.0.1",
3 | "type": "module",
4 | "types": "./dist/index.d.ts",
5 | "exports": "./dist/index.js"
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/ts-import-json-exports-string/src/index.ts:
--------------------------------------------------------------------------------
1 | import pkgJson from '../package.json'
2 |
3 | export const version = pkgJson.version
4 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental-with-buildinfofile/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { existsSync } from 'fs'
3 | import { join } from 'path'
4 | import {
5 | assertContainFiles,
6 | assertFilesContent,
7 | createJob,
8 | } from '../../testing-utils'
9 |
10 | describe('integration - ts-incremental-with-buildinfofile', () => {
11 | const { distDir } = createJob({
12 | directory: __dirname,
13 | })
14 | it('should generate proper assets', async () => {
15 | const distFiles = ['index.js', 'index.d.ts']
16 | await assertContainFiles(distDir, distFiles)
17 | await assertFilesContent(distDir, {
18 | 'index.d.ts': 'declare const _default: () => string;',
19 | })
20 |
21 | expect(existsSync(join(distDir, '.tsbuildinfo'))).toBe(false)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental-with-buildinfofile/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-incremental-with-buildinfofile",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental-with-buildinfofile/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental-with-buildinfofile/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "incremental": true,
4 | "tsBuildInfoFile": "tsconfig.tsbuildinfo"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import { existsSync } from 'fs'
3 | import {
4 | assertContainFiles,
5 | assertFilesContent,
6 | createJob,
7 | } from '../../testing-utils'
8 | import { join } from 'path'
9 |
10 | describe('integration - ts-incremental', () => {
11 | const { distDir } = createJob({
12 | directory: __dirname,
13 | })
14 | it('should generate proper assets', async () => {
15 | const distFiles = ['index.js', 'index.d.ts']
16 |
17 | await assertContainFiles(distDir, distFiles)
18 | await assertFilesContent(distDir, {
19 | 'index.d.ts': 'declare const _default: () => string;',
20 | })
21 |
22 | expect(existsSync(join(distDir, '.tsbuildinfo'))).toBe(false)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-incremental",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-incremental/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "incremental": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-no-emit/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import {
3 | assertContainFiles,
4 | assertFilesContent,
5 | createJob,
6 | } from '../../testing-utils'
7 |
8 | describe('integration ts-no-emit', () => {
9 | const { distDir } = createJob({ directory: __dirname })
10 |
11 | it('should succeed the build', async () => {
12 | // should still emit declaration files
13 | const distFiles = ['index.js', 'index.d.ts']
14 |
15 | await assertContainFiles(distDir, distFiles)
16 | await assertFilesContent(distDir, {
17 | 'index.d.ts': 'declare const _default: () => string;',
18 | })
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/test/integration/ts-no-emit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-no-emit",
3 | "types": "./dist/index.d.ts",
4 | "exports": "./dist/index.js"
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/ts-no-emit/src/index.ts:
--------------------------------------------------------------------------------
1 | export default () => 'index'
2 |
--------------------------------------------------------------------------------
/test/integration/ts-no-emit/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noEmit": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/.gitignore:
--------------------------------------------------------------------------------
1 | !tsconfig.json
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, it } from 'vitest'
2 | import { assertFilesContent, createJob } from '../../testing-utils'
3 |
4 | describe('integration - tsconfig-override - default', () => {
5 | const { distDir } = createJob({
6 | directory: __dirname,
7 | })
8 |
9 | it('should use es5 output in build without override', async () => {
10 | await assertFilesContent(distDir, {
11 | ['index.js']: (content) => {
12 | return content.includes('function A') && !content.includes('class A')
13 | },
14 | })
15 | })
16 | })
17 |
18 | describe('integration - tsconfig-override - customized', () => {
19 | const { distDir } = createJob({
20 | directory: __dirname,
21 | args: ['--tsconfig', 'tsconfig.build.json'],
22 | })
23 |
24 | it('should use es8 output in build', async () => {
25 | await assertFilesContent(distDir, {
26 | ['index.js']: (content) => {
27 | return content.includes('class A') && !content.includes('function A')
28 | },
29 | })
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsconfig-override",
3 | "type": "module",
4 | "exports": {
5 | ".": {
6 | "default": "./dist/index.js",
7 | "types": "./dist/index.d.ts"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/src/index.ts:
--------------------------------------------------------------------------------
1 | export default class A {}
2 |
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | { "compilerOptions": { "target": "es2018" } }
2 |
--------------------------------------------------------------------------------
/test/integration/tsconfig-override/tsconfig.json:
--------------------------------------------------------------------------------
1 | { "compilerOptions": { "target": "es5" } }
2 |
--------------------------------------------------------------------------------
/test/integration/unspecified-types-paths/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest'
2 | import {
3 | assertFilesContent,
4 | createJob,
5 | getFileNamesFromDirectory,
6 | } from '../../testing-utils'
7 |
8 | describe('integration - tsconfig-override', () => {
9 | const { dir } = createJob({
10 | directory: __dirname,
11 | })
12 | it('should not generate js types paths if not specified', async () => {
13 | await assertFilesContent(dir, {
14 | './dist/subpath/nested.js': 'subpath/nested',
15 | './dist/subpath/nested.cjs': 'subpath/nested',
16 | })
17 | // No types files should be generated
18 | expect(await getFileNamesFromDirectory(dir)).toEqual([
19 | 'dist/subpath/nested.cjs',
20 | 'dist/subpath/nested.js',
21 | ])
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/integration/unspecified-types-paths/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "undefined-types-paths",
3 | "type": "module",
4 | "exports": {
5 | "./subpath/nested": {
6 | "import": "./dist/subpath/nested.js",
7 | "require": "./dist/subpath/nested.cjs"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/integration/unspecified-types-paths/src/subpath/nested.ts:
--------------------------------------------------------------------------------
1 | export const value = 'subpath/nested'
2 |
--------------------------------------------------------------------------------
/test/testing-utils/cli.ts:
--------------------------------------------------------------------------------
1 | import {
2 | createAsyncTest,
3 | executeBunchee,
4 | type ExcuteBuncheeResult,
5 | } from './shared'
6 |
7 | export async function runCli({
8 | args,
9 | options,
10 | abortTimeout,
11 | directory,
12 | }: {
13 | args?: string[]
14 | options?: { env?: NodeJS.ProcessEnv }
15 | abortTimeout?: number
16 | directory: string
17 | }) {
18 | return await createAsyncTest({
19 | directory,
20 | args: args ?? [],
21 | options: options ?? {},
22 | abortTimeout,
23 | run: executeBunchee,
24 | })
25 | }
26 |
--------------------------------------------------------------------------------
/test/testing-utils/debug.ts:
--------------------------------------------------------------------------------
1 | export function log(...args: any[]) {
2 | if (process.env.TEST_DEBUG || process.env.DEBUG) console.log(...args)
3 | }
4 |
5 | export function error(...args: any[]) {
6 | if (process.env.TEST_DEBUG || process.env.DEBUG) console.error(...args)
7 | }
8 |
--------------------------------------------------------------------------------
/test/testing-utils/index.ts:
--------------------------------------------------------------------------------
1 | import { glob } from 'fast-glob'
2 |
3 | function normalizePath(filePath: string) {
4 | return filePath.replace(/\\/g, '/')
5 | }
6 | export * from './helpers'
7 |
8 | export { runCli } from './cli'
9 | export { createJob } from './integration'
10 |
11 | export async function getFileNamesFromDirectory(directory: string) {
12 | const files = await glob(
13 | ['**/*.{,c,m}js', '**/*.{,c,m}d.ts', '**/*.{,c,m}js.map'],
14 | {
15 | cwd: directory,
16 | },
17 | )
18 |
19 | return files.sort().map((file) => normalizePath(file))
20 | }
21 |
22 | export const isWindows = process.platform === 'win32'
23 |
--------------------------------------------------------------------------------
/test/testing-utils/integration.ts:
--------------------------------------------------------------------------------
1 | import {
2 | createSyncTest,
3 | executeBunchee,
4 | type ExcuteBuncheeResult,
5 | } from './shared'
6 |
7 | type IntegrationTestOptions = {
8 | args?: string[]
9 | options?: { env?: NodeJS.ProcessEnv }
10 | abortTimeout?: number
11 | directory: string
12 | }
13 |
14 | /** Sync testing helper */
15 | export function createJob({
16 | args,
17 | options,
18 | abortTimeout,
19 | directory,
20 | }: IntegrationTestOptions) {
21 | return createSyncTest({
22 | args: args ?? [],
23 | options: options ?? {},
24 | abortTimeout,
25 | directory,
26 | run: executeBunchee,
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "module": "ESNext",
5 | "target": "ESNext",
6 | "strict": false,
7 | "noUnusedLocals": false,
8 | "jsx": "preserve",
9 | "baseUrl": "..",
10 | "paths": {
11 | "bunchee": ["./src/index.ts"],
12 | "testing-utils": ["./test/testing-utils/index.ts"]
13 | }
14 | },
15 | "include": [
16 | "./**/*.test.ts",
17 | "./**/*.test.tsx",
18 | "./testing-utils",
19 | "../src/**/*.test.ts",
20 | "../src/**/*.test.tsx"
21 | ],
22 | "references": [{ "path": "../tsconfig.json" }]
23 | }
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "rootDir": ".",
5 | "outDir": "./dist",
6 | "target": "ES2019",
7 | "module": "CommonJS",
8 | "lib": ["ES2019"],
9 | "moduleResolution": "node",
10 | "removeComments": true,
11 | "strict": true,
12 | "noUnusedLocals": true,
13 | "noImplicitReturns": true,
14 | "resolveJsonModule": true,
15 | "esModuleInterop": true,
16 | "skipLibCheck": true,
17 | "forceConsistentCasingInFileNames": true
18 | },
19 | "references": [{ "path": "./test/tsconfig.json" }],
20 | "include": ["src", "**/*.json"],
21 | "exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
22 | }
23 |
--------------------------------------------------------------------------------
/vitest.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitest/config'
2 |
3 | export default defineConfig({
4 | test: {
5 | environment: 'node',
6 |
7 | alias: {
8 | '^bunchee$': '/src/index.ts', // Adjusted to use absolute paths
9 | },
10 |
11 | exclude: [
12 | '**/node_modules/**',
13 | '**/test/integration/**/src/**',
14 | '**/test/fixtures/**',
15 | ],
16 | // Test timeout
17 | testTimeout: 60 * 1000,
18 | hookTimeout: 20 * 1000,
19 | },
20 | resolve: {
21 | conditions: ['import', 'default'], // Prefer ES modules if available
22 | },
23 | })
24 |
--------------------------------------------------------------------------------