├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── README.md ├── docs ├── app │ ├── globals.css │ ├── layout.tsx │ ├── opengraph-image.png │ └── page.tsx ├── next-env.d.ts ├── public │ └── llms.txt └── tsconfig.json ├── examples ├── basic-ts │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── react.tsx │ └── tsconfig.json ├── basic │ ├── package.json │ └── src │ │ └── index.js ├── custom-jsx │ ├── package.json │ ├── src │ │ └── index.tsx │ └── tsconfig.json ├── esm │ ├── package.json │ └── src │ │ └── index.js └── server-actions │ ├── package.json │ ├── src │ ├── action.ts │ ├── client.tsx │ └── inline.tsx │ └── tsconfig.json ├── package.json ├── pnpm-lock.yaml ├── scripts └── new-test.js ├── src ├── bin │ └── index.ts ├── build-config.ts ├── bundle.ts ├── constants.ts ├── entries.ts ├── env.ts ├── exports.ts ├── index.ts ├── lib │ ├── file-match.test.ts │ ├── file-match.ts │ ├── format.ts │ ├── memoize.test.ts │ ├── memoize.ts │ └── normalize-error.ts ├── lint.ts ├── logger.ts ├── plugins │ ├── alias-plugin.ts │ ├── esm-shim.test.ts │ ├── esm-shim.ts │ ├── inline-css.ts │ ├── output-state-plugin.ts │ ├── prepend-shebang.ts │ └── raw-plugin.ts ├── prepare │ ├── index.ts │ └── prepare-entries.ts ├── rollup-job.ts ├── rollup │ ├── input.ts │ ├── output.ts │ └── split-chunks.ts ├── types.ts ├── typescript.ts ├── typing.test.ts ├── util │ ├── file-path.test.ts │ └── file-path.ts └── utils.ts ├── test ├── cli │ ├── basic │ │ ├── hello.js │ │ └── index.test.ts │ ├── cjs-relative-imports │ │ ├── cjs-dep.cjs │ │ ├── index.js │ │ ├── index.test.ts │ │ └── js-dep.js │ ├── dts-bundle │ │ ├── .gitignore │ │ ├── base.ts │ │ ├── index.test.ts │ │ └── tsconfig.json │ ├── dts │ │ ├── index.test.ts │ │ └── input.ts │ ├── env-var │ │ ├── index.js │ │ └── index.test.ts │ ├── externals │ │ ├── index.test.ts │ │ └── with-externals.js │ ├── no-dts │ │ ├── base.ts │ │ └── index.test.ts │ ├── no-entry │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── no-entry.txt │ ├── output-in-watch │ │ ├── hello.js │ │ └── index.test.ts │ ├── single-entry-js │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── target │ │ ├── es2020.ts │ │ └── index.test.ts │ └── workspace │ │ ├── index.test.ts │ │ ├── index.ts │ │ └── package.json ├── compile.test.ts ├── compile │ ├── es-advance │ │ ├── __snapshot__ │ │ │ ├── es-advance.js.snapshot │ │ │ └── es-advance.min.js.snapshot │ │ └── input.js │ ├── es-basic │ │ ├── __snapshot__ │ │ │ ├── es-basic.js.snapshot │ │ │ └── es-basic.min.js.snapshot │ │ └── input.js │ ├── jsx-preserve │ │ ├── __snapshot__ │ │ │ ├── jsx-preserve.d.ts.snapshot │ │ │ ├── jsx-preserve.js.snapshot │ │ │ ├── jsx-preserve.min.d.ts.snapshot │ │ │ └── jsx-preserve.min.js.snapshot │ │ ├── input.tsx │ │ └── tsconfig.json │ ├── jsx-react-automatic │ │ ├── __snapshot__ │ │ │ ├── jsx-react-automatic.d.ts.snapshot │ │ │ ├── jsx-react-automatic.js.snapshot │ │ │ ├── jsx-react-automatic.min.d.ts.snapshot │ │ │ └── jsx-react-automatic.min.js.snapshot │ │ ├── input.tsx │ │ ├── package.json │ │ └── tsconfig.json │ ├── jsx │ │ ├── __snapshot__ │ │ │ ├── jsx.js.snapshot │ │ │ └── jsx.min.js.snapshot │ │ └── input.jsx │ ├── module │ │ ├── __snapshot__ │ │ │ ├── module.js.snapshot │ │ │ └── module.min.js.snapshot │ │ ├── a.js │ │ ├── b.js │ │ └── input.js │ ├── shebang │ │ ├── __snapshot__ │ │ │ ├── shebang.js.snapshot │ │ │ └── shebang.min.js.snapshot │ │ └── input.js │ ├── sub-folder-import │ │ ├── __snapshot__ │ │ │ ├── sub-folder-import.js.snapshot │ │ │ └── sub-folder-import.min.js.snapshot │ │ ├── input.js │ │ └── package.json │ ├── treeshake │ │ ├── __snapshot__ │ │ │ ├── treeshake.js.snapshot │ │ │ └── treeshake.min.js.snapshot │ │ └── input.js │ ├── ts-basic │ │ ├── __snapshot__ │ │ │ ├── ts-basic.d.ts.snapshot │ │ │ ├── ts-basic.js.snapshot │ │ │ ├── ts-basic.min.d.ts.snapshot │ │ │ └── ts-basic.min.js.snapshot │ │ ├── input.ts │ │ ├── math.ts │ │ └── tsconfig.json │ ├── ts-interop │ │ ├── __snapshot__ │ │ │ ├── ts-interop.d.ts.snapshot │ │ │ ├── ts-interop.js.snapshot │ │ │ ├── ts-interop.min.d.ts.snapshot │ │ │ └── ts-interop.min.js.snapshot │ │ ├── input.ts │ │ ├── package.json │ │ ├── tsconfig.base.json │ │ └── tsconfig.json │ ├── ts-target-es2018 │ │ ├── __snapshot__ │ │ │ ├── ts-target-es2018.d.ts.snapshot │ │ │ ├── ts-target-es2018.js.snapshot │ │ │ ├── ts-target-es2018.min.d.ts.snapshot │ │ │ └── ts-target-es2018.min.js.snapshot │ │ ├── input.ts │ │ └── tsconfig.json │ ├── tsx-css-global │ │ ├── __snapshot__ │ │ │ ├── tsx-css-global.d.ts.snapshot │ │ │ ├── tsx-css-global.js.snapshot │ │ │ ├── tsx-css-global.min.d.ts.snapshot │ │ │ └── tsx-css-global.min.js.snapshot │ │ ├── input.tsx │ │ ├── style.css │ │ └── tsconfig.json │ ├── tsx │ │ ├── __snapshot__ │ │ │ ├── env.d.ts │ │ │ ├── tsx.d.ts.snapshot │ │ │ ├── tsx.js.snapshot │ │ │ ├── tsx.min.d.ts.snapshot │ │ │ └── tsx.min.js.snapshot │ │ ├── env.d.ts │ │ ├── foo.tsx │ │ ├── input.tsx │ │ ├── package.json │ │ └── tsconfig.json │ └── use-client │ │ ├── __snapshot__ │ │ ├── use-client.js.snapshot │ │ └── use-client.min.js.snapshot │ │ ├── client.js │ │ └── input.js ├── fixtures │ └── integration-test-template │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ └── index.js ├── integration │ ├── basic-jsx │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── bin │ │ ├── cts │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── bin │ │ │ │ └── index.cts │ │ ├── multi-path │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── bin │ │ │ │ ├── a.ts │ │ │ │ └── b.ts │ │ ├── patch-binary │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── bin │ │ │ │ └── index.ts │ │ └── single-path │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ └── bin │ │ │ └── index.ts │ ├── browserslist │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── conflicted-entry │ │ ├── conflicted-entry.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── foo.ts │ │ │ └── foo │ │ │ └── index.jsx │ ├── default-default-export-different-ext │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── a.ts │ │ │ ├── b.ts │ │ │ └── c.ts │ ├── default-default-export │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── a.ts │ │ │ ├── b.ts │ │ │ └── c.ts │ ├── default-node-mjs │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── dev-prod-convention-reexport │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── core.ts │ │ │ └── index.ts │ ├── dev-prod-convention │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── dev-prod-nested-convention │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── core.development.ts │ │ │ ├── core.production.ts │ │ │ ├── core.ts │ │ │ ├── index.development.ts │ │ │ ├── index.production.ts │ │ │ └── index.ts │ ├── dev-prod-special-convention │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── index.react-server.ts │ │ │ └── index.ts │ ├── duplicate-entries-partial-specified │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── a.ts │ │ │ ├── a.workerd.ts │ │ │ └── a │ │ │ └── shared.ts │ ├── dynamic-require │ │ ├── dynamic-require.test.ts │ │ ├── node_modules │ │ │ └── external-lib │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ ├── package.json │ │ └── src │ │ │ ├── foo.js │ │ │ ├── index.js │ │ │ └── required-module.js │ ├── edge-variable │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── entry-index-index │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index │ │ │ ├── index.js │ │ │ └── index.react-server.js │ ├── errors │ │ └── compile-error │ │ │ ├── package.json │ │ │ └── src │ │ │ └── index.tsx │ ├── esm-pkg-cjs-main-field │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── esm-shims │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── custom-require.js │ │ │ ├── dirname.js │ │ │ ├── filename.js │ │ │ └── require.js │ ├── exports-order │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── a.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ ├── externals │ │ ├── index.test.ts │ │ ├── node_modules │ │ │ ├── .modules.yaml │ │ │ ├── peer-dep-meta │ │ │ │ └── index.js │ │ │ └── peer-dep │ │ │ │ └── index.js │ │ ├── package.json │ │ ├── src │ │ │ └── index.js │ │ └── sub-export.js │ ├── import-fallback │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── a │ │ │ └── index.edge-light.js │ │ │ └── b.js │ ├── js-bad-configured-types │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── js-only │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── lint │ │ ├── cjs-pkg-esm-main-field │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── index.js │ │ ├── invalid-exports-cjs │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ ├── foo.js │ │ │ │ └── index.js │ │ ├── invalid-exports-esm │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ ├── foo.js │ │ │ │ └── index.js │ │ ├── missing-files-exports │ │ │ ├── foo │ │ │ │ └── index.js │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ ├── foo.js │ │ │ │ └── index.js │ │ ├── missing-files-main │ │ │ ├── index.js │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ │ └── index.js │ │ └── single-entry │ │ │ ├── .gitignore │ │ │ ├── index.test.ts │ │ │ ├── package.json │ │ │ └── src │ │ │ └── index.ts │ ├── missing-entry-file │ │ ├── missing-entry-file.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── bar.js.missing │ │ │ ├── foo.js.missing │ │ │ └── index.js │ ├── mixed-directives │ │ ├── .gitignore │ │ ├── mixed-directives.test.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── action.ts │ │ │ ├── client.tsx │ │ │ └── inline.tsx │ │ └── tsconfig.json │ ├── monorepo-composite-no-incremental │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── packages │ │ │ └── a │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ └── index.ts │ │ │ │ └── tsconfig.json │ │ └── tsconfig.json │ ├── monorepo-composite │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── packages │ │ │ └── a │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ └── index.ts │ │ │ │ └── tsconfig.json │ │ └── tsconfig.json │ ├── multi-entries │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── client.ts │ │ │ ├── index.ts │ │ │ ├── lite.ts │ │ │ ├── server │ │ │ ├── index.edge-light.ts │ │ │ ├── index.react-server.ts │ │ │ └── index.ts │ │ │ ├── shared.edge-light.ts │ │ │ └── shared.ts │ ├── multi-exports-ts │ │ ├── .gitignore │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── foo.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ ├── multi-types │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── nested-exports │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── foo │ │ │ └── bar.js │ ├── no-clean │ │ ├── .gitignore │ │ ├── index.test.ts │ │ ├── no-clean.json │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── no-entry │ │ └── src │ │ │ ├── no-entry.txt │ │ │ └── style.css │ ├── node-mixed-legacy-modern-entries │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── output-short │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── output │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── bin │ │ │ └── cli.js │ │ │ ├── foo.js │ │ │ ├── index.js │ │ │ └── index.react-server.js │ ├── pkg-exports-default │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── pkg-exports-js │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── pkg-exports-ts-rsc │ │ ├── .gitignore │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── api │ │ │ ├── index.react-server.ts │ │ │ └── index.ts │ │ │ ├── index.react-native.ts │ │ │ ├── index.react-server.ts │ │ │ └── index.ts │ ├── prepare-js │ │ ├── .gitignore │ │ ├── index.test.ts │ │ └── src │ │ │ ├── bin.js │ │ │ ├── foo.js │ │ │ └── index.js │ ├── prepare-ts-with-pkg-json │ │ ├── .gitignore │ │ ├── index.test.ts │ │ └── src │ │ │ └── index.ts │ ├── prepare-ts-with-test-file │ │ ├── .gitignore │ │ ├── index.test.ts │ │ └── src │ │ │ ├── foo.spec.ts │ │ │ ├── index.test.ts │ │ │ └── index.ts │ ├── prepare-ts │ │ ├── .gitignore │ │ ├── index.test.ts │ │ └── src │ │ │ ├── bin │ │ │ ├── cli.ts │ │ │ └── cmd.ts │ │ │ ├── foo.ts │ │ │ ├── index.react-server.ts │ │ │ └── index.ts │ ├── raw-data │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── content.txt │ │ │ └── index.js │ ├── relative-entry │ │ ├── package.json │ │ ├── relative-entry.test.ts │ │ └── src │ │ │ ├── index.js │ │ │ └── relative.js │ ├── server-components-same-layer │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── _client.js │ │ │ └── index.js │ ├── server-components │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── index.js │ │ │ ├── mod_actions.js │ │ │ ├── mod_asset.js │ │ │ ├── mod_client.js │ │ │ └── ui.js │ ├── shared-any-module │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── _internal │ │ │ ├── __mocks__ │ │ │ │ └── a.mock.js │ │ │ ├── run-tests.spec.js │ │ │ ├── util-a.ts │ │ │ └── util-b.ts │ │ │ ├── export-a.js │ │ │ ├── export-b.js │ │ │ ├── export-c.js │ │ │ └── private │ │ │ └── _nested │ │ │ └── util-c.ts │ ├── shared-entry │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── script.js │ │ └── src │ │ │ ├── index.js │ │ │ ├── shared.js │ │ │ └── sub │ │ │ └── foo.js │ ├── shared-module-special-condition │ │ ├── package.json │ │ ├── shared-module-special-condition.test.ts │ │ └── src │ │ │ ├── _util.ts │ │ │ └── index.ts │ ├── shared-module-ts-esm │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── _util.ts │ │ │ └── index.ts │ ├── shared-module-ts │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── another.ts │ │ │ ├── index.react-server.ts │ │ │ ├── index.ts │ │ │ └── lib │ │ │ ├── _app-context.ts │ │ │ └── _util.ts │ ├── shared-module-with-suffix │ │ ├── package.json │ │ ├── shared-module-with-suffix.test.ts │ │ └── src │ │ │ ├── _private │ │ │ └── util.browser.ts │ │ │ └── client │ │ │ └── index.ts │ ├── shared-module │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── _internal │ │ │ ├── index.js │ │ │ └── index.react-server.js │ │ │ ├── another.js │ │ │ ├── client.js │ │ │ ├── index.js │ │ │ ├── index.react-server.js │ │ │ └── lib │ │ │ ├── _app-context.js │ │ │ └── _util.js │ ├── sourcemap-dts │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── split-common-chunks │ │ ├── .gitignore │ │ ├── package.json │ │ ├── split-common-chunks.test.ts │ │ ├── src │ │ │ ├── bar.ts │ │ │ ├── foo.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── stage3-decorator │ │ ├── .gitignore │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── subpath-imports │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── index.js │ │ │ └── lib │ │ │ └── polyfill.js │ ├── success-cmd │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.js │ ├── ts-allow-js │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.js │ │ └── tsconfig.json │ ├── ts-dual-package-module │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-dual-package-type-cjs │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-error │ │ ├── index.test.ts │ │ ├── node_modules │ │ │ └── typescript │ │ │ │ └── index.js │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-exports-multiple-conditions │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ ├── index.browser.ts │ │ │ ├── index.edge-light.ts │ │ │ ├── index.ts │ │ │ └── index.workerd.ts │ ├── ts-exports-types │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-import-json-exports-condition │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── ts-import-json-exports-string │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ │ └── index.ts │ ├── ts-incremental-with-buildinfofile │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-incremental │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── ts-no-emit │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── tsconfig-override │ │ ├── .gitignore │ │ ├── index.test.ts │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ ├── tsconfig.build.json │ │ └── tsconfig.json │ └── unspecified-types-paths │ │ ├── index.test.ts │ │ ├── package.json │ │ └── src │ │ └── subpath │ │ └── nested.ts ├── testing-utils │ ├── cli.ts │ ├── debug.ts │ ├── helpers.ts │ ├── index.ts │ ├── integration.ts │ └── shared.ts └── tsconfig.json ├── tsconfig.json └── vitest.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | node_modules 3 | dist 4 | *.log 5 | .yalc 6 | yalc.lock 7 | test/**/*.js.map 8 | .DS_Store 9 | test/**/tsconfig.json 10 | test/**/*.d.* 11 | !test/**/node_modules 12 | .next 13 | .vscode 14 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml 2 | README.md 3 | test/integration/errors 4 | -------------------------------------------------------------------------------- /docs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Geist, Geist_Mono } from 'next/font/google' 2 | import './globals.css' 3 | 4 | const geistSans = Geist({ 5 | variable: '--font-geist-sans', 6 | subsets: ['latin'], 7 | }) 8 | 9 | const geistMono = Geist_Mono({ 10 | variable: '--font-geist-mono', 11 | subsets: ['latin'], 12 | }) 13 | 14 | import React from 'react' 15 | import './globals.css' 16 | 17 | export default function Layout({ children }) { 18 | return ( 19 | 20 | 21 | {children} 22 | 23 | 24 | ) 25 | } 26 | 27 | export const metadata = { 28 | title: 'Bunchee', 29 | description: 'Zero-config bundler for npm packages', 30 | } 31 | -------------------------------------------------------------------------------- /docs/app/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/docs/app/opengraph-image.png -------------------------------------------------------------------------------- /docs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "noEmit": true, 9 | "incremental": true, 10 | "module": "esnext", 11 | "esModuleInterop": true, 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ] 21 | }, 22 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/basic-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic-ts", 3 | "version": "0.0.1", 4 | "main": "./dist/index.js", 5 | "exports": { 6 | ".": { 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 | "scripts": { 18 | "build": "bunchee" 19 | }, 20 | "peerDependencies": { 21 | "react": "*" 22 | }, 23 | "devDependencies": { 24 | "bunchee": "latest", 25 | "react": "latest" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/basic-ts/src/index.ts: -------------------------------------------------------------------------------- 1 | export function foo(): string { 2 | return 'foo' 3 | } 4 | -------------------------------------------------------------------------------- /examples/basic-ts/src/react.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export function MyComponent() { 4 | return Custom Component 5 | } 6 | -------------------------------------------------------------------------------- /examples/basic-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic", 3 | "version": "0.0.1", 4 | "main": "./dist/index.js", 5 | "exports": { 6 | ".": { 7 | "import": "./dist/index.mjs", 8 | "require": "./dist/index.js" 9 | } 10 | }, 11 | "scripts": { 12 | "build": "bunchee" 13 | }, 14 | "devDependencies": { 15 | "bunchee": "latest" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/basic/src/index.js: -------------------------------------------------------------------------------- 1 | export function foo() { 2 | return 'foo' 3 | } 4 | -------------------------------------------------------------------------------- /examples/custom-jsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-jsx", 3 | "version": "0.0.1", 4 | "main": "./dist/index.js", 5 | "exports": { 6 | ".": { 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 | "scripts": { 18 | "build": "bunchee" 19 | }, 20 | "peerDependencies": { 21 | "vue": "*" 22 | }, 23 | "devDependencies": { 24 | "bunchee": "latest", 25 | "vue": "latest" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/custom-jsx/src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as Vue from 'vue' 2 | 3 | export const Spinner = Vue.defineComponent(() => () => { 4 | return
loading
5 | }) 6 | -------------------------------------------------------------------------------- /examples/custom-jsx/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "moduleResolution": "Bundler", 5 | // Customized JSX for Vue 6 | "jsx": "preserve", 7 | "jsxFactory": "Vue.h", 8 | "jsxImportSource": "vue" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esm", 3 | "version": "0.0.1", 4 | "type": "module", 5 | "main": "./dist/index.js", 6 | "exports": { 7 | ".": { 8 | "import": "./dist/index.js", 9 | "require": "./dist/index.cjs" 10 | } 11 | }, 12 | "scripts": { 13 | "build": "bunchee" 14 | }, 15 | "devDependencies": { 16 | "bunchee": "latest" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/esm/src/index.js: -------------------------------------------------------------------------------- 1 | export function foo() { 2 | return 'foo' 3 | } 4 | -------------------------------------------------------------------------------- /examples/server-actions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server-actions-example", 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 | "devDependencies": { 15 | "@types/react": "latest" 16 | }, 17 | "peerDependencies": { 18 | "react": "^18 || ^19" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/server-actions/src/action.ts: -------------------------------------------------------------------------------- 1 | 'use server' 2 | 3 | export async function action1() { 4 | return 'action1' 5 | } 6 | -------------------------------------------------------------------------------- /examples/server-actions/src/client.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { action1 } from './action' 4 | 5 | export default function Page() { 6 | return 7 | } 8 | -------------------------------------------------------------------------------- /examples/server-actions/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 | -------------------------------------------------------------------------------- /examples/server-actions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ES6", 4 | "moduleResolution": "node", 5 | "jsx": "react-jsx", 6 | "target": "ES2022" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/env.ts: -------------------------------------------------------------------------------- 1 | import { ParsedExportCondition } from './types' 2 | 3 | /** 4 | * @return {Record} env { 'process.env.': '' } 5 | */ 6 | export function getDefinedInlineVariables( 7 | envs: string[], 8 | parsedExportCondition: ParsedExportCondition, 9 | ): Record { 10 | const envVars = envs.reduce((acc: Record, key) => { 11 | const value = process.env[key] 12 | if (typeof value !== 'undefined') { 13 | acc['process.env.' + key] = JSON.stringify(value) 14 | } 15 | return acc 16 | }, {}) 17 | 18 | const exportConditionNames = Object.keys(parsedExportCondition.export).reduce( 19 | (acc, key) => { 20 | // key could be 'require' or 'import.development' etc. 21 | const exportTypes = key.split('.') 22 | for (const exportType of exportTypes) { 23 | acc.add(exportType) 24 | } 25 | return acc 26 | }, 27 | new Set() as Set, 28 | ) 29 | 30 | // For development and production convention, we override the NODE_ENV value 31 | if (exportConditionNames.has('development')) { 32 | envVars['process.env.NODE_ENV'] = JSON.stringify('development') 33 | } else if (exportConditionNames.has('production')) { 34 | envVars['process.env.NODE_ENV'] = JSON.stringify('production') 35 | } 36 | 37 | if (exportConditionNames.has('edge-light')) { 38 | envVars['EdgeRuntime'] = JSON.stringify('edge-runtime') 39 | } 40 | 41 | return envVars 42 | } 43 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export type { BundleConfig } from './types' 2 | export { default as bundle } from './bundle' 3 | -------------------------------------------------------------------------------- /src/lib/file-match.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { matchFile } from './file-match' 3 | 4 | describe('matchFile', () => { 5 | it('posix', () => { 6 | // Generate few different cases for the matchFile function 7 | expect(matchFile(['dist'], './dist/index.js')).toBe(true) 8 | expect(matchFile(['dist'], './dist/index.d.ts')).toBe(true) 9 | 10 | // Match file outside of the dist folder 11 | expect(matchFile(['dist'], './src/index.js')).toBe(false) 12 | expect(matchFile(['dist'], './src/index.d.ts')).toBe(false) 13 | 14 | // Match nested 15 | expect(matchFile(['dist/**/nested'], './dist/foo/nested/index.js')).toBe( 16 | true, 17 | ) 18 | expect(matchFile(['dist/**/nested'], './dist/foo/index.js')).toBe(false) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /src/lib/file-match.ts: -------------------------------------------------------------------------------- 1 | import { posix } from 'path' 2 | import picomatch from 'picomatch' 3 | 4 | export const matchFile = (matchingPattern: string[], filePath: string) => { 5 | return matchingPattern.some((pattern) => { 6 | // pattern is always posix 7 | const normalizedPattern = posix.normalize(pattern) 8 | const expandedPattern = normalizedPattern.endsWith('/') 9 | ? `${normalizedPattern}**` 10 | : `${normalizedPattern}/**` 11 | 12 | const matcher = picomatch(expandedPattern) 13 | 14 | const normalizedFilePath = posix.normalize(filePath) 15 | return matcher(normalizedFilePath) 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /src/lib/format.ts: -------------------------------------------------------------------------------- 1 | import { sep } from 'path' 2 | 3 | export function posixRelativify(path: string) { 4 | return path.startsWith('.') ? path : `./${path}` 5 | } 6 | 7 | export function platformRelativify(path: string) { 8 | return path.startsWith('.') ? path : `.${sep}${path}` 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/memoize.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest' 2 | import { memoizeByKey } from './memoize' 3 | 4 | describe('memoize', () => { 5 | it('should memoize the function by default based on arg', () => { 6 | const fn = vi.fn((a: number, b: number) => a + b) 7 | const memoized = memoizeByKey(fn)() 8 | expect(memoized(1, 2)).toBe(3) 9 | expect(memoized(1, 2)).toBe(3) 10 | expect(fn).toBeCalledTimes(1) 11 | expect(memoized(1, 5)).toBe(6) 12 | expect(fn).toBeCalledTimes(2) 13 | }) 14 | 15 | it('should memoize based on the string key resolver', () => { 16 | const fn = vi.fn((a: number, b: number) => a + b) 17 | const memoized = memoizeByKey(fn)('key') 18 | expect(memoized(1, 2)).toBe(3) 19 | expect(memoized(1, 2)).toBe(3) 20 | expect(memoized(1, 5)).toBe(3) // still cache since the key is the same 21 | expect(fn).toBeCalledTimes(1) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /src/lib/memoize.ts: -------------------------------------------------------------------------------- 1 | type CacheKeyResolver = string | ((...args: any[]) => string) 2 | 3 | const createMemoize = any>( 4 | fn: T, 5 | cacheKey?: CacheKeyResolver, // if you need specify a cache key 6 | cacheArg?: Map>, 7 | ) => { 8 | const cache: Map> = cacheArg || new Map() 9 | return ((...args: Parameters) => { 10 | const key = cacheKey 11 | ? typeof cacheKey === 'function' 12 | ? cacheKey(...args) 13 | : cacheKey 14 | : JSON.stringify({ args }) 15 | const existing = cache.get(key) 16 | if (existing !== undefined) { 17 | return existing 18 | } 19 | const result = fn(...args) 20 | cache.set(key, result) 21 | return result 22 | }) as T 23 | } 24 | 25 | export const memoizeByKey = any>(fn: T) => { 26 | const cache = new Map>() 27 | return (cacheKey?: CacheKeyResolver) => createMemoize(fn, cacheKey, cache) 28 | } 29 | 30 | export const memoize = any>(fn: T) => 31 | createMemoize(fn) 32 | -------------------------------------------------------------------------------- /src/lib/normalize-error.ts: -------------------------------------------------------------------------------- 1 | export function normalizeError(error: any) { 2 | // Remove the noise from rollup plugin error 3 | if (error.code === 'PLUGIN_ERROR') { 4 | const normalizedError = new Error(error.message) 5 | normalizedError.stack = error.stack 6 | error = normalizedError 7 | } 8 | return error 9 | } 10 | -------------------------------------------------------------------------------- /src/logger.ts: -------------------------------------------------------------------------------- 1 | import pc from 'picocolors' 2 | 3 | const defaultColorFn = (text: string) => text 4 | function color(prefixColor: any) { 5 | return pc.isColorSupported ? (pc as any)[prefixColor] : defaultColorFn 6 | } 7 | 8 | export const logger = { 9 | log(...arg: any[]) { 10 | console.log(...arg) 11 | }, 12 | warn(...arg: any[]) { 13 | console.warn(color('yellow')('!'), ...arg) 14 | }, 15 | error(...arg: any) { 16 | console.error(color('red')('⨯'), ...arg) 17 | }, 18 | info(...arg: any) { 19 | console.log(color('green')('✓'), ...arg) 20 | }, 21 | } 22 | 23 | export function paint(prefix: string, prefixColor: any, ...arg: any[]) { 24 | if (pc.isColorSupported) { 25 | console.log((pc as any)[prefixColor](prefix), ...arg) 26 | } else { 27 | console.log(prefix, ...arg) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/plugins/esm-shim.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { GLOBAL_REQUIRE_REGEX } from './esm-shim' 3 | 4 | describe('require regex', () => { 5 | const match = (code: string) => GLOBAL_REQUIRE_REGEX.test(code) 6 | it('should match require', () => { 7 | expect(match('require("foo")')).toBe(true) 8 | expect(match('require(\n"foo"\n)')).toBe(true) 9 | expect(match(`require(\`mod\`)`)).toBe(true) 10 | expect(match(`require.resolve('mod')`)).toBe(true) 11 | expect(match(`\nrequire.resolve(value)`)).toBe(true) 12 | 13 | expect(match('foo.require("foo")')).toBe(false) 14 | expect(match(`"require('module')"`)).toBe(false) 15 | expect(match(`\`require('module')\``)).toBe(false) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /src/plugins/prepend-shebang.ts: -------------------------------------------------------------------------------- 1 | import MagicString from 'magic-string' 2 | import type { Plugin } from 'rollup' 3 | 4 | export const prependShebang = (entry: string): Plugin => ({ 5 | name: 'prependShebang', 6 | transform: (code: string, id: string) => { 7 | if (id !== entry) return 8 | const shebang = '#!/usr/bin/env node\n' 9 | if (code.startsWith(shebang)) return 10 | const magicString = new MagicString(code) 11 | magicString.prepend(shebang) 12 | return { 13 | code: magicString.toString(), 14 | map: magicString.generateMap({ hires: true }), 15 | } 16 | }, 17 | }) 18 | -------------------------------------------------------------------------------- /src/plugins/raw-plugin.ts: -------------------------------------------------------------------------------- 1 | import { type FilterPattern, createFilter } from '@rollup/pluginutils' 2 | import type { Plugin } from 'rollup' 3 | 4 | export function rawContent({ exclude }: { exclude: FilterPattern }): Plugin { 5 | const filter = createFilter(['**/*.data', '**/*.txt'], exclude) 6 | 7 | return { 8 | name: 'string', 9 | 10 | transform(code, id) { 11 | if (filter(id)) { 12 | return { 13 | code: `const data = ${JSON.stringify(code)};\nexport default data;`, 14 | map: null, 15 | } 16 | } 17 | return null 18 | }, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/typing.test.ts: -------------------------------------------------------------------------------- 1 | // Import from generated files instead of using tsconfig alias 2 | import { describe, it } from 'vitest' 3 | 4 | import { bundle, type BundleConfig } from './index' 5 | 6 | describe('types', () => { 7 | it('should be able to import the node API and use correct typings', async () => { 8 | const options: BundleConfig = { 9 | dts: false, 10 | watch: false, 11 | minify: false, 12 | sourcemap: false, 13 | external: [], 14 | format: 'esm', 15 | target: 'es2015', 16 | runtime: 'nodejs', 17 | } 18 | 19 | return () => bundle('./tmp/index.ts', options) 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /test/cli/basic/hello.js: -------------------------------------------------------------------------------- 1 | function sayHello() { 2 | const val = 'hello' 3 | console.log(val) 4 | return val 5 | } 6 | 7 | export default sayHello 8 | export const world = 'world' 9 | -------------------------------------------------------------------------------- /test/cli/cjs-relative-imports/cjs-dep.cjs: -------------------------------------------------------------------------------- 1 | module.exports = 'dot-cjs-dep' 2 | -------------------------------------------------------------------------------- /test/cli/cjs-relative-imports/index.js: -------------------------------------------------------------------------------- 1 | const jsDep = require('./js-dep') 2 | const cjsDep = require('./cjs-dep') 3 | 4 | exports.jsDep = jsDep 5 | exports.cjsDep = cjsDep 6 | -------------------------------------------------------------------------------- /test/cli/cjs-relative-imports/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import fs from 'fs' 3 | import { runCli } from '../../testing-utils' 4 | 5 | test(`cli cjs-relative-imports should work properly`, async () => { 6 | const { code, distFile } = await runCli({ 7 | directory: __dirname, 8 | args: ['index.js', '-o', 'dist/index.js'], 9 | }) 10 | expect(code).toBe(0) 11 | 12 | const content = fs.readFileSync(distFile, { encoding: 'utf-8' }) 13 | 14 | expect(content.includes('dot-js-dep')).toBe(true) 15 | expect(content.includes('dot-cjs-dep')).toBe(true) 16 | }) 17 | -------------------------------------------------------------------------------- /test/cli/cjs-relative-imports/js-dep.js: -------------------------------------------------------------------------------- 1 | module.exports = 'dot-js-dep' 2 | -------------------------------------------------------------------------------- /test/cli/dts-bundle/.gitignore: -------------------------------------------------------------------------------- 1 | !tsconfig.json -------------------------------------------------------------------------------- /test/cli/dts-bundle/base.ts: -------------------------------------------------------------------------------- 1 | import { ParserConfig } from '@swc/types' 2 | 3 | export const createParser = (options: ParserConfig) => { 4 | // noop 5 | } 6 | -------------------------------------------------------------------------------- /test/cli/dts-bundle/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "ESNext", 5 | "moduleResolution": "bundler" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/cli/dts/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import fs from 'fs' 3 | import path from 'path' 4 | import { runCli } from '../../testing-utils' 5 | 6 | describe('cli', () => { 7 | it(`cli dts should work properly`, async () => { 8 | const { code, distFile } = await runCli({ 9 | directory: __dirname, 10 | args: ['./input.ts', '-o', 'dist/output.js'], 11 | }) 12 | const typeFile = distFile.replace('.js', '.d.ts') 13 | 14 | expect(path.basename(distFile)).toBe('output.js') 15 | expect(path.basename(typeFile)).toBe('output.d.ts') 16 | expect(fs.existsSync(distFile)).toBe(true) 17 | expect(fs.existsSync(typeFile)).toBe(true) 18 | expect(code).toBe(0) 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/cli/dts/input.ts: -------------------------------------------------------------------------------- 1 | export default 'base' 2 | -------------------------------------------------------------------------------- /test/cli/env-var/index.js: -------------------------------------------------------------------------------- 1 | export const myTestEnv = process.env.MY_TEST_ENV 2 | -------------------------------------------------------------------------------- /test/cli/env-var/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import fs from 'fs' 3 | import { runCli } from '../../testing-utils' 4 | 5 | test(`cli env-var should work properly`, async () => { 6 | const { code, distFile } = await runCli({ 7 | directory: __dirname, 8 | args: ['index.js', '--env', 'MY_TEST_ENV', '-o', 'dist/index.js'], 9 | options: { 10 | env: { 11 | MY_TEST_ENV: 'my-test-value', 12 | }, 13 | }, 14 | }) 15 | const content = fs.readFileSync(distFile, { encoding: 'utf-8' }) 16 | expect(content.includes('my-test-value')).toBe(true) 17 | expect(code).toBe(0) 18 | }) 19 | -------------------------------------------------------------------------------- /test/cli/externals/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import fs from 'fs' 3 | import { runCli } from '../../testing-utils' 4 | 5 | describe('cli', () => { 6 | it(`cli external should work properly`, async () => { 7 | const { code, distFile } = await runCli({ 8 | directory: __dirname, 9 | args: [ 10 | 'with-externals.js', 11 | '-o', 12 | 'dist/with-externals.bundle.js', 13 | '--external', 14 | '@huozhi/testing-package', 15 | ], 16 | }) 17 | const content = fs.readFileSync(distFile, { encoding: 'utf-8' }) 18 | 19 | expect(content.includes('@@test_expected_string@@')).toBe(false) 20 | expect(content.includes('bar-package')).toBe(true) 21 | expect(code).toBe(0) 22 | }) 23 | 24 | it(`cli no-externals should work properly`, async () => { 25 | const { code, distFile } = await runCli({ 26 | directory: __dirname, 27 | args: [ 28 | 'with-externals.js', 29 | '--no-external', 30 | '-o', 31 | 'dist/with-externals.bundle.js', 32 | ], 33 | }) 34 | const content = fs.readFileSync(distFile, { encoding: 'utf-8' }) 35 | 36 | expect(content.includes('@@test_expected_string@@')).toBe(true) 37 | expect(content.includes('bar-package')).toBe(true) 38 | expect(code).toBe(0) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /test/cli/externals/with-externals.js: -------------------------------------------------------------------------------- 1 | import { __TEST_EXPECTED_STRING__ } from '@huozhi/testing-package' 2 | import bar from 'bar-package' 3 | 4 | export function baz() { 5 | return __TEST_EXPECTED_STRING__ 6 | } 7 | 8 | export function barFunction() { 9 | return bar 10 | } 11 | -------------------------------------------------------------------------------- /test/cli/no-dts/base.ts: -------------------------------------------------------------------------------- 1 | export default 'base' 2 | -------------------------------------------------------------------------------- /test/cli/no-dts/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import fs from 'fs' 3 | import path from 'path' 4 | import { runCli } from '../../testing-utils' 5 | 6 | test(`cli no-dts option should work properly`, async () => { 7 | const { code, distFile } = await runCli({ 8 | directory: __dirname, 9 | args: ['./base.ts', '-o', 'dist/base.js', '--no-dts'], 10 | }) 11 | const typeFile = distFile.replace('.js', '.d.ts') 12 | 13 | expect(path.basename(distFile)).toBe('base.js') 14 | expect(fs.existsSync(distFile)).toBe(true) 15 | expect(fs.existsSync(typeFile)).toBe(false) 16 | expect(code).toBe(0) 17 | }) 18 | -------------------------------------------------------------------------------- /test/cli/no-entry/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import { runCli } from '../../testing-utils' 3 | 4 | test(`cli no-entry should work properly`, async () => { 5 | const { code, stderr } = await runCli({ 6 | directory: __dirname, 7 | }) 8 | expect( 9 | // The "src" directory does not contain any entry files. 10 | // For proper usage, please refer to the following link: 11 | // https://github.com/huozhi/bunchee#usage 12 | stderr.includes('The "src" directory does not contain any entry files.'), 13 | ).toBe(true) 14 | expect(code).toBe(0) 15 | }) 16 | -------------------------------------------------------------------------------- /test/cli/no-entry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-entry", 3 | "main": "./dist/index.js" 4 | } 5 | -------------------------------------------------------------------------------- /test/cli/no-entry/src/no-entry.txt: -------------------------------------------------------------------------------- 1 | no-entry -------------------------------------------------------------------------------- /test/cli/output-in-watch/hello.js: -------------------------------------------------------------------------------- 1 | function sayHello() { 2 | const val = 'hello' 3 | console.log(val) 4 | return val 5 | } 6 | 7 | export default sayHello 8 | export const world = 'world' 9 | -------------------------------------------------------------------------------- /test/cli/output-in-watch/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import { runCli } from '../../testing-utils' 3 | 4 | test('cli - output-in-watch', async () => { 5 | const { stdout, signal } = await runCli({ 6 | directory: __dirname, 7 | args: ['hello.js', '-w', '-o', 'dist/hello.bundle.js'], 8 | abortTimeout: 3000, 9 | }) 10 | expect(stdout).toMatchInlineSnapshot(` 11 | "Watching changes in the project directory... 12 | " 13 | `) 14 | expect(signal).toBe('SIGTERM') // SIGTERM exit code 15 | }) 16 | -------------------------------------------------------------------------------- /test/cli/single-entry-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "exports": "./dist/index.js", 3 | "types": "./dist/index.d.ts" 4 | } 5 | -------------------------------------------------------------------------------- /test/cli/single-entry-js/src/index.js: -------------------------------------------------------------------------------- 1 | const single = 'entry' 2 | 3 | export { single } 4 | -------------------------------------------------------------------------------- /test/cli/target/es2020.ts: -------------------------------------------------------------------------------- 1 | export const spread = { ...globalThis } 2 | export async function loadList() { 3 | return Promise.resolve([1, 2, 3]) 4 | } 5 | export const optionalChainFn = setTimeout?.apply?.bind 6 | export class A {} 7 | -------------------------------------------------------------------------------- /test/cli/target/index.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest' 2 | import fs from 'fs' 3 | import { runCli } from '../../testing-utils' 4 | 5 | test(`cli es2020-target should work properly`, async () => { 6 | const { code, distFile } = await runCli({ 7 | directory: __dirname, 8 | args: ['es2020.ts', '--target', 'es2020', '-o', 'dist/es2020.js'], 9 | }) 10 | const content = fs.readFileSync(distFile, { encoding: 'utf-8' }) 11 | 12 | expect(content.includes(`...globalThis`)).toBe(true) 13 | expect(content.includes(`setTimeout?.apply?.bind`)).toBe(true) 14 | expect(content.includes(`async function`)).toBe(true) 15 | expect(content.includes(`class A`)).toBe(true) 16 | expect(code).toBe(0) 17 | }) 18 | -------------------------------------------------------------------------------- /test/cli/workspace/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import fs from 'fs' 3 | import { runCli } from '../../testing-utils' 4 | import path from 'path' 5 | 6 | describe('cli', () => { 7 | it(`cli workspace should work properly`, async () => { 8 | const { code, distDir } = await runCli({ 9 | directory: __dirname, 10 | args: ['./index.ts'], 11 | }) 12 | const distFile = path.join(distDir, 'index.mjs') 13 | 14 | expect(fs.existsSync(distFile)).toBe(true) 15 | // CLI does not generate declaration files 16 | expect(fs.existsSync(distFile.replace('.mjs', '.d.mts'))).toBe(false) 17 | expect(code).toBe(0) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /test/cli/workspace/index.ts: -------------------------------------------------------------------------------- 1 | export default 'package' 2 | -------------------------------------------------------------------------------- /test/cli/workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": "./dist/index.d.ts", 3 | "exports": "./dist/index.mjs" 4 | } 5 | -------------------------------------------------------------------------------- /test/compile/es-advance/__snapshot__/es-advance.js.snapshot: -------------------------------------------------------------------------------- 1 | const foo = { 2 | bar: 'hello' 3 | }; 4 | console.log('bar', foo == null ? void 0 : foo.bar); 5 | var _foo_bar; 6 | const prop = (_foo_bar = foo.bar) != null ? _foo_bar : 'default'; 7 | console.log('name', prop); 8 | -------------------------------------------------------------------------------- /test/compile/es-advance/__snapshot__/es-advance.min.js.snapshot: -------------------------------------------------------------------------------- 1 | var l;const o={bar:"hello"};console.log("bar",null==o?void 0:o.bar),console.log("name",null!=(l=o.bar)?l:"default"); 2 | -------------------------------------------------------------------------------- /test/compile/es-advance/input.js: -------------------------------------------------------------------------------- 1 | const foo = { 2 | bar: 'hello', 3 | } 4 | 5 | console.log('bar', foo?.bar) 6 | 7 | const prop = foo.bar ?? 'default' 8 | 9 | console.log('name', prop) 10 | -------------------------------------------------------------------------------- /test/compile/es-basic/__snapshot__/es-basic.js.snapshot: -------------------------------------------------------------------------------- 1 | import { _ as _async_to_generator, a as _class_private_field_loose_key, b as _class_private_field_loose_base } from './cc-tR0qO6Uj.mjs'; 2 | 3 | function* generator() { 4 | yield 1; 5 | } 6 | function asyncFunc() { 7 | return _asyncFunc.apply(this, arguments); 8 | } 9 | function _asyncFunc() { 10 | _asyncFunc = _async_to_generator(function*() { 11 | yield new Promise((r)=>r(1)); 12 | }); 13 | return _asyncFunc.apply(this, arguments); 14 | } 15 | var _x = /*#__PURE__*/ _class_private_field_loose_key("_x"); 16 | class A { 17 | *f1() { 18 | yield 1; 19 | } 20 | constructor(){ 21 | Object.defineProperty(this, _x, { 22 | writable: true, 23 | value: void 0 24 | }); 25 | _class_private_field_loose_base(this, _x)[_x] = 1; 26 | this.getX = ()=>{ 27 | return _class_private_field_loose_base(this, _x)[_x]; 28 | }; 29 | } 30 | } 31 | const _v = 123; 32 | const x = ()=>`value:${_v}`; 33 | 34 | export { A, asyncFunc, generator, x }; 35 | -------------------------------------------------------------------------------- /test/compile/es-basic/__snapshot__/es-basic.min.js.snapshot: -------------------------------------------------------------------------------- 1 | import{_ as t,a as e,b as i}from"./cc-DSvfI42W.mjs";function*n(){yield 1}function r(){return s.apply(this,arguments)}function s(){return(s=t(function*(){yield new Promise(t=>t(1))})).apply(this,arguments)}var a=e("_x");class o{*f1(){yield 1}constructor(){Object.defineProperty(this,a,{writable:!0,value:void 0}),i(this,a)[a]=1,this.getX=()=>i(this,a)[a]}}let c=()=>"value:123";export{o as A,r as asyncFunc,n as generator,c as x}; 2 | -------------------------------------------------------------------------------- /test/compile/es-basic/input.js: -------------------------------------------------------------------------------- 1 | function* generator() { 2 | yield 1 3 | } 4 | 5 | async function asyncFunc() { 6 | await new Promise((r) => r(1)) 7 | } 8 | 9 | class A { 10 | #x = 1 11 | getX = () => { 12 | return this.#x 13 | }; 14 | 15 | *f1() { 16 | yield 1 17 | } 18 | } 19 | 20 | const _v = 123 21 | export const x = () => `value:${_v}` 22 | 23 | export { generator, asyncFunc, A } 24 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/__snapshot__/jsx-preserve.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react from 'react'; 2 | 3 | declare function Jsx(): react.JSX.Element; 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/__snapshot__/jsx-preserve.js.snapshot: -------------------------------------------------------------------------------- 1 | function Jsx() { 2 | return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("div", null, "hello"), /*#__PURE__*/ React.createElement("h1", null, "yep")); 3 | } 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/__snapshot__/jsx-preserve.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react from 'react'; 2 | 3 | declare function Jsx(): react.JSX.Element; 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/__snapshot__/jsx-preserve.min.js.snapshot: -------------------------------------------------------------------------------- 1 | function e(){return React.createElement(React.Fragment,null,React.createElement("div",null,"hello"),React.createElement("h1",null,"yep"))}export{e as default}; 2 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/input.tsx: -------------------------------------------------------------------------------- 1 | function Jsx() { 2 | return ( 3 | <> 4 |
hello
5 |

