storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.58k stars 9.3k forks source link

[Bug]: Cannot use import statement outside a module #24089

Open daviddelusenet opened 1 year ago

daviddelusenet commented 1 year ago

Describe the bug

Hello everyone!

My project is monorepo setup with Turborepo. The structure of the project is the following

apps
  docs
  e2e
  web
packages
  icons
  ui

In the ui package is where my Storybook installation lives. Today I decided to start the migration from Storybook 6 to version 7.

After the migration I get the following error when running storybook dev:

Failed to load preset: {"name":"/Users/david.lusenet/Development/website/node_modules/@storybook/addon-storysource/preset.js"} on level 2
/Users/david.lusenet/Development/website/node_modules/@storybook/addon-storysource/preset.js:1
import './dist/preset';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1176:20)
    at Module._compile (node:internal/modules/cjs/loader:1218:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Object.newLoader (/Users/david.lusenet/Development/website/node_modules/esbuild-register/dist/node.js:2262:9)
    at extensions..js (/Users/david.lusenet/Development/website/node_modules/esbuild-register/dist/node.js:4807:24)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at interopRequireDefault (/Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:37:21)
    at getContent (/Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:44:332)
    at loadPreset (/Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:44:517)
    at /Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:46:411
    at Array.map (<anonymous>)
    at loadPresets (/Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:46:393)
    at loadPreset (/Users/david.lusenet/Development/website/node_modules/@storybook/core-common/dist/index.js:44:958)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

This is my how my Storybook main.js files look like:

import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { dirname, join } from 'path';

const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
  stories: ['../**/*.stories.@(ts|tsx|mdx)'],

  typescript: {
    reactDocgen: 'none',
  },

  features: {
    emotionAlias: false,
  },

  staticDirs: ['../../../apps/web/public'],

  addons: [
    getAbsolutePath('storybook-addon-swc'),
    getAbsolutePath('@storybook/addon-actions'),
    getAbsolutePath('@storybook/addon-docs'),
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-controls'),
    getAbsolutePath('@storybook/addon-storysource'),
    getAbsolutePath('@storybook/addon-viewport'),
  ],

  webpackFinal: async config => {
    // Add Vanilla-Extract and MiniCssExtract Plugins
    config.plugins?.push(new VanillaExtractPlugin(), new MiniCssExtractPlugin());

    // Exclude vanilla extract's "*.vanilla.css" files from other "*.css" processing
    config.module?.rules?.forEach(rule => {
      if (typeof rule !== 'string' && rule.test instanceof RegExp && rule.test.test('test.css')) {
        rule.exclude = /\.vanilla\.css$/i;
      }
    });

    config.module?.rules?.push({
      // Targets only CSS files generated by vanilla-extract
      test: /\.vanilla\.css$/i,
      use: [
        MiniCssExtractPlugin.loader,
        {
          loader: require.resolve('css-loader'),
          options: {
            // Required as image imports should be handled via JS/TS import statements
            url: false,
          },
        },
      ],
    });

    config.resolve = {
      ...config.resolve,
      plugins: [
        /** Make sure storybook handles aliases like import 'components/Button */
        new TsconfigPathsPlugin({
          configFile: path.resolve(__dirname, '../tsconfig.json'),
        }),
      ],
      roots: [
        /** Server .../public as a root to serve static files loaded through css */
        path.resolve(__dirname, '../public'),
      ],
    };

    return config;
  },

  framework: {
    name: getAbsolutePath('@storybook/nextjs'),
    options: {},
  },

  docs: {
    autodocs: true,
  },
};

function getAbsolutePath(value) {
  return dirname(require.resolve(join(value, 'package.json')));
}

One thing I'm sure about, it's not related to the Vanilla-Extract setup because the error was already happening before I added that.

When I just remove the getAbsolutePath('@storybook/addon-storysource') everything works fine.

Does anyone have any idea on how to fix this?

Please let me know if you need any more information and thanks in advance!

To Reproduce

No response

