-
Notifications
You must be signed in to change notification settings - Fork 135
build: migrate from webpack to tsdown #1254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
christopherthielen
commented
Feb 9, 2026
- Replace webpack with tsdown for library bundling
- Output ESM (.mjs) and CJS (.cjs) for bundlers
- Output IIFE bundles for browsers (includes @uirouter/core)
- Remove webpack, ts-loader, cross-env, tsconfig-paths-webpack-plugin
- Remove tweak_sourcemap_paths and fixmaps scripts
- Update package.json exports for dual ESM/CJS
- Modernize tsconfig.json (ES2020 target, bundler resolution)
- Replace webpack with tsdown for library bundling - Output ESM (.mjs) and CJS (.cjs) for bundlers - Output IIFE bundles for browsers (includes @uirouter/core) - Remove webpack, ts-loader, cross-env, tsconfig-paths-webpack-plugin - Remove tweak_sourcemap_paths and fixmaps scripts - Update package.json exports for dual ESM/CJS - Modernize tsconfig.json (ES2020 target, bundler resolution)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Migrate the library build pipeline from webpack to tsdown, producing modern ESM/CJS outputs plus browser-friendly IIFE bundles, and updating packaging metadata accordingly.
Changes:
- Remove webpack bundling configuration and dependencies.
- Add
tsdown.config.tsto build ESM/CJS + IIFE (min/non-min) bundles. - Update
package.jsonexports/entrypoints and tighten published files via.npmignore.
Reviewed changes
Copilot reviewed 4 out of 7 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
webpack.config.js |
Removes legacy webpack UMD bundling configuration. |
tsdown.config.ts |
Adds tsdown build definitions for ESM/CJS and browser IIFE outputs. |
package.json |
Updates package entrypoints/exports for dual ESM+CJS and switches build script to tsdown. |
.npmignore |
Adjusts npm publish exclusions for the new toolchain/config files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "type": "module", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.mts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/index.d.mts", | ||
| "import": "./dist/index.mjs", | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The published type entrypoints look inconsistent with what most TS declaration emitters produce. dts: true commonly generates *.d.ts (not *.d.mts/*.d.cts), and if those files aren’t actually emitted into dist/, TypeScript consumers will fail to resolve types. Consider updating types/exports.types to point at the actual emitted declaration filenames (often ./dist/index.d.ts), or adjust the build so it truly emits both index.d.mts and index.d.cts.
| "types": "./dist/index.d.mts", | ||
| "import": "./dist/index.mjs", | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exports shape is atypical: nesting "types" under "require" is not a standard Node condition and is likely to be ignored by Node, and may not be interpreted by TypeScript the way you intend. Prefer either (a) keep "require" as a string target and provide a top-level "types" target, or (b) use a conditional "types" object keyed by "import"/"require" while keeping runtime "import"/"require" targets as strings.
| "types": "./dist/index.d.mts", | |
| "import": "./dist/index.mjs", | |
| "require": { | |
| "types": "./dist/index.d.cts", | |
| "default": "./dist/index.cjs" | |
| } | |
| "types": { | |
| "import": "./dist/index.d.mts", | |
| "require": "./dist/index.d.cts" | |
| }, | |
| "import": "./dist/index.mjs", | |
| "require": "./dist/index.cjs" |
tsdown.config.ts
Outdated
| external: ['react', 'react-dom', 'react/jsx-runtime'], | ||
| noExternal: ['@uirouter/core', 'prop-types', 'classnames'], | ||
| outDir: 'dist', | ||
| globalName: 'UIRouterReact', | ||
| platform: 'browser', | ||
| outputOptions: { | ||
| globals: { | ||
| react: 'React', | ||
| 'react-dom': 'ReactDOM', | ||
| 'react/jsx-runtime': 'React', | ||
| }, | ||
| }, |
Copilot
AI
Feb 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the IIFE browser build, mapping 'react/jsx-runtime' to the 'React' global is very likely incorrect: React’s UMD global typically does not expose the jsx/jsxs runtime as React.jsx in a way that satisfies react/jsx-runtime imports. This can lead to runtime failures in the IIFE bundle. Consider bundling react/jsx-runtime into the IIFE outputs (remove it from external for IIFE), or map it to the correct global that the jsx-runtime UMD build provides (and document that requirement for script-tag consumers).
Mapping react/jsx-runtime to the React global doesn't work because
React's UMD global doesn't expose jsx/jsxs as top-level properties.
Instead, bundle the tiny jsx-runtime shim into the IIFE output — its
internal require('react') still resolves to the React global.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>