yep

6 | 7 | ) 8 | } 9 | 10 | export default Jsx 11 | -------------------------------------------------------------------------------- /test/compile/jsx-preserve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/__snapshot__/jsx-react-automatic.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react_jsx_runtime from 'react/jsx-runtime'; 2 | 3 | declare function Jsx(): react_jsx_runtime.JSX.Element; 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/__snapshot__/jsx-react-automatic.js.snapshot: -------------------------------------------------------------------------------- 1 | import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; 2 | 3 | function Jsx() { 4 | return /*#__PURE__*/ jsxs(Fragment, { 5 | children: [ 6 | /*#__PURE__*/ jsx("div", { 7 | children: "hello" 8 | }), 9 | /*#__PURE__*/ jsx("h1", { 10 | children: "yep" 11 | }) 12 | ] 13 | }); 14 | } 15 | 16 | export { Jsx as default }; 17 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/__snapshot__/jsx-react-automatic.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react_jsx_runtime from 'react/jsx-runtime'; 2 | 3 | declare function Jsx(): react_jsx_runtime.JSX.Element; 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/__snapshot__/jsx-react-automatic.min.js.snapshot: -------------------------------------------------------------------------------- 1 | import{jsxs as e,Fragment as r,jsx as i}from"react/jsx-runtime";function n(){return e(r,{children:[i("div",{children:"hello"}),i("h1",{children:"yep"})]})}export{n as default}; 2 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/input.tsx: -------------------------------------------------------------------------------- 1 | function Jsx() { 2 | return ( 3 | <> 4 |
hello
5 |

yep

6 | 7 | ) 8 | } 9 | 10 | export default Jsx 11 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsx-react-automatic", 3 | "peerDependencies": { 4 | "react": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/compile/jsx-react-automatic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react-jsx", 4 | "moduleResolution": "node" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/compile/jsx/__snapshot__/jsx.js.snapshot: -------------------------------------------------------------------------------- 1 | function Jsx() { 2 | return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("div", null, "hello"), /*#__PURE__*/ React.createElement("h1", null, "yep")); 3 | } 4 | 5 | export { Jsx as default }; 6 | -------------------------------------------------------------------------------- /test/compile/jsx/__snapshot__/jsx.min.js.snapshot: -------------------------------------------------------------------------------- 1 | function e(){return React.createElement(React.Fragment,null,React.createElement("div",null,"hello"),React.createElement("h1",null,"yep"))}export{e as default}; 2 | -------------------------------------------------------------------------------- /test/compile/jsx/input.jsx: -------------------------------------------------------------------------------- 1 | function Jsx() { 2 | return ( 3 | 4 |
hello
5 |

yep

6 |
7 | ) 8 | } 9 | 10 | export default Jsx 11 | -------------------------------------------------------------------------------- /test/compile/module/__snapshot__/module.js.snapshot: -------------------------------------------------------------------------------- 1 | class Parent { 2 | f() { 3 | return 1; 4 | } 5 | } 6 | 7 | class A extends Parent { 8 | get x() { 9 | return super.f(); 10 | } 11 | constructor(){ 12 | super(); 13 | } 14 | } 15 | const a = new A(); 16 | 17 | console.log('main', a.x); 18 | -------------------------------------------------------------------------------- /test/compile/module/__snapshot__/module.min.js.snapshot: -------------------------------------------------------------------------------- 1 | class e{f(){return 1}}console.log("main",new class extends e{get x(){return super.f()}constructor(){super()}}().x); 2 | -------------------------------------------------------------------------------- /test/compile/module/a.js: -------------------------------------------------------------------------------- 1 | import { Parent } from './b' 2 | 3 | class A extends Parent { 4 | constructor() { 5 | super() 6 | } 7 | get x() { 8 | return super.f() 9 | } 10 | } 11 | 12 | const a = new A() 13 | 14 | export default a 15 | -------------------------------------------------------------------------------- /test/compile/module/b.js: -------------------------------------------------------------------------------- 1 | class Parent { 2 | f() { 3 | return 1 4 | } 5 | } 6 | 7 | export { Parent } 8 | -------------------------------------------------------------------------------- /test/compile/module/input.js: -------------------------------------------------------------------------------- 1 | import a from './a' 2 | 3 | console.log('main', a.x) 4 | -------------------------------------------------------------------------------- /test/compile/shebang/__snapshot__/shebang.js.snapshot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log('shebang'); 3 | -------------------------------------------------------------------------------- /test/compile/shebang/__snapshot__/shebang.min.js.snapshot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log("shebang"); 3 | -------------------------------------------------------------------------------- /test/compile/shebang/input.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | console.log('shebang') 4 | -------------------------------------------------------------------------------- /test/compile/sub-folder-import/__snapshot__/sub-folder-import.js.snapshot: -------------------------------------------------------------------------------- 1 | import ms from 'ms/index'; 2 | 3 | var input = ((...args)=>ms(...args)); 4 | 5 | export { input as default }; 6 | -------------------------------------------------------------------------------- /test/compile/sub-folder-import/__snapshot__/sub-folder-import.min.js.snapshot: -------------------------------------------------------------------------------- 1 | import r from"ms/index";var t=(...t)=>r(...t);export{t as default}; 2 | -------------------------------------------------------------------------------- /test/compile/sub-folder-import/input.js: -------------------------------------------------------------------------------- 1 | import ms from 'ms/index' 2 | 3 | export default (...args) => ms(...args) 4 | -------------------------------------------------------------------------------- /test/compile/sub-folder-import/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "ms": "*" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/treeshake/__snapshot__/treeshake.js.snapshot: -------------------------------------------------------------------------------- 1 | class Foo { 2 | getFoo() { 3 | return 'foo'; 4 | } 5 | } 6 | 7 | export { Foo }; 8 | -------------------------------------------------------------------------------- /test/compile/treeshake/__snapshot__/treeshake.min.js.snapshot: -------------------------------------------------------------------------------- 1 | class o{getFoo(){return"foo"}}export{o as Foo}; 2 | -------------------------------------------------------------------------------- /test/compile/treeshake/input.js: -------------------------------------------------------------------------------- 1 | class Foo { 2 | getFoo() { 3 | return 'foo' 4 | } 5 | } 6 | 7 | // This will be removed by treeshaking 8 | class Bar { 9 | getBar() { 10 | return 'bar' 11 | } 12 | } 13 | 14 | export { Foo } 15 | -------------------------------------------------------------------------------- /test/compile/ts-basic/__snapshot__/ts-basic.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare const sum: number; 2 | declare const clone: { 3 | a: number; 4 | b: number; 5 | }; 6 | declare function asyncFunc(): Promise; 7 | 8 | export { asyncFunc, clone, sum as default }; 9 | -------------------------------------------------------------------------------- /test/compile/ts-basic/__snapshot__/ts-basic.js.snapshot: -------------------------------------------------------------------------------- 1 | import { _ as _extends, a as _async_to_generator } from './cc-CgYInQop.mjs'; 2 | 3 | const add = (a, b)=>a + b; 4 | 5 | const sum = add(1, 2); 6 | const obj = { 7 | a: 1, 8 | b: 2 9 | }; 10 | const clone = _extends({}, obj); 11 | function asyncFunc() { 12 | return _asyncFunc.apply(this, arguments); 13 | } 14 | function _asyncFunc() { 15 | _asyncFunc = _async_to_generator(function*() { 16 | yield new Promise((r)=>r(1)); 17 | }); 18 | return _asyncFunc.apply(this, arguments); 19 | } 20 | 21 | export { asyncFunc, clone, sum as default }; 22 | -------------------------------------------------------------------------------- /test/compile/ts-basic/__snapshot__/ts-basic.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare const sum: number; 2 | declare const clone: { 3 | a: number; 4 | b: number; 5 | }; 6 | declare function asyncFunc(): Promise; 7 | 8 | export { asyncFunc, clone, sum as default }; 9 | -------------------------------------------------------------------------------- /test/compile/ts-basic/__snapshot__/ts-basic.min.js.snapshot: -------------------------------------------------------------------------------- 1 | import{_ as n,a as t}from"./cc-BNzK7Xbm.mjs";let a=3,e=n({},{a:1,b:2});function s(){return c.apply(this,arguments)}function c(){return(c=t(function*(){yield new Promise(n=>n(1))})).apply(this,arguments)}export{s as asyncFunc,e as clone,a as default}; 2 | -------------------------------------------------------------------------------- /test/compile/ts-basic/input.ts: -------------------------------------------------------------------------------- 1 | import { add } from './math' 2 | 3 | const sum: number = add(1, 2) 4 | 5 | const obj = { a: 1, b: 2 } 6 | const clone = { ...obj } 7 | 8 | export async function asyncFunc() { 9 | await new Promise((r) => r(1)) 10 | } 11 | 12 | export { clone } 13 | export default sum 14 | -------------------------------------------------------------------------------- /test/compile/ts-basic/math.ts: -------------------------------------------------------------------------------- 1 | export const add = (a: number, b: number): number => a + b 2 | -------------------------------------------------------------------------------- /test/compile/ts-basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*.ts"] 3 | } 4 | -------------------------------------------------------------------------------- /test/compile/ts-interop/__snapshot__/ts-interop.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare const a: { 2 | x: number; 3 | }; 4 | declare const b = "hello"; 5 | 6 | export { b, a as default }; 7 | -------------------------------------------------------------------------------- /test/compile/ts-interop/__snapshot__/ts-interop.js.snapshot: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports, '__esModule', { value: true }); 2 | 3 | const a = { 4 | x: 1 5 | }; 6 | const b = 'hello'; 7 | 8 | exports.b = b; 9 | exports.default = a; 10 | -------------------------------------------------------------------------------- /test/compile/ts-interop/__snapshot__/ts-interop.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare const a: { 2 | x: number; 3 | }; 4 | declare const b = "hello"; 5 | 6 | export { b, a as default }; 7 | -------------------------------------------------------------------------------- /test/compile/ts-interop/__snapshot__/ts-interop.min.js.snapshot: -------------------------------------------------------------------------------- 1 | Object.defineProperty(exports,"__esModule",{value:!0}),exports.b="hello",exports.default={x:1}; 2 | -------------------------------------------------------------------------------- /test/compile/ts-interop/input.ts: -------------------------------------------------------------------------------- 1 | const a = { x: 1 } 2 | const b = 'hello' 3 | 4 | export { b } 5 | export default a 6 | -------------------------------------------------------------------------------- /test/compile/ts-interop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "dist/bundle.js" 3 | } 4 | -------------------------------------------------------------------------------- /test/compile/ts-interop/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/ts-interop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json" 3 | } 4 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/__snapshot__/ts-target-es2018.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare function asyncFunc(): Promise; 2 | declare const spread: { 3 | x: number; 4 | y: number; 5 | }; 6 | 7 | export { asyncFunc, spread }; 8 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/__snapshot__/ts-target-es2018.js.snapshot: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | async function asyncFunc() { 3 | await new Promise((r)=>r(2)); 4 | } 5 | const spread = { 6 | ...{ 7 | x: 1, 8 | y: 2 9 | } 10 | }; 11 | 12 | export { asyncFunc, spread }; 13 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/__snapshot__/ts-target-es2018.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | declare function asyncFunc(): Promise; 2 | declare const spread: { 3 | x: number; 4 | y: number; 5 | }; 6 | 7 | export { asyncFunc, spread }; 8 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/__snapshot__/ts-target-es2018.min.js.snapshot: -------------------------------------------------------------------------------- 1 | "use client";async function e(){await new Promise(e=>e(2))}let n={x:1,y:2};export{e as asyncFunc,n as spread}; 2 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/input.ts: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | export async function asyncFunc() { 4 | await new Promise((r) => r(2)) 5 | } 6 | export const spread = { ...{ x: 1, y: 2 } } 7 | -------------------------------------------------------------------------------- /test/compile/ts-target-es2018/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*.ts"], 3 | "compilerOptions": { 4 | "target": "ES2018" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/__snapshot__/tsx-css-global.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react from 'react'; 2 | 3 | declare function Foo(): react.JSX.Element; 4 | 5 | export { Foo as default }; 6 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/__snapshot__/tsx-css-global.js.snapshot: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | function __insertCSS(code) { 3 | if (!code || typeof document == 'undefined') return 4 | let head = document.head || document.getElementsByTagName('head')[0] 5 | let style = document.createElement('style') 6 | style.type = 'text/css' 7 | head.appendChild(style) 8 | ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code)) 9 | } 10 | 11 | __insertCSS(".foo{transform-origin:center}"); 12 | 13 | function Foo() { 14 | return /*#__PURE__*/ React.createElement("p", { 15 | className: "foo" 16 | }, "foo"); 17 | } 18 | 19 | export { Foo as default }; 20 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/__snapshot__/tsx-css-global.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | import * as react from 'react'; 2 | 3 | declare function Foo(): react.JSX.Element; 4 | 5 | export { Foo as default }; 6 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/__snapshot__/tsx-css-global.min.js.snapshot: -------------------------------------------------------------------------------- 1 | "use client";function e(){return React.createElement("p",{className:"foo"},"foo")}!function(e){if(!e||"undefined"==typeof document)return;let t=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css",t.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}(".foo{transform-origin:center}");export{e as default}; 2 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/input.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import './style.css' 4 | 5 | export default function Foo() { 6 | return

