storybook: Can't resolve fs, nothing helps

I’m installing the latest version of Storybook to my existing project. With initial templates which are coming with the install, everything’s ok. But when I’m trying to create a new story with one of my components it throws Can't resolve fs... Here’s my package.json

"dependencies": {
   "@date-io/core": "^1.3.6",
   "@date-io/date-fns": "^1.3.11",
   "@loadable/component": "^5.12.0",
   "@material-ui/core": "^4.11.2",
   "@material-ui/icons": "^4.9.1",
   "@material-ui/lab": "^4.0.0-alpha.55",
   "@material-ui/pickers": "^3.2.8",
   "axios": "^0.21.1",
   "axios-cancel": "^0.2.2",
   "chart.js": "^2.7.3",
   "chartjs-plugin-datasource-prometheus": "^1.0.6",
   "classnames": "^2.2.6",
   "connected-react-router": "^6.5.2",
   "date-fns": "^2.4.1",
   "file-saver": "^2.0.0",
   "google-libphonenumber": "^3.2.25",
   "history": "^4.7.2",
   "is-ip": "^3.1.0",
   "is-valid-hostname": "^1.0.1",
   "lodash-es": "^4.17.11",
   "material-table": "^1.69.3",
   "material-ui-phone-number": "^2.2.6",
   "moment": "^2.29.1",
   "object-hash": "^2.0.3",
   "password-generator": "^2.2.3",
   "prop-types": "^15.7.1",
   "react": "^16.8.6",
   "react-chartjs-2": "^2.8.0",
   "react-color": "^2.18.0",
   "react-confirm": "^0.1.18",
   "react-csv": "^2.0.3",
   "react-custom-scrollbars": "^4.2.1",
   "react-dom": "^16.8.6",
   "react-dropzone": "4.2.11",
   "react-flag-icon-css": "^1.0.25",
   "react-google-recaptcha-v3": "^1.7.0",
   "react-intl": "^2.8.0",
   "react-loading-overlay": "^1.0.1",
   "react-material-ui-form-validator": "^2.0.3",
   "react-redux": "^6.0.0",
   "react-router": "^5.1.0",
   "react-router-dom": "^5.1.0",
   "react-router-redux": "^4.0.8",
   "react-scripts": "3.4.4",
   "react-scrollable-feed": "^1.2.0",
   "react-select": "^3.0.5",
   "react-spinners": "^0.5.1",
   "react-stomp": "^5.0.0",
   "react-swipeable-views": "^0.13.9",
   "react-web-notification": "^0.8.0",
   "recompose": "latest",
   "redux": "^4.0.1",
   "redux-devtools-extension": "^2.13.8",
   "redux-form": "^8.1.0",
   "redux-localstorage": "^0.4.1",
   "redux-logger": "^3.0.6",
   "redux-thunk": "^2.3.0",
   "split-sms": "^0.1.7",
   "typeface-roboto": "^0.0.54",
   "validatorjs": "^3.15.1",
   "webstomp-client": "^1.2.6"
 },
 "devDependencies": {
   "@storybook/addon-actions": "^6.4.1",
   "@storybook/addon-essentials": "^6.4.1",
   "@storybook/addon-links": "^6.4.1",
   "@storybook/node-logger": "^6.4.1",
   "@storybook/preset-create-react-app": "^3.2.0",
   "@storybook/react": "^6.4.1",
   "env-cmd": "^10.1.0",
   "rimraf": "^2.6.3"
 },
 "browser": {
   "fs": false,
   "path": false,
   "os": false
 },

I tried to add this to webpack.config.js

const path = require('path');

module.exports = (storybookBaseConfig, configType) => {
  storybookBaseConfig.resolve.alias = {
    ...storybookBaseConfig.resolve.alias,
    'fs': path.resolve(__dirname, 'fsMock.js')
  };

  return storybookBaseConfig;
};

And this to fsMock.js

module.exports = {
  readFileSync: () => 'mock',
  // other things in fs that you are using
}

And this to main.js

webpackFinal: async (config, { configType }) => {
  config.resolve.alias = {
    ...config.resolve.alias,
    'fs': path.resolve(__dirname, 'fsMock.js')
  };
  return config
}

Yet still, nothing helps. With the previous version, everything worked fine, but the project had updates for dependencies so the storybook upgraded as well and since then nothing works. How to resolve it?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 23 (7 by maintainers)

Most upvoted comments

I tried config.resolve.fallback.fs = false, but it kept telling me that fallback was an invalid option.

This worked for me instead:

module.exports = {
  stories: ["../../src/directory/**/*.stories.tsx", "../../src/commons/**/*.stories.tsx"],
  addons: [
    "@storybook/addon-essentials",
    "@storybook/addon-a11y",
    "@storybook/preset-create-react-app"
  ],
  webpackFinal: (config) => {
    config.node = { fs: 'empty' }
    return config;
  },
};

@HuyAms Thanks for the hint, setting the fallback did it for me!

You can set it in the .storybook/main.js file in the webpackFinal property, see https://storybook.js.org/docs/react/configure/webpack#extending-storybooks-webpack-config

For example:

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
  ],
  framework: '@storybook/react',
  webpackFinal: (config) => {
    config.resolve.fallback.fs = false;

    return config;
  },
};

If you have Issues with typescript use something like this

const config: StorybookConfig = {
  stories: [
    "../src/components/**/*.stories.mdx",
    "../src/components/**/*.stories.@(js|jsx|ts|tsx)",
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook/nextjs",
    options: {},
  },
  docs: {
    autodocs: "tag",
  },
  webpackFinal: async (config) => {
    if (config.resolve?.fallback)
      config.resolve.fallback = { ...config.resolve.fallback, fs: false };
    return config;
  },
};
export default config;

Hi, I got the same issue with version 6.4.19 Can't resolve fs.... I am using Storybook with RemixJS

Also tried the solutions with fsMock and with webpackFinal as the OP mentioned but nothing works. I got this suggestion

Looks like storybook isn’t treeshaking out the node portions that are exported from “remix”. Since it’s webpack based you could look at setting the resolution of the node modules to “false”.

{
  resolve: {
    fallback: {
      fs: false
    }
  }
}

Do you know where I could set it in storybook?

This is probably because I’m using webpack 5.

same issue here…

So anyway, if you end up with similar issue, because you use alias, it is partially because alias takes precedence over anything else. More correct solution, according to the docs, might be using alias instead of falback.

Setting resolve.alias to false will tell webpack to ignore a module. https://webpack.js.org/configuration/resolve/#resolvealias

This will make it so that the module is ignored even if it’s actually installed in node_modules, which is more explicit than using fallback which only takes effect if the module is not found.

// alias module to another module/path or disable - takes precedence - https://webpack.js.org/configuration/resolve/#resolvealias
config.resolve.alias = {
  ...config.resolve.alias,
  fs: false,
}

Oh and btw, you can annotate the js config with ts types using JSDoc.

/.storybook/main.js

/** @type {import("../node_modules/@storybook/types/dist").StorybookConfig} */
module.exports = {
  webpackFinal: (/** @type {import('webpack').WebpackOptionsNormalized} */config, options) => {
    // config is typed here
    return config;
  },
}

@Apoerin if you do manage to find out more or have a repro, please let me know. if it’s affecting your project i’m sure it will affect other users as well and i’d love to track it down and fix! in the meantime, glad you have a workaround (even if it’s a pretty unsatisfying one!) 💯