System

Environment Info:

  System:
    OS: macOS 13.4
    CPU: (10) arm64 Apple M1 Pro
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    Yarn: 3.3.1 - ~/.nvm/versions/node/v18.16.0/bin/yarn
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
  Browsers:
    Chrome: 116.0.5845.140
    Safari: 16.5

Additional context

No response

daviddelusenet commented 1 year ago

Any updates on this?

Dremora commented 1 year ago

Probably not related, but you don't need new TsconfigPathsPlugin, since @storybook/next already handles that.

nouman91 commented 1 year ago

I am also getting the same error in the addon-storysource package:

My setup:

   "@storybook/addon-a11y": "7.4.6",
    "@storybook/addon-actions": "7.4.6",
    "@storybook/addon-controls": "7.4.6",
    "@storybook/addon-docs": "7.4.6",
    "@storybook/addon-essentials": "7.4.6",
    "@storybook/addon-storysource": "7.4.6",
    "@storybook/addons": "7.4.6",
    "@storybook/api": "7.4.6",
    "@storybook/components": "7.4.6",
    "@storybook/core-events": "7.4.6",
    "@storybook/react": "7.4.6",
    "@storybook/react-webpack5": "7.4.6",
    "@storybook/theming": "7.4.6",

main.js file:

import { dirname, join } from 'path';
// Case Sensitive partial filename of Story
const storyName = process.argv[6];

const stories = storyName
  ? `../src/**/?(*)${storyName}?(*).stories.{mdx,tsx}`
  : '../src/**/*.stories.{mdx,tsx}';

module.exports = {
  addons: [
    getAbsolutePath('@storybook/addon-a11y'),
    getAbsolutePath('@storybook/addon-actions'),
    getAbsolutePath('@storybook/addon-docs'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-controls'),
    getAbsolutePath('@storybook/addon-storysource'),
    getAbsolutePath('storybook-dark-mode'),
  ],

  framework: {
    name: getAbsolutePath('@storybook/react-webpack5'),
    options: {},
  },

  features: {
    postcss: false,
    storyStoreV7: false,
  },
  staticDirs: ['../public'],
  stories: [stories],
};

function getAbsolutePath(value) {
  return dirname(require.resolve(join(value, 'package.json')));
}

Error log:

node_modules/@storybook/addon-storysource/preset.js:1
import './dist/preset';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:360:18)
    at wrapSafe (node:internal/modules/cjs/loader:1124:15)
    at Module._compile (node:internal/modules/cjs/loader:1160:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1250:10)
the-simian commented 1 year ago

I want to report I am getting a similar error with "@storybook/addon-storysource": "^7.5.2", so this error is still present in the latest version. There is an issue with the import statement inside of storysource preset.js

Here is my config:

/** @type { import('@storybook/nextjs').StorybookConfig } */
const config = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-interactions'),
    getAbsolutePath('@storybook/addon-a11y'),
    getAbsolutePath('@storybook/addon-storysource'), //<---------------commenting this out and storybook builds correctly
    getAbsolutePath('@etchteam/storybook-addon-status'),
    {
      name: '@storybook/addon-styling',
      options: {
        // Check out https://github.com/storybookjs/addon-styling/blob/main/docs/api.md
        // For more details on this addon's options.
        postCss: {
          implementation: require.resolve('postcss'),
        },
      },
    },
    getAbsolutePath('@storybook/addon-themes'),
    getAbsolutePath('@storybook/addon-mdx-gfm'),
  ],
  framework: {
    name: getAbsolutePath('@storybook/nextjs'),
    options: {},
  },
  docs: {
    autodocs: 'tag',
  },
};
export default config;

