【问题标题】:How to resolve aliases in Storybook?如何解决 Storybook 中的别名?
【发布时间】:2021-06-01 07:42:52
【问题描述】:

我有一个带有 Storybook 的 React/Typescript 项目。 Storybook 很好用,但是一旦我开始导入带别名的文件,它就会崩溃。

例子:

import Foo from "@components/foo" => crash
import Foo from "../../components/foo" => ok

该应用可以正常使用别名。该问题仅与 Storybook 有关。

这是我的故事书配置:

module.exports = {
  stories: ["../**/stories.tsx"],
  webpackFinal: (config) => {
    return {
      ...config,
      module: {
        ...config.module,
        rules: [
          {
            test: /\.(ts|js)x?$/,
            exclude: /node_modules/,
            use: { loader: "babel-loader" },
          },
          { test: /\.css$/, use: ["style-loader", "css-loader"] },
          { test: /\.(png|jpg|gif)$/, use: ["file-loader"] },
          {
            test: /\.svg$/,
            use: [
              {
                loader: "babel-loader",
              },
              {
                loader: "react-svg-loader",
                options: {
                  jsx: true,
                },
              },
            ],
          },
        ],
      },
    };
  },
  typescript: {
    check: false,
    checkOptions: {},
    reactDocgen: "react-docgen-typescript",
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) =>
        prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,
    },
  },
};

我的 webpack 配置:

/* eslint-env node */
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const Dotenv = require("dotenv-webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const isProductionMode = (mode) => mode === "production";

module.exports = () => {
  const env = require("dotenv").config({ path: __dirname + "/.env" });
  const nodeEnv = env.parsed.NODE_ENV;
  return {
    mode: "development",
    entry: "./src/index.tsx",
    output: {
      path: path.join(__dirname, "./dist"),
      filename: "[name].[contenthash].bundle.js",
      publicPath: "/",
    },
    resolve: {
      extensions: [".ts", ".tsx", ".js", "jsx", ".json"],
      alias: {
    "@api": path.resolve(__dirname, "src/api/"),
    "@assets": path.resolve(__dirname, "src/assets/"),
    "@components": path.resolve(__dirname, "src/components/"),
    "@containers": path.resolve(__dirname, "src/containers/"),
    "@data": path.resolve(__dirname, "src/data/"),
    "@i18n": path.resolve(__dirname, "src/i18n/"),
    "@models": path.resolve(__dirname, "src/models/"),
    "@pages": path.resolve(__dirname, "src/pages/"),
    "@src": path.resolve(__dirname, "src/"),
    "@stores": path.resolve(__dirname, "src/stores/"),
    "@utils": path.resolve(__dirname, "src/utils/"),
  },
    },
    module: {
      rules: [
        {
          test: /\.(ts|js)x?$/,
          exclude: /node_modules/,
          use: { loader: "babel-loader" },
        },
        { test: /\.css$/, use: ["style-loader", "css-loader"] },
        { test: /\.(png|jpg|jpeg|gif)$/, use: ["file-loader"] },
        {
          test: /\.svg$/,
          use: [
            {
              loader: "babel-loader",
            },
            {
              loader: "react-svg-loader",
              options: {
                jsx: true,
              },
            },
          ],
        },
      ],
    },
    devServer: {
      historyApiFallback: true,
      port: 3000,
      inline: true,
      hot: true,
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: "./src/index.html",
      }),
      new Dotenv(),
    ],
    optimization: {
      minimize: isProductionMode(nodeEnv),
      minimizer: isProductionMode(nodeEnv) ? [new TerserPlugin()] : [],
      splitChunks: { chunks: "all" },
    },
  };
};

如何解决这个问题?我使用的是 webpack 5.24.2 和 storybook 6.1.20,所以这些是最新版本。

【问题讨论】:

  • 您是否尝试过在故事书配置中重复您的别名?不是 100% 肯定,但我认为传递给 webpackFinalconfig 是故事书的默认配置,并且对您的其他 webpack 配置一无所知。您可以尝试在 webpackFinal 中使用 console.logging config 进行确认。编辑进一步审查看起来你可以导入和合并你现有的 webpack 配置:storybook.js.org/docs/react/configure/…
  • 如果我用“resolve”添加别名,它会显示“configuration.module 有一个未知属性 'resolve'”。如果我像在官方文档中那样导入 webpack,它会说“无法读取未定义的模块”
  • 两件事,resolve 位于 webpack 配置的顶层,而不是在 config.module 之下。不是 100% 确定 webpack 导出/导入问题,但请注意您的 webpack 配置导出是一个函数,而不是普通对象,因此您需要调用它并将该调用的输出与故事书默认值合并导入工作。

标签: reactjs webpack storybook


【解决方案1】:

只需将其添加到您的.storybook/main.js

const path = require('path');

module.exports = {
  "stories": [
    "../components/**/*.stories.mdx",
    "../components/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    '@storybook/preset-scss',
  ],
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      '@/interfaces': path.resolve(__dirname, "../interfaces"),
    };

    return config;
  }
}

这里interface 是我项目根目录下的文件夹

对我有用

【讨论】:

    【解决方案2】:

    如果您使用的是 webpack 5,则需要指定应使用 webpack5,方法是在之前的答案之外还添加以下内容:

      core: {
        builder: "webpack5",
      },
    

    最终的 storybook/main.js 将类似于:

        // .storybook/main.js
    const path = require('path');
    const appWebpack = require(path.join(process.cwd(), 'webpack.config.js'));
    module.exports = {
      stories: ['../src/**/*.stories.@(tsx|mdx)'],
      addons: [
        "@storybook/addon-links",
        "@storybook/addon-essentials",
        '@storybook/preset-scss'
      ],
      core: {
        builder: "webpack5",
      },
      webpackFinal: async (config) => {
        config.resolve.modules = [
          ...(config.resolve.modules || []),
          ...[path.resolve(process.cwd(), "src")],
        ];
        config.resolve.alias = {
          ...(config.resolve.alias || {}),
          ...appWebpack().resolve.alias,
        };
        return config;
      },
    };
    

    这将允许绝对路径和别名(当然,只要这些别名在您的主 webpack.config.js 和 jsconfig.json/tsconfig.json 中正确设置)

    已编辑

    特别是在别名方面遇到了麻烦,我又在 webpack 坎坷的道路上走了一趟。

    我已经更新了上面 .storybook/main.js 的原始“final”,明确地合并了别名和模块节点。

    编辑 2

    请注意,eslint 会在你创建的全局装饰器中使用别名(并添加到 .storybook/preview.js)。你可以放心地忽略这一点——它们仍然有效。如果/当我也想出如何纠正这个问题时,我会回来添加第三次编辑。

    【讨论】:

      【解决方案3】:

      当我遇到同样的问题时,这对我有用:

      • 在开发部门yarn add -D tsconfig-paths-webpack-plugin 中安装一个包。
      • 然后调整您的./storybook/main.js 配置:
      ... // other imports
      const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
      
      ...
      webpackFinal: (config) => {
        config.resolve.plugins = config.resolve.plugins || [];
        config.resolve.plugins.push(
          new TsconfigPathsPlugin({
            configFile: path.resolve(__dirname, "../tsconfig.json"),
          })
        );
      
        return { ... }
      }
      ...
      

      【讨论】:

        猜你喜欢
        • 2020-06-23
        • 2019-05-31
        • 2021-10-16
        • 2018-09-03
        • 2021-10-09
        • 1970-01-01
        • 2018-11-19
        • 2020-11-10
        • 2020-11-24
        相关资源
        最近更新 更多