foo

7 | } 8 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/style.css: -------------------------------------------------------------------------------- 1 | /* This is a comment */ 2 | .foo { 3 | transform-origin: center; 4 | } 5 | -------------------------------------------------------------------------------- /test/compile/tsx-css-global/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/tsx/__snapshot__/env.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huozhi/bunchee/283437b5288bc28e3c87cc11ef894fe120eef92e/test/compile/tsx/__snapshot__/env.d.ts -------------------------------------------------------------------------------- /test/compile/tsx/__snapshot__/tsx.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | type FooString = string; 2 | 3 | declare function Tsx(): any; 4 | 5 | export { Tsx as default }; 6 | export type { FooString }; 7 | -------------------------------------------------------------------------------- /test/compile/tsx/__snapshot__/tsx.js.snapshot: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | function Tsx() { 4 | return /*#__PURE__*/ React.createElement("div", null, "hello"); 5 | } 6 | 7 | export { Tsx as default }; 8 | -------------------------------------------------------------------------------- /test/compile/tsx/__snapshot__/tsx.min.d.ts.snapshot: -------------------------------------------------------------------------------- 1 | type FooString = string; 2 | 3 | declare function Tsx(): any; 4 | 5 | export { Tsx as default }; 6 | export type { FooString }; 7 | -------------------------------------------------------------------------------- /test/compile/tsx/__snapshot__/tsx.min.js.snapshot: -------------------------------------------------------------------------------- 1 | import e from"react";function t(){return e.createElement("div",null,"hello")}export{t as default}; 2 | -------------------------------------------------------------------------------- /test/compile/tsx/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react' 2 | -------------------------------------------------------------------------------- /test/compile/tsx/foo.tsx: -------------------------------------------------------------------------------- 1 | type FooString = string 2 | 3 | export { type FooString } 4 | -------------------------------------------------------------------------------- /test/compile/tsx/input.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function Tsx() { 4 | return
hello
5 | } 6 | 7 | export default Tsx 8 | export { type FooString } from './foo' 9 | -------------------------------------------------------------------------------- /test/compile/tsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "peerDependencies": { 3 | "react": "*" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/tsx/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/use-client/__snapshot__/use-client.js.snapshot: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import { c as client } from './client-12s-Cm06vGwQ.mjs'; 3 | 4 | var input = (()=>{ 5 | return client(); 6 | }); 7 | 8 | export { input as default }; 9 | -------------------------------------------------------------------------------- /test/compile/use-client/__snapshot__/use-client.min.js.snapshot: -------------------------------------------------------------------------------- 1 | "use strict";import{c as t}from"./client-12s-B-RDfYre.mjs";var s=()=>t();export{s as default}; 2 | -------------------------------------------------------------------------------- /test/compile/use-client/client.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | export default function client() { 4 | return React.useState(null) 5 | } 6 | -------------------------------------------------------------------------------- /test/compile/use-client/input.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import client from './client' 4 | ;('use client') // this should be ignored it didn't appear at the top of the file 5 | 6 | export default () => { 7 | return client() 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/integration-test-template/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils' 3 | 4 | describe('integration - ', () => { 5 | const { distDir } = createJob({ 6 | directory: __dirname, 7 | }) 8 | it('should work', async () => { 9 | const files = await getFileNamesFromDirectory(distDir) 10 | // expect(files).toEqual([]) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /test/fixtures/integration-test-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "main": "./dist/index.js", 4 | "type": "module", 5 | "exports": { 6 | ".": "./dist/index.js" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/integration-test-template/src/index.js: -------------------------------------------------------------------------------- 1 | export function foo() { 2 | return 'foo' 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/basic-jsx/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { createJob, assertContainFiles } from '../../testing-utils' 3 | 4 | describe('integration basic-jsx', () => { 5 | const { job, distDir } = createJob({ 6 | directory: __dirname, 7 | }) 8 | it('should work with basic JSX format', async () => { 9 | const { stdout, stderr } = job 10 | expect(stderr + stdout).not.toContain('(swc plugin)') 11 | assertContainFiles(distDir, ['index.js', 'index.mjs']) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/integration/basic-jsx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js-basic", 3 | "main": "./dist/index.js", 4 | "module": "./dist/index.mjs", 5 | "exports": { 6 | ".": { 7 | "import": "./dist/index.mjs", 8 | "require": "./dist/index.js" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/integration/basic-jsx/src/index.js: -------------------------------------------------------------------------------- 1 | export function Foo() { 2 | return

Foo

3 | } 4 | -------------------------------------------------------------------------------- /test/integration/bin/cts/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { assertFilesContent, createJob } from '../../../testing-utils' 3 | 4 | describe('integration bin/cts', () => { 5 | const { distDir } = createJob({ 6 | directory: __dirname, 7 | }) 8 | it('should work with bin as .cts extension', async () => { 9 | await assertFilesContent(distDir, { 10 | 'bin/index.cjs': '#!/usr/bin/env node', 11 | }) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/integration/bin/cts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "bin": "./dist/bin/index.cjs" 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/bin/cts/src/bin/index.cts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const path = require('path') 3 | console.log(path.basename(__filename)) 4 | -------------------------------------------------------------------------------- /test/integration/bin/multi-path/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { 3 | assertFilesContent, 4 | createJob, 5 | isWindows, 6 | } from '../../../testing-utils' 7 | 8 | describe('integration bin/multi-path', () => { 9 | // TODO: handle the transform error on windows 10 | if (isWindows) { 11 | it('skip test on windows', () => {}) 12 | return 13 | } 14 | const { distDir } = createJob({ 15 | directory: __dirname, 16 | }) 17 | it('should work with bin as multi path', async () => { 18 | await assertFilesContent(distDir, { 19 | 'bin/a.js': '#!/usr/bin/env node', 20 | 'bin/b.js': '#!/usr/bin/env node', 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /test/integration/bin/multi-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "bin": { 3 | "a": "./dist/bin/a.js", 4 | "b": "./dist/bin/b.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/integration/bin/multi-path/src/bin/a.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log('a') 3 | -------------------------------------------------------------------------------- /test/integration/bin/multi-path/src/bin/b.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log('b') 3 | -------------------------------------------------------------------------------- /test/integration/bin/patch-binary/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 bin/patch-binary', () => { 9 | const { distDir } = createJob({ directory: __dirname }) 10 | it('should patch binary directive', async () => { 11 | const distFiles = ['bin.js'] 12 | await assertContainFiles(distDir, distFiles) 13 | await assertFilesContent(distDir, { 14 | 'bin.js': "#!/usr/bin/env node\nconsole.log('Hello, world!');", 15 | }) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /test/integration/bin/patch-binary/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "bin": "./dist/bin.js" 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/bin/patch-binary/src/bin/index.ts: -------------------------------------------------------------------------------- 1 | console.log('Hello, world!') 2 | -------------------------------------------------------------------------------- /test/integration/bin/single-path/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { 3 | createJob, 4 | assertContainFiles, 5 | assertFilesContent, 6 | isWindows, 7 | } from '../../../testing-utils' 8 | 9 | describe('integration bin/single-path', () => { 10 | // TODO: handle the transform error on windows 11 | if (isWindows) { 12 | it('skip test on windows', () => {}) 13 | return 14 | } 15 | const { distDir } = createJob({ directory: __dirname }) 16 | it('should work with bin as single path', async () => { 17 | const distFiles = ['bin.js'] 18 | await assertContainFiles(distDir, distFiles) 19 | await assertFilesContent(distDir, { 20 | 'bin.js': /console.log\('Hello, world!'\)/, 21 | }) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /test/integration/bin/single-path/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "bin": "./dist/bin.js" 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/bin/single-path/src/bin/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | console.log('Hello, world!') 3 | -------------------------------------------------------------------------------- /test/integration/browserslist/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { assertFilesContent, createJob } from '../../testing-utils' 3 | 4 | describe('browserslist', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | it('should work with basic JSX format', async () => { 7 | await assertFilesContent(distDir, { 8 | 'index.js': `_class_private_field_loose_key`, 9 | }) 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /test/integration/browserslist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browserslist", 3 | "main": "./dist/index.js", 4 | "browserslist": [ 5 | "ie 9" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/browserslist/src/index.js: -------------------------------------------------------------------------------- 1 | export class A { 2 | static prop = 'A-prop' 3 | 4 | #foo() { 5 | return 'foo' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/conflicted-entry/conflicted-entry.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { createJob } from '../../testing-utils' 3 | 4 | describe('integration - conflicted-entry', () => { 5 | const { job } = createJob({ directory: __dirname }) 6 | it('should error on conflicted entries', async () => { 7 | const { code, stderr } = job 8 | expect(code).toBe(1) 9 | expect(stderr).toContain('Conflicted entry files found for entries: ./foo') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /test/integration/conflicted-entry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conflicted-entry", 3 | "exports": { 4 | "./foo": "./dist/foo.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/integration/conflicted-entry/src/foo.ts: -------------------------------------------------------------------------------- 1 | export class Foo {} 2 | -------------------------------------------------------------------------------- /test/integration/conflicted-entry/src/foo/index.jsx: -------------------------------------------------------------------------------- 1 | export class Foo {} 2 | -------------------------------------------------------------------------------- /test/integration/default-default-export-different-ext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "default-default-esm", 3 | "type": "module", 4 | "exports": { 5 | "./a": { 6 | "import": { 7 | "types": "./dist/a.d.ts", 8 | "default": "./dist/a.js" 9 | }, 10 | "require": { 11 | "types": "./dist/a.d.cts", 12 | "default": "./dist/a.cjs" 13 | }, 14 | "default": "./dist/a.cjs" 15 | }, 16 | "./b": { 17 | "import": { 18 | "types": "./dist/b.d.ts", 19 | "default": "./dist/b.js" 20 | }, 21 | "require": { 22 | "types": "./dist/b.d.cts", 23 | "default": "./dist/b.cjs" 24 | }, 25 | "default": "./dist/b.cjs" 26 | }, 27 | "./c": { 28 | "default": "./dist/c.cjs" 29 | } 30 | }, 31 | "private": true 32 | } 33 | -------------------------------------------------------------------------------- /test/integration/default-default-export-different-ext/src/a.ts: -------------------------------------------------------------------------------- 1 | export * from './b' 2 | export const a = 'a' 3 | -------------------------------------------------------------------------------- /test/integration/default-default-export-different-ext/src/b.ts: -------------------------------------------------------------------------------- 1 | export const b = 'b' 2 | -------------------------------------------------------------------------------- /test/integration/default-default-export-different-ext/src/c.ts: -------------------------------------------------------------------------------- 1 | import { a } from './a' 2 | 3 | export const c = `c${a}` 4 | -------------------------------------------------------------------------------- /test/integration/default-default-export/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { 3 | getFileNamesFromDirectory, 4 | createJob, 5 | getFileContents, 6 | } from '../../testing-utils' 7 | 8 | describe('integration - default-default-export', () => { 9 | const { distDir } = createJob({ directory: __dirname }) 10 | 11 | it('should not export esm module in cjs file', async () => { 12 | const distFiles = await getFileNamesFromDirectory(distDir) 13 | expect(distFiles).toEqual([ 14 | 'a.cjs', 15 | 'a.d.ts', 16 | 'a.js', 17 | 'b.cjs', 18 | 'b.d.ts', 19 | 'b.js', 20 | 'c.js', 21 | ]) 22 | const contents = await getFileContents(distDir) 23 | expect(contents['a.cjs']).toMatchInlineSnapshot(` 24 | "var b_cjs = require('./b.cjs'); 25 | 26 | const a = 'a'; 27 | 28 | exports.a = a; 29 | Object.keys(b_cjs).forEach(function (k) { 30 | if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, { 31 | enumerable: true, 32 | get: function () { return b_cjs[k]; } 33 | }); 34 | }); 35 | " 36 | `) 37 | expect(contents['a.js']).toMatchInlineSnapshot(` 38 | "export * from './b.js'; 39 | 40 | const a = 'a'; 41 | 42 | export { a }; 43 | " 44 | `) 45 | expect(contents['c.js']).toMatchInlineSnapshot(` 46 | "import { a } from './a.js'; 47 | 48 | const c = \`c\${a}\`; 49 | 50 | export { c }; 51 | " 52 | `) 53 | }) 54 | }) 55 | -------------------------------------------------------------------------------- /test/integration/default-default-export/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "default-default-esm", 3 | "type": "module", 4 | "exports": { 5 | "./a": { 6 | "import": { 7 | "types": "./dist/a.d.ts", 8 | "default": "./dist/a.js" 9 | }, 10 | "require": { 11 | "types": "./dist/a.d.cts", 12 | "default": "./dist/a.cjs" 13 | }, 14 | "default": "./dist/a.js" 15 | }, 16 | "./b": { 17 | "import": { 18 | "types": "./dist/b.d.ts", 19 | "default": "./dist/b.js" 20 | }, 21 | "require": { 22 | "types": "./dist/b.d.cts", 23 | "default": "./dist/b.cjs" 24 | }, 25 | "default": "./dist/b.js" 26 | }, 27 | "./c": { 28 | "default": "./dist/c.js" 29 | } 30 | }, 31 | "private": true 32 | } 33 | -------------------------------------------------------------------------------- /test/integration/default-default-export/src/a.ts: -------------------------------------------------------------------------------- 1 | export * from './b' 2 | export const a = 'a' 3 | -------------------------------------------------------------------------------- /test/integration/default-default-export/src/b.ts: -------------------------------------------------------------------------------- 1 | export const b = 'b' 2 | -------------------------------------------------------------------------------- /test/integration/default-default-export/src/c.ts: -------------------------------------------------------------------------------- 1 | import { a } from './a' 2 | 3 | export const c = `c${a}` 4 | -------------------------------------------------------------------------------- /test/integration/default-node-mjs/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { readFile } from 'fs/promises' 3 | import { createJob, existsFile } from '../../testing-utils' 4 | 5 | describe('integration default-node-mjs', () => { 6 | const { distDir } = createJob({ directory: __dirname }) 7 | 8 | it('should work with .mjs extension', async () => { 9 | const distFiles = [`${distDir}/index.node.mjs`] 10 | 11 | for (const f of distFiles) { 12 | expect(await existsFile(f)).toBe(true) 13 | } 14 | 15 | expect(await readFile(distFiles[0], 'utf-8')).toContain('export {') 16 | expect(await readFile(distFiles[0], 'utf-8')).not.toContain('exports') 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/integration/default-node-mjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "exports": { 3 | ".": { 4 | "node": "./dist/index.node.mjs" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/default-node-mjs/src/index.js: -------------------------------------------------------------------------------- 1 | export const value = 'index' 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention-reexport/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, assertFilesContent } from '../../testing-utils' 3 | 4 | describe('integration dev-prod-convention-reexport', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | 7 | it('should work with dev and prod optimize conditions', async () => { 8 | await assertFilesContent(distDir, { 9 | // index export 10 | 'index.dev.js': /core.dev.js/, 11 | 'index.dev.mjs': /core.dev.mjs/, 12 | 'index.prod.js': /core.prod.js/, 13 | 'index.prod.mjs': /core.prod.mjs/, 14 | 'index.js': /core.js/, 15 | 'index.mjs': /core.mjs/, 16 | }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention-reexport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-prod-convention-reexport", 3 | "exports": { 4 | ".": { 5 | "import": { 6 | "development": "./dist/index.dev.mjs", 7 | "production": "./dist/index.prod.mjs", 8 | "default": "./dist/index.mjs" 9 | }, 10 | "require": { 11 | "production": "./dist/index.prod.js", 12 | "development": "./dist/index.dev.js", 13 | "default": "./dist/index.js" 14 | } 15 | }, 16 | "./core": { 17 | "import": { 18 | "development": "./dist/core.dev.mjs", 19 | "production": "./dist/core.prod.mjs", 20 | "default": "./dist/core.mjs" 21 | }, 22 | "require": { 23 | "production": "./dist/core.prod.js", 24 | "development": "./dist/core.dev.js", 25 | "default": "./dist/core.js" 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention-reexport/src/core.ts: -------------------------------------------------------------------------------- 1 | export const value = 'core.cond' 2 | export const env = process.env.NODE_ENV 3 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention-reexport/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './core' 2 | export const value = 'index' 3 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, assertFilesContent } from '../../testing-utils' 3 | 4 | describe('integration dev-prod-convention', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | 7 | it('should work with dev and prod optimize conditions', async () => { 8 | await assertFilesContent(distDir, { 9 | 'index.development.js': /= "development"/, 10 | 'index.development.mjs': /= "development"/, 11 | 'index.production.js': /= "production"/, 12 | 'index.production.mjs': /= "production"/, 13 | // Do not replace NODE_ENV by default 14 | 'index.js': /= process.env.NODE_ENV/, 15 | 'index.mjs': /= process.env.NODE_ENV/, 16 | }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-prod-convention", 3 | "exports": { 4 | ".": { 5 | "import": { 6 | "development": "./dist/index.development.mjs", 7 | "production": "./dist/index.production.mjs", 8 | "default": "./dist/index.mjs" 9 | }, 10 | "require": { 11 | "production": "./dist/index.production.js", 12 | "development": "./dist/index.development.js", 13 | "default": "./dist/index.js" 14 | }, 15 | "default": "./dist/index.js" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/integration/dev-prod-convention/src/index.ts: -------------------------------------------------------------------------------- 1 | export const value = process.env.NODE_ENV 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, assertFilesContent } from '../../testing-utils' 3 | 4 | describe('integration dev-prod-nested-convention', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | 7 | it('should work with dev and prod optimize conditions', async () => { 8 | await assertFilesContent(distDir, { 9 | // index export 10 | 'index.development.js': /= "development"/, 11 | 'index.development.mjs': /= "development"/, 12 | 'index.production.js': /= "production"/, 13 | 'index.production.mjs': /= "production"/, 14 | 'index.js': /= 'index'/, 15 | 'index.mjs': /= 'index'/, 16 | 17 | // core export 18 | 'core.development.js': `= 'core' + "development"`, 19 | 'core.development.mjs': `= 'core' + "development"`, 20 | 'core.production.js': `= 'core' + "production"`, 21 | 'core.production.mjs': `= 'core' + "production"`, 22 | 'core.js': /= 'core'/, 23 | 'core.mjs': /= 'core'/, 24 | }) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-prod-nested-convention", 3 | "exports": { 4 | ".": { 5 | "import": { 6 | "development": "./dist/index.development.mjs", 7 | "production": "./dist/index.production.mjs", 8 | "default": "./dist/index.mjs" 9 | }, 10 | "require": { 11 | "production": "./dist/index.production.js", 12 | "development": "./dist/index.development.js", 13 | "default": "./dist/index.js" 14 | } 15 | }, 16 | "./core": { 17 | "import": { 18 | "development": "./dist/core.development.mjs", 19 | "production": "./dist/core.production.mjs", 20 | "default": "./dist/core.mjs" 21 | }, 22 | "require": { 23 | "production": "./dist/core.production.js", 24 | "development": "./dist/core.development.js", 25 | "default": "./dist/core.js" 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/core.development.ts: -------------------------------------------------------------------------------- 1 | export const value = 'core' + process.env.NODE_ENV 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/core.production.ts: -------------------------------------------------------------------------------- 1 | export const value = 'core' + process.env.NODE_ENV 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/core.ts: -------------------------------------------------------------------------------- 1 | export const value = 'core' 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/index.development.ts: -------------------------------------------------------------------------------- 1 | export const value = process.env.NODE_ENV 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/index.production.ts: -------------------------------------------------------------------------------- 1 | export const value = process.env.NODE_ENV 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-nested-convention/src/index.ts: -------------------------------------------------------------------------------- 1 | export const value = 'index' 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-special-convention/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, assertFilesContent } from '../../testing-utils' 3 | 4 | describe('integration dev-prod-special-convention', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | 7 | it('should work with dev prod and special optimize conditions', async () => { 8 | await assertFilesContent(distDir, { 9 | 'index.react-server.mjs': 'index.react-server', 10 | 'index.development.js': /'index.default'/, 11 | 'index.development.mjs': /'index.default'/, 12 | 'index.production.js': /'index.default'/, 13 | 'index.production.mjs': /'index.default'/, 14 | 'index.js': /'index.default'/, 15 | 'index.mjs': /'index.default'/, 16 | }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /test/integration/dev-prod-special-convention/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dev-prod-special-convention", 3 | "exports": { 4 | ".": { 5 | "react-server": "./dist/index.react-server.mjs", 6 | "import": { 7 | "production": "./dist/index.production.mjs", 8 | "development": "./dist/index.development.mjs", 9 | "default": "./dist/index.mjs" 10 | }, 11 | "require": { 12 | "production": "./dist/index.production.js", 13 | "development": "./dist/index.development.js", 14 | "default": "./dist/index.js" 15 | }, 16 | "default": "./dist/index.js" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/integration/dev-prod-special-convention/src/index.react-server.ts: -------------------------------------------------------------------------------- 1 | export const value = 'index.react-server' 2 | -------------------------------------------------------------------------------- /test/integration/dev-prod-special-convention/src/index.ts: -------------------------------------------------------------------------------- 1 | export const value = 'index.default' 2 | -------------------------------------------------------------------------------- /test/integration/duplicate-entries-partial-specified/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils' 3 | 4 | describe('integration duplicate-entries-partial-specified', () => { 5 | const { distDir } = createJob({ directory: __dirname }) 6 | 7 | it('should not generate js types paths if not specified', async () => { 8 | expect(await getFileNamesFromDirectory(distDir)).toEqual([ 9 | 'a.js', 10 | 'a.workerd.js', 11 | ]) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/integration/duplicate-entries-partial-specified/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "duplicate-entries-partial-specified", 3 | "type": "module", 4 | "exports": { 5 | "./a": { 6 | "workerd": "./dist/a.workerd.js", 7 | "import": "./dist/a.js" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/integration/duplicate-entries-partial-specified/src/a.ts: -------------------------------------------------------------------------------- 1 | export { internal } from './a/shared' 2 | -------------------------------------------------------------------------------- /test/integration/duplicate-entries-partial-specified/src/a.workerd.ts: -------------------------------------------------------------------------------- 1 | export { internal } from './a/shared' 2 | -------------------------------------------------------------------------------- /test/integration/duplicate-entries-partial-specified/src/a/shared.ts: -------------------------------------------------------------------------------- 1 | export const internal = 'a' 2 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/dynamic-require.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import fs from 'fs' 3 | import { createJob, getFileNamesFromDirectory } from '../../testing-utils' 4 | 5 | describe('integration - dynamic-require', () => { 6 | const { distDir } = createJob({ directory: __dirname }) 7 | 8 | it('should work to include the relative dynamic module', async () => { 9 | expect(await getFileNamesFromDirectory(distDir)).toEqual([ 10 | 'foo.cjs', 11 | 'foo.js', 12 | 'index.cjs', 13 | 'index.js', 14 | ]) 15 | // TODO: add helper of read content of dist file 16 | 17 | // For require calls to the relative path, the value should be bundled 18 | expect(fs.readFileSync(`${distDir}/index.cjs`, 'utf-8')).toContain( 19 | `return 'being-required'`, 20 | ) 21 | expect(fs.readFileSync(`${distDir}/index.js`, 'utf-8')).toContain( 22 | `return 'being-required'`, 23 | ) 24 | // For require calls to the external library, the value should not be bundled 25 | expect(fs.readFileSync(`${distDir}/foo.cjs`, 'utf-8')).not.toContain( 26 | `external-lib-value`, 27 | ) 28 | expect(fs.readFileSync(`${distDir}/foo.js`, 'utf-8')).not.toContain( 29 | `external-lib-value`, 30 | ) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/node_modules/external-lib/index.js: -------------------------------------------------------------------------------- 1 | const ExternalLib = { 2 | method() { 3 | return 'external-lib-value'; 4 | } 5 | } 6 | 7 | export default ExternalLib 8 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/node_modules/external-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "external-lib", 3 | "type": "module", 4 | "main": "./index.js" 5 | } -------------------------------------------------------------------------------- /test/integration/dynamic-require/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dynamic-require", 3 | "main": "./dist/index.js", 4 | "type": "module", 5 | "exports": { 6 | ".": { 7 | "import": "./dist/index.js", 8 | "default": "./dist/index.cjs" 9 | }, 10 | "./foo": { 11 | "import": "./dist/foo.js", 12 | "default": "./dist/foo.cjs" 13 | } 14 | }, 15 | "dependencies": { 16 | "external-lib": "*" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/src/foo.js: -------------------------------------------------------------------------------- 1 | import externalLib from 'external-lib' 2 | 3 | export function foo() { 4 | return externalLib.method() 5 | } 6 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/src/index.js: -------------------------------------------------------------------------------- 1 | export function index() { 2 | require('./required-module').method() 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/dynamic-require/src/required-module.js: -------------------------------------------------------------------------------- 1 | export function method() { 2 | return 'being-required' 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/edge-variable/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'vitest' 2 | import { createJob, assertFilesContent } from '../../testing-utils' 3 | 4 | describe('integration edge-variable', () => { 5 | const { distDir } = createJob({ 6 | directory: __dirname, 7 | }) 8 | it('should work with edge export condition', async () => { 9 | await assertFilesContent(distDir, { 10 | 'index.js': /typeof EdgeRuntime/, 11 | 'index.edge.js': /const variable = \"string\"/, // typeof "edge-runtime" 12 | }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /test/integration/edge-variable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "exports": { 4 | "edge-light": "./dist/index.edge.js", 5 | "import": "./dist/index.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/edge-variable/src/index.js: -------------------------------------------------------------------------------- 1 | export const variable = typeof EdgeRuntime 2 | -------------------------------------------------------------------------------- /test/integration/entry-index-index/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { 3 | assertFilesContent, 4 | createJob, 5 | stripANSIColor, 6 | } from '../../testing-utils' 7 | 8 | describe('integration entry-index-index', () => { 9 | const { distDir, job } = createJob({ 10 | directory: __dirname, 11 | }) 12 | it('should work with index file inside index directory', async () => { 13 | await assertFilesContent(distDir, { 14 | 'default.js': /'index'/, 15 | 'react-server.js': /\'react-server\'/, 16 | }) 17 | 18 | const stdout = stripANSIColor(job.stdout) 19 | expect(stdout).toContain('. dist/default.js') 20 | expect(stdout).toContain('. (react-server) dist/react-server.js') 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /test/integration/entry-index-index/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entry-index-index", 3 | "exports": { 4 | "react-server": "./dist/react-server.js", 5 | "default": "./dist/default.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/entry-index-index/src/index/index.js: -------------------------------------------------------------------------------- 1 | export const index = 'index' 2 | -------------------------------------------------------------------------------- /test/integration/entry-index-index/src/index/index.react-server.js: -------------------------------------------------------------------------------- 1 | export const index = 'react-server' 2 | -------------------------------------------------------------------------------- /test/integration/errors/compile-error/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "compile-error", 3 | "main": "./dist/index.js" 4 | } -------------------------------------------------------------------------------- /test/integration/errors/compile-error/src/index.tsx: -------------------------------------------------------------------------------- 1 | expor t functi on functi on App() { 2 | return
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 | --------------------------------------------------------------------------------