here's the current versions of my deps I am using:

    "@etchteam/storybook-addon-status": "^4.2.4",
    "@storybook/addon-a11y": "^7.5.2",
    "@storybook/addon-essentials": "7.5.1",
    "@storybook/addon-interactions": "7.5.1",
    "@storybook/addon-links": "7.5.1",
    "@storybook/addon-mdx-gfm": "7.5.1",
    "@storybook/addon-onboarding": "1.0.8",
    "@storybook/addon-storysource": "^7.5.2",
    "@storybook/addon-styling": "1.3.7",
    "@storybook/addon-themes": "7.5.1",
    "@storybook/blocks": "7.5.1",
    "@storybook/nextjs": "7.5.1",
    "@storybook/react": "7.5.1",
    "@storybook/testing-library": "0.2.2",

Here are the relvant parts of the trace:

SB_CORE-SERVER_0002 (CriticalPresetLoadError): 
Storybook failed to load the following preset: 
my-project/node_modules/@storybook/addon-storysource/preset.js.

/my-project/node_modules/@storybook/addon-storysource/preset.js:1
import './dist/preset';
^^^^^^
SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1153:20)
    at Module._compile (node:internal/modules/cjs/loader:1197:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
    at Object.newLoader (/my-project/node_modules/esbuild-register/dist/node.js:2262:9)
    at extensions..js (/my-project/node_modules/esbuild-register/dist/node.js:4838:24)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at Module.require (node:internal/modules/cjs/loader:1115:19)
    at require (node:internal/modules/helpers:119:18)

Here's the exact line in the source code: https://github.com/storybookjs/storybook/blob/next/code/addons/storysource/preset.js#L1 , on the next branch.

mikematos84 commented 11 months ago

I am also receiving the same error.

$ yarn storybook
@storybook/cli v7.5.3

SB_CORE-SERVER_0002 (CriticalPresetLoadError): Storybook failed to load the following preset: .\.storybook\main.js.

Please check whether your setup is correct, the Storybook dependencies (and their peer dependencies) are installed correctly and there are no package version clashes.

If you believe this is a bug, please open an issue on Github.

SB_CORE-SERVER_0002 (CriticalPresetLoadError): Storybook failed to load the following preset: E:\Projects\Personal\monorepo\node_modules\@storybook\addon-storysource.

Please check whether your setup is correct, the Storybook dependencies (and their peer dependencies) are installed correctly and there are no package version clashes.

If you believe this is a bug, please open an issue on Github.

SB_CORE-SERVER_0002 (CriticalPresetLoadError): Storybook failed to load the following preset: E:\Projects\Personal\monorepo\node_modules\@storybook\addon-storysource\preset.js.

Please check whether your setup is correct, the Storybook dependencies (and their peer dependencies) are installed correctly and there are no package version clashes.

If you believe this is a bug, please open an issue on Github.

E:\Projects\Personal\monorepo\node_modules\@storybook\addon-storysource\preset.js:1
import './dist/preset';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1149:20)
    at Module._compile (node:internal/modules/cjs/loader:1190:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1280:10)
    at Object.newLoader (E:\Projects\Personal\monorepo\node_modules\esbuild-register\dist\node.js:2262:9)
    at extensions..js (E:\Projects\Personal\monorepo\node_modules\esbuild-register\dist\node.js:4838:24)
    at Module.load (node:internal/modules/cjs/loader:1089:32)
    at Module._load (node:internal/modules/cjs/loader:930:12)
    at Module.require (node:internal/modules/cjs/loader:1113:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at loadPreset (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:82)
    at loadPreset (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:82)
    at async Promise.all (index 4)
    at async loadPresets (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:505)
    at async loadPreset (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:13:1025)
    at async Promise.all (index 1)
    at async loadPresets (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:505)
    at async getPresets (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:1525)
    at async buildDevStandalone (E:\Projects\Personal\monorepo\node_modules\@storybook\core-server\dist\index.js:119:1599)
    at async withTelemetry (E:\Projects\Personal\monorepo\node_modules\@storybook\core-server\dist\index.js:103:3903)
    at async dev (E:\Projects\Personal\monorepo\node_modules\@storybook\cli\dist\generate.js:473:401)
    at loadPreset (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:82)
    at async Promise.all (index 1)
    at async loadPresets (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:505)
    at async getPresets (E:\Projects\Personal\monorepo\node_modules\@storybook\core-common\dist\index.js:15:1525)
    at async buildDevStandalone (E:\Projects\Personal\monorepo\node_modules\@storybook\core-server\dist\index.js:119:1599)
    at async withTelemetry (E:\Projects\Personal\monorepo\node_modules\@storybook\core-server\dist\index.js:103:3903)
    at async dev (E:\Projects\Personal\monorepo\node_modules\@storybook\cli\dist\generate.js:473:401)
    at async Command.<anonymous> (E:\Projects\Personal\monorepo\node_modules\@storybook\cli\dist\generate.js:475:225)

WARN Broken build, fix the error above.
WARN You may need to refresh the browser.

WARN   Failed to load preset: {"name":"E:\\Projects\\Personal\\monorepo\\node_modules\\@storybook\\addon-storysource\\preset.js"} on level 2
E:\Projects\Personal\monorepo\node_modules\@storybook\addon-storysource\preset.js:1
import './dist/preset';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1149:20)
    at Module._compile (node:internal/modules/cjs/loader:1190:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1280:10)
    at Object.newLoader (E:\Projects\Personal\monorepo\node_modules\esbuild-register\dist\node.js:2262:9)
    at extensions..js (E:\Projects\Personal\monorepo\node_modules\esbuild-register\dist\node.js:4838:24)
    at Module.load (node:internal/modules/cjs/loader:1089:32)
    at Module._load (node:internal/modules/cjs/loader:930:12)
    at Module.require (node:internal/modules/cjs/loader:1113:19)
    at require (node:internal/modules/cjs/helpers:103:18)

