A module requiring 'fs' does not work inside storybook, but does work in-browser

Viewed 846

I've got a basic create-react-app setup. A part of the CRA application is a lexer and a parser generated by antlr4ts.

In-browser, everything runs fine.

However, Storybook (installed via npx sb init) refuses to build, throwing:

ERROR in ./node_modules/antlr4ts/misc/InterpreterDataReader.js
Module not found: Error: Can't resolve 'fs' in '/home/rijndael/projects/antlr-truth-table-generator/node_modules/antlr4ts/misc'
 @ ./node_modules/antlr4ts/misc/InterpreterDataReader.js 16:11-24
 @ ./node_modules/antlr4ts/misc/index.js
 @ ./src/antlr/index.ts
 @ ./src/store/slices/tables/index.ts
 @ ./src/components/TruthTable/index.tsx
 @ ./src/components/TruthTable/stories/index.stories.tsx
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)stories\/(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js ./node_modules/webpack-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined

Indeed, a module I'm requiring has import { Interval } from "antlr4ts/misc";.

However, antlr4ts/misc/index.js doesn't seem to require InterpreterDataReader. Perhaps one of its children does, however why it's then not listed in the require stack trace?

antlr4ts/misc/index.js

__export(require("./ANTLRInputStream"));
__export(require("./BailErrorStrategy"));
__export(require("./BufferedTokenStream"));
__export(require("./CharStreams"));
__export(require("./CodePointBuffer"));
__export(require("./CodePointCharStream"));
__export(require("./CommonToken"));
__export(require("./CommonTokenFactory"));
__export(require("./CommonTokenStream"));
__export(require("./ConsoleErrorListener"));
__export(require("./DefaultErrorStrategy"));
__export(require("./Dependents"));
__export(require("./DiagnosticErrorListener"));
__export(require("./FailedPredicateException"));
__export(require("./InputMismatchException"));
__export(require("./InterpreterRuleContext"));
__export(require("./IntStream"));
__export(require("./Lexer"));
__export(require("./LexerInterpreter"));
__export(require("./LexerNoViableAltException"));
__export(require("./ListTokenSource"));
__export(require("./NoViableAltException"));
__export(require("./Parser"));
__export(require("./ParserInterpreter"));
__export(require("./ParserRuleContext"));
__export(require("./ProxyErrorListener"));
__export(require("./ProxyParserErrorListener"));
__export(require("./RecognitionException"));
__export(require("./Recognizer"));
__export(require("./RuleContext"));
__export(require("./RuleContextWithAltNum"));
__export(require("./RuleDependency"));
__export(require("./RuleVersion"));
__export(require("./Token"));
__export(require("./TokenStreamRewriter"));
__export(require("./VocabularyImpl"));

Inside InterpreterDataReader.js we indeed do have a const fs = require("fs");. However, it's no less weird, as everything does run when built by react-scripts.

  • How do I make it run inside Storybook as well?
  • Why does it run when built by react-scripts, but not inside Storybook?

.storybook/main.js:

module.exports = {
  "stories": [
    "../src/**/stories/*.stories.mdx",
    "../src/**/stories/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [

  ]
}

Update

I fixed it by importing directly import { Interval } from "antlr4ts/misc/Interval";, thus omitting the giant require block in antlr4ts/misc/index.js. However, I'm no less interested in why it runs inside the browser, but not in Storybook.

0 Answers
Related