Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use Storybook as expected in a monorepo #5949

Closed
maecapozzi opened this issue Mar 7, 2019 · 26 comments
Closed

Unable to use Storybook as expected in a monorepo #5949

maecapozzi opened this issue Mar 7, 2019 · 26 comments

Comments

@maecapozzi
Copy link

Describe the bug
I am working in a lerna-managed monorepo with Typescript. Originally, we had a separate storybook configuration in each package, which worked nicely. We decided we wanted a root-level storybook that pulled from the *.stories.tsx files inside each package.

Here is an example of the desired file structure:

root
.storybook
packages
  +-- package1
    +-- Button.stories.tsx
  +-- package2
    +-- FancyButton.stories.tsx

After following the fix in this issue to solve our original exports not found error, we had no more error messages, but also no stories appeared.

After digging into the devtools for some time, we found that the stories were being read, and the correct paths were being generated. It looked like at some point they were unexpectedly cleared from the StoryStore.

Is this expected behavior? Is it possible to create a top-level storybook that reads from stories inside of packages in a lerna-managed monorepo?

Expected behavior
I expected to see a working storybook with stories from all of my packages in it.

Code snippets

webpack.config.js

module.exports = (baseConfig, env, config) => {
  // There is a bug in storybook for monorepo users.
  // Lines 5 - 12 are a temporary fix for this problem found in this issue:
  // https://github.com/storybooks/storybook/issues/3346#issuecomment-425516669
  config.module.rules = config.module.rules.filter(
    rule =>
      !(
        rule.use &&
        rule.use.length &&
        rule.use.find(({ loader }) => loader === 'babel-loader')
      )
  );
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: require.resolve('babel-loader'),
    options: {
      presets: [
        [
          'react-app',
          {
            flow: false,
            typescript: true,
          },
        ],
      ],
    },
  });
  config.resolve.extensions.push('.ts', '.tsx');
  return config;
};

config.ts

import { configure } from '@storybook/react';
// automatically import all files ending in *.stories.tsx
const req = require.context('../packages', true, /.stories.tsx$/);

function loadStories() {
  req.keys().forEach(req);
}

configure(loadStories, module);

System:

  • MacOS
  • Macbook Pro mid-2015
  • chrome
  • react
  • @storybook/react@4.1.6

Additional context
I ended up just creating a top-level /stories folder and moving all of my packages into it. That works nicely. I'd just like to understand why the structure I was originally aiming for doesn't work.

@maecapozzi
Copy link
Author

maecapozzi commented Mar 7, 2019

@shilman, if possible, you might consider adding a lerna tag to this as well. I have a hunch that this problem is more lerna-related than typescript-related.

@shilman
Copy link
Member

shilman commented Mar 8, 2019

We don't have a lerna tag -- compatibility with other tools is our catchall. If I see a lot more lerna-related issues I'll def create one.

@tmeasday
Copy link
Member

tmeasday commented Mar 9, 2019

Hi @maecapozzi - I'm glad you figured out a workaround, but I'm wondering about the original issue. I wonder why you think it might be lerna related? Because of symlinks within node_modules? I would expect SB to just ignore node_modules when searching for stories, but I could be missing something.

OTOH maybe there is a more general issue with monorepos specifically with typescript? I know plenty of people (myself) included have a similar setup to what you originally described so there must be something different going on here.

@tmeasday
Copy link
Member

tmeasday commented Mar 9, 2019

Sorry I should add I guess what I did to work around #3346 is:

  const babelLoader = storybookBaseConfig.module.rules[0];
  babelLoader.exclude.push(
    path.resolve('./lib/components/node_modules'),
    /* etc */
  );

Which is perhaps a little simpler and less disruptive that what you posted...

@shilman
Copy link
Member

shilman commented Mar 9, 2019

Related: #5220

@maecapozzi
Copy link
Author

maecapozzi commented Mar 11, 2019

@tmeasday, I did think that maybe it had to do with the symlinks.

Alternatively, as I was digging into the dev tools, it looked like something called StoryStore was getting constantly recreated as storybook went into different packages, and losing its context.

@astrotim
Copy link

astrotim commented Mar 12, 2019

I am also unable to get SB5 working with our Lerna monorepo. We have a custom Webpack config which I haven't had any success updating to the single signature format. Initially it was blowing up on the .css files (we use PostCSS), and after some trial and error I progressed to it blowing up on the JSX parsing.

// webpack.config.js
module.exports = async ({ config, mode }) => {
  config.module.rules.push(babelLoader)
  config.module.rules.push(cssLoader)

  return config;
}