main.js

const { dirname, join, resolve } = require('path');

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    getAbsolutePath('@storybook/addon-a11y'),
    getAbsolutePath('@storybook/addon-links'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@storybook/addon-interactions'),
    // Commenting the below out or just using the string without getAbsolutePath seems to work
    getAbsolutePath('@storybook/addon-storysource'),
    getAbsolutePath('storybook-dark-mode'),
    getAbsolutePath('storybook-addon-mock'),
    ...(process.env?.TRANSPILER === 'swc'
      ? [getAbsolutePath('storybook-addon-swc')]
      : [])
  ],
  framework: {
    name: getAbsolutePath('@storybook/nextjs'),
    options: {}
  },
  webpackFinal: async config => {
    // 👈 and add this here
    config.resolve.alias = {
      ...config.resolve.alias,
      '@': resolve(__dirname, '../src/')
    };
    return config;
  },
  docs: {
    autodocs: true
  }
};

function getAbsolutePath(value) {
  return dirname(require.resolve(join(value, 'package.json')));
}

package.json

{
    ...
    "devDependencies": {
        "@storybook/addon-a11y": "^7.5.3",
        "@storybook/addon-actions": "^7.5.3",
        "@storybook/addon-docs": "^7.5.3",
        "@storybook/addon-essentials": "^7.5.3",
        "@storybook/addon-interactions": "^7.5.3",
        "@storybook/addon-links": "^7.5.3",
        "@storybook/addon-storysource": "^7.5.3",
        "@storybook/nextjs": "^7.5.3",
        "@storybook/react": "^7.5.3",
        "@storybook/testing-library": "^0.2.2",
        "storybook": "7.5.3",
        "storybook-addon-mock": "^4.3.0",
        "storybook-addon-swc": "^1.2.0",
        "storybook-dark-mode": "^3.0.1",
    }
    ...
}

Note

It's also worth noting that in checking the preset.js files of all my other addons if one exists, it does not use import, but rather module.exports or requires, so it's commonjs. Is this just not getting transpiled correctly before packaging?

bozdoz commented 10 months ago

In my experience, you can remove the getAbsolutePath and it will work:

- getAbsolutePath('@storybook/addon-storysource'),
+ '@storybook/addon-storysource',