Custom output directories
Closed this issue · 5 comments
I'd like to migrate a project to tshy
, it's already in use and I'd like to avoid breaking changes.
However, the dist
structure is looking this way:
./dist — ESM build
./dist/cjs — CommonJS build
Is it possible to retain this arrangement?
No, it's not. But it shouldn't be a breaking change, it's just updating some paths in package.json. Why would that affect anything outside the package?
Why would that affect anything outside the package?
It's a react components library and consumers are currently importing those components individually for better tree-shaking by webpack, this way:
import Component from "that-library/components/Component";
and
import Component from "that-library/cjs/components/Component";
(some are using Jest for testing, so they use CJS version)
Each component is an entrypoint.
I think if change the dist
structure to esm
and commonjs
, it would be breaking, @isaacs
Yeah, there's no way to do that with tshy. It uses exports
conditions to decide whether to route to a commonjs or esm module.
You could, I guess, put the file at src/cjs/components/Component.tsx
or something, but then it'd be that-library/cjs/components/Component
for both esm and cjs.
The consumer should not know the shape of the dist folder or that it exists. They're not importing by file path, they're importing by export subpaths.
So, with tshy, you'd typically have the file at src/components/Component.tsx
, let's say.
That'll be built to both:
dist/esm/components/Component.js
anddist/commonjs/components/Component.js
In the package.json, you'll have:
{
"tshy": {
"exports": {
"./": "./src/index.ts",
"./components/Component": "./src/components/Component.tsx"
}
},
"": "this bit below here is built by tshy, not you"
"exports": {
"./components/Component": {
"import": {
"types": "./dist/esm/components/Component.d.ts",
"default": "./dist/esm/components/Component.js"
},
"require": {
"types": "./dist/commonjs/components/Component.d.ts",
"default": "./dist/commonjs/components/Component.js"
}
}
}
}
So, your user would do require("that-library/components/Component")
and get the CJS version, or import("that-library/components/Component")
for the ESM version. Same path either way, different results depending on import type.
So, if you switch to tshy, just delete all the /cjs/
strings from your jest import paths. And yes, if that's how you were doing it before, using the path to differentiate the type at the import site (instead of letting the conditional exports handle it) then that might be a breaking change to switch to tshy. You could make it non-breaking by kludging in the old paths explicitly, but I'd recommend deprecating them, at least.