Open lifeiscontent opened 3 years ago
@lifeiscontent ESM output is genuinely a challenge for many package maintainers, including me.
The biggest challenge is that, perhaps, for esm outputs, all the import/export statements must include the annoying 'js' extension. But if you use .js
in your typescript source, it's not quite typescript anymore and I doubt why typescript does not complain about that before transpilation.
My solution to that is to add .js
extension via babel with babel-plugin-add-import-extension
and babel-plugin-transform-default-named-imports
.
As for storybook, I'm not quite sure about your intention? For viewing stories or publishing storybook as a website, you don't need to add '.js'. It only becomes an issue if you want to export stories as ES module for other projects. But it's unrelated to storybook, but just your build system.
Hey @alvis, then intention here is that I have stories in the package I'm publishing, so when I import the typescript source of that package, storybook doesn't know how to handle the import path.
since storybook is a tool for development I'd expect it to know how to resolve these paths since it supports typescript.
@lifeiscontent In this case, what you need is a tool that transpile your tsx files to ES modules. Pure tsc
doesn't work, but rollup
or babel
with the plugins I mentioned above can do the job.
Storybook can only generate you a static web site.
@alvis the doc types for storybook wouldn't work if I did that, there's a known bug that only allows you to import typescript source, outside of node_modules.
It could be the case, I'm not sure, even with declaration file emitted? Maybe you can link the known issue here too.
CC: @shilman do you happen to know where the issue is for storybook not reading d.ts (compiled ts source for controls)
For others that wind up here, this is the answer: https://github.com/softwareventures/resolve-typescript-plugin
If you use baseUrl
/ pathMapping
, you will need to redefine your aliases using webpackFinal
& config.resolve.alias
since tsconfig-paths-webpack
plugin doesn't play nicely with resolve-typescript-plugin
. Example:
{
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.tsx?$/,
use: 'ts-loader',
})
/**
* Used in lieu of tsconfig-paths-webpack plugin since that doesn't
* play nicely with resolve-typescript-plugin. If a new folder is added (direct
* child of `src/`), it will need to be added here. :/ (but not tsconfig.json)
*/
config.resolve.alias = {
components: path.resolve(__dirname, '../src/components/'),
hocs: path.resolve(__dirname, '../src/hocs/'),
hooks: path.resolve(__dirname, '../src/hooks/'),
utils: path.resolve(__dirname, '../src/utils/'),
}
config.resolve.extensions = ['.js', '.jsx', '.json']
config.resolve.plugins = [
...(config.resolve.plugins || []),
/**
* See https://github.com/storybookjs/storybook/issues/15962
* and https://github.com/softwareventures/resolve-typescript-plugin
*/
new ResolveTypeScriptPlugin(),
/**
* Needed to support TS aliases.
*/
// new TsconfigPathsPlugin({
// extensions: config.resolve.extensions,
// }),
]
return config
},
}
I have a similar problem, but in my case I have a preset in .ts
which imports es module with .js
extension. So I use this preset like this:
// .storybook/main.ts
export default {
stories: ['../stories/**/*.stories.@(md|ts)x'],
addons: [
'@storybook/addon-postcss',
'@storybook/addon-essentials',
{
name: './../src/client/addon/preset',
options: { clientPort: 8000 },
},
],
features: {
previewCsfV3: true,
},
};
Solution from @as-zlynn-philipps sounds great, but this is a fix at Storybook level. Eventhough TS seems to accept ".js" even when the source a ".ts", you probably want to improve the bundle process instead to automatically add the ".js" extension. This ticket shows a possible solution with Esbuild: https://github.com/evanw/esbuild/issues/622
Edit: after more research, fix at Storybook level is the right solution. This issue may also affect Jest or other Webpack based development tooling that loads the TypeScript source.
This problem is still present - would be great if someone had the time to look at it !
I confirm that @as-zlynn-philipps 's answer still works, and the comment around the path resolution is also pertinent. I also ended up having to comment out the TsConfigPathsPlugin and find an alternative.
A potential easy fix would be to upgrade to webpack 5.74.0 that includes the fix. On storybook's side, we could provide a safe default to map .js to .ts when typescript is being used. Would there be any downsides to that ?
Describe the bug I'm creating a UI Library that is distributed as a ES Module.
in typescript, to create an ES Module compliant package you must import/export all paths as
.js
as outlined here: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99cstorybook does not currently infer these paths and will fail to find the .ts files during development.
in order to provide a great developer experience, storybook should support this functionality.
To Reproduce
https://github.com/lifeiscontent/storybook-repro
System
Additional context
thanks for your help ❤️