@storybook/angular
is not resolving non-relative imports. I believe non-relative imports are a relative new feature of TypeScript that allow you to reference imports from a baseUrl
rather than always using relative imports to your own code.
I think that support for this feature should be a priority as VS Code will now rename all your modules to use non-relative imports automatically when you move/rename a file so its difficult problem to avoid.
Create a strorybook project with Angular 6.1.1 and use non-relative imports in your code, e.g.
src/app/somefile.ts
import { environment } from 'environments/environment';
// instead of import { environment } from '../environments/environment';
"@storybook/addon-actions": "^4.0.0-alpha.20",
"@storybook/addon-centered": "^4.0.0-alpha.20",
"@storybook/addon-knobs": "^4.0.0-alpha.20",
"@storybook/addon-links": "^4.0.0-alpha.20",
"@storybook/addon-notes": "^4.0.0-alpha.20",
"@storybook/addon-storysource": "^3.4.10",
"@storybook/addons": "^4.0.0-alpha.20",
"@storybook/angular": "^4.0.0-alpha.20",
Windows 10
I have managed to work around this using the TsconfigPathsPlugin
and modifying my tsconfig.json
file to use compilerOptions.paths
(note the mappings look slightly ridiculous).
.storybook/tsconfig.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "es2015",
"paths": {
"app/*": ["app/*"],
"pages/*": ["pages/*"],
"shared/*": ["shared/*"],
"environments/*": ["environments/*"]
}
},
"exclude": [
"../src/test.ts",
"../src/**/*.spec.ts",
"../src/**/*.stories.ts"
],
"include": ["../src/**/*"]
}
NB: compilerOptions.baseUrl
has a value of "./src" in my root tsconfig.json
.storybook/webpack.config.js
const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = (baseConfig, env, config) => {
config.resolve.plugins = config.resolve.plugins || [];
config.resolve.plugins.push(
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, '../tsconfig.json')
})
);
return config;
};
NB: The initial build is also excruciatingly slow, but I don't think its related.
Regarding the absolute paths, there was a similar issue - #3916. Maybe we should add 'baseUrl' to resolve.modules
by default 馃
For build time, please check this - #3968
Thanks @igor-dv its all working a treat now. And the build time has gone from 7 minutes down to 20 seconds 馃殫 馃挩
Here's my .storybook/webpack.config.js
for anyone that needs it, although hopefully this will be fixed in the angular storybook project soon.
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = (baseConfig, env, config) => {
// To get tsconfig baseUrl working
// There is likely a better way to extract the baseUrl from tsconfig.
config.resolve.modules.push(path.resolve(__dirname, '../src'));
// To dramatically increase the build speed.
let rule = config.module.rules.find(rule => {
const { loader } = rule.use[0];
return loader && loader.includes('ts-loader');
});
rule.use[0].options.transpileOnly = true;
config.plugins.push(
new ForkTsCheckerWebpackPlugin({
tslint: path.resolve(__dirname, '../tslint.json'),
tsconfig: path.resolve(__dirname, 'tsconfig.json')
})
);
return config;
};
@cwmrowe
adding this to the storybook webpack config works:
// To get tsconfig baseUrl working
// There is likely a better way to extract the baseUrl from tsconfig.
config.resolve.modules.push(path.resolve(__dirname, '../src'));
how does it work though? This seems specific to how webpack resolves module, and may or may not be directly co-related to how tsconfig is setup (?)
If it's useful to anyone, I'm doing this to avoid duplicating resolve.modules
and tsconfig.json
baseUrl
:
// webpack.config.js
const path = require('path');
const { compilerOptions } = require('./tsconfig.json');
module.exports = {
// other stuff
resolve: {
modules: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, compilerOptions.baseUrl),
],
},
};
I highly recommend using tsconfig-paths-webpack-plugin for aliases.
CC: @shilman - i feel like this is worth recommending at least in FAQ or maybe out of the box
setup:
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
webpackFinal: async (config) => {
config.resolve.plugins.push(new TsconfigPathsPlugin({}));
return config;
},
};
Most helpful comment
I highly recommend using tsconfig-paths-webpack-plugin for aliases.
CC: @shilman - i feel like this is worth recommending at least in FAQ or maybe out of the box
setup: