Storybook: [Angular] Storybook doesn't work with non-relative imports

Created on 11 Jan 2018  路  12Comments  路  Source: storybookjs/storybook

Non-relative imports like this

import {TestComponent} from "app/test/test.component"

doesn't work in stories file

stories/index.stories.ts
Module not found: Error: Can't resolve 'app/test/test.component' in 'stories'



md5-06d5770899041cc78da8b91fd8be9828



import {TestComponent} from "../src/app/test/test.component"

but if test.component has non-relative import it would have the same error

storybook/angular 3.4.0-alpha.1

angular has workaround question / support

Most helpful comment

A possible workaround could be this - https://github.com/storybooks/storybook/issues/2616#issuecomment-360973839
I've seen some other solutions, for example adding plugin - https://github.com/s-panferov/awesome-typescript-loader#advanced-path-resolution-in-typescript-20

I think we will need to add something like this by default to storybook.

All 12 comments

Same thing is happening with create-react-app.

Edit:

Resolved the CRA issue by adding NODE_PATH=src in my package.json

 "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "storybook": "NODE_PATH=src start-storybook -p 9009 -s public",
    "build-storybook": "build-storybook -s public"
  }

Although it would be nice if it read from my .env file.

By "non-relative imports", you mean paths mapping in tsconfig.json?

I have the same problem: "Module not found: Error: Can't resolve '@gorila/core/utils'"

in tsconfig.json:
{ ... "paths": { "@env/*": ["src/environments/*"], } ... }

A possible workaround could be this - https://github.com/storybooks/storybook/issues/2616#issuecomment-360973839
I've seen some other solutions, for example adding plugin - https://github.com/s-panferov/awesome-typescript-loader#advanced-path-resolution-in-typescript-20

I think we will need to add something like this by default to storybook.

I have set following code in webpack.config.js

const path = require('path');
const genDefaultConfig = require('@storybook/angular/dist/server/config/defaults/webpack.config.js');
module.exports = (baseConfig, env) => {
  const config = genDefaultConfig(baseConfig, env);
  const lib_path = path.join( __dirname ,  "../src/lib" );
  config.resolve.alias['@lib-path'] = lib_path;
  return config;
};

this setting has solved the issue.

https://github.com/storybooks/storybook/issues/3258
Please see this in detail

The workaround by @morninng almost worked with few adjustments:
I'm using @storybook/angular of version 4.0.0-alpha.10. Because of that, the following line of code didn't work:

const genDefaultConfig = require('@storybook/angular/dist/server/config/defaults/webpack.config.js');

This file does not exist.
I had to patch baseConfig object and adjust baseConfig.entry.styles. For some reason the path there was not right.

@DmitryEfimenko , can you please share your result for sake of clarity

sure, below is the final webpack.config.js that worked for me. It's more of a generalized solution, which looks for tsconfig.json file, parses its options and applies them to webpack config:

const path = require('path');
var fs = require("fs");
const findUp = require('find-up');

module.exports = (baseConfig) => {
  const tsFile = findUp.sync('tsconfig.json');
  const tsConfig = JSON.parse(fs.readFileSync(tsFile));
  const root = path.join(path.dirname(tsFile), tsConfig.compilerOptions.baseUrl);
  if (!baseConfig.resolve.alias) {
    baseConfig.resolve.alias = {};
  }
  for (const prop in tsConfig.compilerOptions.paths) {
    // expects something like: "@pwa/*": ["projects/pwa/src/app/*"]
    const val = tsConfig.compilerOptions.paths[prop][0];
    const alias = prop.substring(0, prop.length - 2);
    const resolvePath = val.substring(0, val.length - 2);
    baseConfig.resolve.alias[alias] = path.join(root, resolvePath);
  }

  baseConfig.entry.styles[0] = baseConfig.entry.styles[0].replace('\\projects\\pwa\\projects\\pwa', '\\projects\\pwa');
  return baseConfig;
};

Notice the shenanigans with baseConfig.entry.styles[0]. This is due to the issue where original value looks something like this: C:\Source\PM-for-random-tests\client-ng6\projects\pwa\projects\pwa\src\css\styles.scss. notice the double projects\pwa. I have no idea why that's the case

By the way, I think I understand why the issue with styles came around. It's probably worth opening a new issue specifically for that. Anyhow, the command I run to start storybook is:

start-storybook -p 9001 -c projects/pwa/.storybook

As you can see, my project is in projects/pwa, but storybook thinks it's in the current working directory.
This issue will be more relevant for ng6 projects which support monorepo style libraries.

Thanks @DmitryEfimenko

Here is a storybook 5.1 version equivalent (except for the 'style' part) :

const path = require('path');
var fs = require("fs");
const findUp = require('find-up');

module.exports = ({ config, mode }) => {
  const tsFile = findUp.sync('tsconfig.json');
  const tsConfig = JSON.parse(fs.readFileSync(tsFile));
  const root = path.join(path.dirname(tsFile), tsConfig.compilerOptions.baseUrl);
  if (!config.resolve.alias) {
    config.resolve.alias = {};
  }
  for (const prop in tsConfig.compilerOptions.paths) {
    // expects something like: "@pwa/*": ["projects/pwa/src/app/*"]
    const val = tsConfig.compilerOptions.paths[prop][0];
    const alias = prop.substring(0, prop.length - 2);
    const resolvePath = val.substring(0, val.length - 2);
    config.resolve.alias[alias] = path.join(root, resolvePath);
  }
  return config;
}

MMM, why do I still have to do this ?
According to @igor-dv 's merge request it should be native, no ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

miljan-aleksic picture miljan-aleksic  路  3Comments

dnlsandiego picture dnlsandiego  路  3Comments

sakulstra picture sakulstra  路  3Comments

shilman picture shilman  路  3Comments

ZigGreen picture ZigGreen  路  3Comments