Storybook will run with above config if I only include a trivial example, however when I attempt to load a story with some of our monorepo components, I get a bunch of errors like:

Module parse failed: Unexpected token (13:6)
You may need an appropriate loader to handle this file type.

and

Module build failed (from ./node_modules/@storybook/core/node_modules/postcss-loader/src/index.js):
SyntaxError

(2:1) Unknown word

For comparison, my working SB4 custom Webpack config is

module.exports = storybookBaseConfig => {
  storybookBaseConfig.module.rules.push(babelLoader);
  storybookBaseConfig.module.rules.push(cssLoader);

  return storybookBaseConfig;
};

@mr-wildcard
Copy link

mr-wildcard commented Mar 12, 2019

@astrotim I'm having the exact same issue right now in our monorepo (not using Lerna though).

I temporarily fixed it by prefixing the import statement this way :

import '!style-loader!css-loader!highlight.js/styles/github-gist.css';

I never used Lerna but I don't feel like this is related to it... It might have to do with what I'd call webpack contexts switching : the custom webpack configuration we provide to Storybook somehow conflicts with what Storybook does internally.

Don't know if it'll help, but you might have a look to webpack resolveLoader.modules : https://webpack.js.org/configuration/resolve/#resolveloader
I kind of resolved some other painful issues with it.

@astrotim
Copy link

I actually now think my issue in unrelated to our monorepo environment, but my rather it is #6083

@stale stale bot added the inactive label Apr 4, 2019
@stale stale bot removed the inactive label Apr 4, 2019
@stale stale bot added the inactive label Apr 25, 2019
@sibelius
Copy link

I've got this error as well, any way to fix this or any workaround?

I've tried to include packages on our custom wepback config

config.module.rules[0].include = [path.join(cwd, 'src'), path.join(cwd, 'packages/')];

but it did not worked well

this is the error:

ReferenceError: exports is not defined
    at Module../packages/shared/dist/Valeu.js (MyEmail.story.tsx:41)
    at __webpack_require__ 

@stale stale bot removed the inactive label Apr 30, 2019
@Centerworx
Copy link

I am also having the same issue. My monorepo is just running yarn workspaces, no lerna. All of my packages are running typescript.

@sibelius
Copy link

sibelius commented May 4, 2019

Use latest alphas releases

@mbulfair
Copy link

I'm working with a monorepo as well, but the issue has something to do with css-loader, I am using style-loader/css-loader/postcss-loader with css modules, I'm trying to switch from styleguidst to storybook, and it hasn't been easy at all. I am not sure where the issue is but, I get the unknown word:
var content = require("!!../../../node_modules/css-loader/dist/cjs.js??ref--10-1!../../../node_modules/postcss-loader/src/index.js??ref--10-2!./button.module.css");

Using the beta.0 version of 5.1 as I needed the core-js v3 issue resolved.

@ux-engineer
Copy link

Just noticed this import is not working when using in a Lerna monorepository import '@fortawesome/fontawesome-svg-core/styles.css';. When copied @FortAwesome folder inside storybook folder's node_modules folder, the import started working (although can't get FA icons to show up yet)...

@stale stale bot added the inactive label Jun 10, 2019
@shilman shilman removed the inactive label Jun 10, 2019
@Jimmydalecleveland
Copy link
Contributor

Hello,
I'm using a monorepo of gatsby projects (gatsby-themes) and getting this error, only when importing Link from gatsby, no matter what I try:

