-
-
Notifications
You must be signed in to change notification settings - Fork 141
Description
Reproduction link or steps
From the minimal reproduction repository, run yarn && yarn build.
What is expected?
The 'minimal reproduction' library has a single dependency, keyframe-resample, and its package.json is worth mentioning. The dependency uses package.json#exports with node and default entrypoints. Both entrypoints load a .wasm resource in an intended-to-treeshake way, and the dependency sets sideEffects: false. The minimal reproduction does not import anything that depends on the WASM resource, importing only a single plain-JS resampleDebug function.
When I build with tsdown, I'm intending for this resampleDebug function to be resolved from the 'default' export (not the 'node' export) and inlined into the build, without leaving any traces of platform-specific WASM resources. I use the following tsdown config:
export default defineConfig({
entry: 'src/index.ts',
inlineOnly: ['keyframe-resample'],
target: 'esnext',
platform: 'browser', // compare: 'node', 'neutral', 'browser'
treeshake: true, // workaround: { moduleSideEffects: false, propertyReadSideEffects: false }
});What is actually happening?
Two things appear to be going wrong here:
- Despite
platform: 'browser'in my config, tsdown is resolvingkeyframe-resamplefrom node_modules/keyframe-resample/dist/keyframe-resample-node.modern.js for the CJS build, and from node_modules/keyframe-resample/dist/keyframe-resample-browser.modern.js for the ESM build. Referring tokeyframe-resample'spackage.jsonlinked above, I can't see why the Node.js build is being preferred over the browser-specific CJS or ESM builds. - An unused line remains, in the CJS build output only:
This line does break downstream code if left behind, so I'd like to make sure it tree-shakes.
const wasm = /* @__PURE__ */ (0, node_fs_promises.readFile)(/* @__PURE__ */ new URL("./release.wasm", require("url").pathToFileURL(__filename).href));
I have a workaround, I think, which involves configuring:
{
...
treeshake: { moduleSideEffects: false, propertyReadSideEffects: false }
}With this, the WASM resource is tree-shaken. tsdown is still using the Node.js-specific entrypoint for the CJS build, which surprises me, but with the WASM resource gone it's not breaking anything in this case.
Any additional comments?
I'm the author of the keyframe-resample package, and was previously bundling a library that depended on it using microbundle/rollup. I don't think microbundle fully supports package.json#exports but somehow this was still working alright. Building platform-agnostic libraries depending on WASM dependencies has been tricky for me historically, it's certainly possible there's a better approach than what I've done in keyframe-resample.
The actual project affected by this possible bug, which the minimal reproduction mimics, is https://gltf-transform.dev/.