ERROR in my-gatsby/node_modules/gatsby/cache-dir/gatsby-browser-entry.js 17:2
Module parse failed: Unexpected token (17:2)
You may need an appropriate loader to handle this file type.
| 
| const StaticQuery = props => (
>   <StaticQueryContext.Consumer>
|     {staticQueryData => {
|       if (
 @ ./src/baseComponents/Link/Link.stories.jsx 4:0-30
 @ . sync \.stories\.(js|jsx)$
 @ ./.storybook/config.js
 @ multi my-gatsby/node_modules/@storybook/core/dist/server/common/polyfills.js /my-gatsby/node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/config.js (webpack)-hot-middleware/client.js?reload=true

I feel certain this is an issue with monorepos and storybook (perhaps the combination with gatsby as well), because I have a gatsby starter project running just fine with storybook ( gatsby: 2.8.4 and @storybook/react: 5.1.3) after following this tutorial: https://www.gatsbyjs.org/docs/visual-testing-with-storybook/

I took that working gatsby starter and placed it in my monorepo, but not in a directory that uses yarn workspaces, and it also runs just fine. It only causes the error shown above when placed under a folder that uses yarn workspaces which handles node_modules at the root of the project.

I've tried adding a custom .storybook/.babelrc file, loading in the presets for env and react as well, but no luck there either.

@ndelangen
Copy link
Member

@Jimmydalecleveland run storybook with the --debug-webpack flag and it will print the webpack config for you.

Look at the loaders defined and you'll see there are exclude & include rules for the loaders responsible for transpiling code.

I think if you just remove the include property, it should start to work for you.

@Jimmydalecleveland
Copy link
Contributor

@ndelangen Thank you for the quick response. I solved this problem last night differently, and now that I've tried your suggestion and it also works, I'm not understanding why.

I pushed a separate include rule: path.resolve('../../node_modules/gatsby') because my understanding was that Gatsby has un-transpiled ES6 code and I saw from the Error I previously posted that it was failing when encountering JSX in my project's root /node_modules/gatsby. That worked, but I'm not sure why your suggestion works, since it is removing the include for the inner yarn workspace package. If you don't mind, could you explain that a bit?

If you need more context, here is the before and after log of what that config looks like after applying your suggestion:

// before deleting include rule
{
  test: /\.(mjs|jsx?)$/,
  use: [ { loader: 'babel-loader', options: [Object] } ],
  include: [ './my-project/themes/gatsby-theme-storybook' ],
  exclude: [ './my-project/themes/gatsby-theme-storybook/node_modules' ]
}

// after
{
  test: /\.(mjs|jsx?)$/,
  use: [ { loader: 'babel-loader', options: [Object] } ],
  exclude: [ './my-project/themes/gatsby-theme-storybook/node_modules' ]
}

And this is the line I was previously using that worked in ./my-project/themes/gatsby-theme-storybook/.storybook/webpack.config.js:
config.module.rules[0].include.push(path.resolve('../../node_modules/gatsby'))

Thanks again, I really appreciate it.

@ndelangen
Copy link
Member

@Jimmydalecleveland removing that include is on my todo list, but I'm afraid of it messing up people's setup, So I want to do it for the next major (6.0) I think.

My solution works because it simply removes all include filters.

Yours work, because... I have no freaking clue why. 😭 not enough context on the project file structure to really judge.

@Jimmydalecleveland
Copy link
Contributor

@ndelangen Ok, no problem. I'm pretty sure it is a very specific problem to monorepos with Gatsby and storybook not at the root of the project. Take care!

@hueter
Copy link

hueter commented Jul 2, 2019

thanks @Jimmydalecleveland, your fix worked for me! I also have a gatsby app inside a monorepo with yarn workspaces and kept getting an ambiguous error from nodemodules/gatsby when running yarn storybook

@stale stale bot added the inactive label Jul 23, 2019
@storybookjs storybookjs deleted a comment from stale bot Jul 24, 2019
@stale stale bot removed the inactive label Jul 24, 2019
@stale stale bot added the inactive label Aug 15, 2019
@stale stale bot closed this as completed Sep 14, 2019
@DmitryEfimenko
Copy link

this should not be closed. This issue will only be more important with the rise of Nrwl NX

@ndelangen
Copy link
Member

ndelangen commented Nov 15, 2019

#8822 288cb50

@ndelangen
Copy link
Member

PR is open addressing this, will be a 6.0.0 feature

@storybookjs storybookjs deleted a comment from stale bot Nov 15, 2019
@storybookjs storybookjs deleted a comment from stale bot Nov 15, 2019
@storybookjs storybookjs deleted a comment from stale bot Nov 15, 2019
@claudio-moya
Copy link

I also report this issue, when I want to load packages or files outside of node_modules I got the empty "exports" issue, in my case is like this:

.storybook/
  ...
  webpack.config.js
npm/
  my-custom-package/
     index.js    
     ...
src/
  ...
webpack.config.js

I solved patching the .storybook/webpack.config.js using @i-like-robots solution:

#3346 (comment)

@shilman
Copy link
Member

shilman commented Jan 21, 2020

Whoopee!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-alpha.0 containing PR #8822 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

@kvedantmahajan
Copy link

kvedantmahajan commented Jul 10, 2021

This is important. "@storybook/react": "^6.3.4", doesn't have it. Here is the main file. Only stories at root folder works and not inside any of packages/**

module.exports = {
  stories: [
    '../packages/**/*.stories.mdx',
    '../packages/**/*.stories.@(js|jsx|ts|tsx)'
  ],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials']
}

@shilman This is closed. Not sure why. What would be the workaround?

@claudio-moya Could you please post your patch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests