You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Storybook静态构建部署SCSS静态资源路径加载异常问题

Storybook静态构建CSS资源路径异常解决方案

问题根因

该问题是三层配置不匹配导致的:

  • SCSS中硬编码了/开头的站点绝对路径,webpack默认不会对这类硬编码绝对路径做publicPath适配
  • Storybook 6.x版本中,publicPath配置仅作用于HTML入口的脚本、样式标签引用路径,不会处理JS内联CSS中的url()引用
  • 之前配置的postcss-url等插件未命中webpack loader的执行顺序(postcss-loader需放在sass-loader编译完成后、css-loader解析url前执行才会生效)

落地修复步骤

  • 第一步:调整项目下.storybook/webpack.config.js配置,在loader层拦截重写CSS中的绝对路径引用,配置示例如下:
const path = require('path');

module.exports = async ({ config }) => {
  // 匹配内置CSS处理规则
  const cssRule = config.module.rules.find(rule => rule.test?.toString().includes('css'));
  if (cssRule && Array.isArray(cssRule.oneOf)) {
    cssRule.oneOf.forEach(ruleSet => {
      if (!Array.isArray(ruleSet.use)) return;
      ruleSet.use.forEach(loaderConfig => {
        // 给css-loader加路径拦截逻辑
        if (loaderConfig.loader?.includes('css-loader')) {
          loaderConfig.options = {
            ...loaderConfig.options,
            url: (resourcePath) => {
              // 把/assets开头的绝对路径转成相对路径
              if (resourcePath.startsWith('/assets/')) {
                return resourcePath.slice(1);
              }
              return true;
            }
          };
        }
        // 补全postcss-url配置,放在正确的loader执行位置
        if (loaderConfig.loader?.includes('postcss-loader')) {
          const existingPlugins = loaderConfig.options?.postcssOptions?.plugins || [];
          loaderConfig.options.postcssOptions = {
            ...loaderConfig.options.postcssOptions,
            plugins: [
              ...existingPlugins,
              ['postcss-url', {
                url: (asset) => asset.url.startsWith('/assets/') ? asset.url.slice(1) : asset.url
              }]
            ]
          };
        }
      });
    });
  }

  // 配置静态资源别名,避免多层目录相对路径写错
  config.resolve.alias = {
    ...config.resolve.alias,
    '@storybook-assets': path.resolve(__dirname, '../src/assets')
  };

  return config;
};
  • 第二步:修正项目project.json中build-storybook目标的静态资源配置,保证构建时资源文件能正确复制到输出目录:
{
  "targets": {
    "build-storybook": {
      "executor": "@nrwl/storybook:build",
      "options": {
        // 保留原有其他配置项
        "staticDirs": [
          { "from": "src/assets", "to": "assets" }
        ]
      }
    }
  }
}
  • 第三步:调整SCSS中的路径写法,不要硬编码/开头的绝对路径,二选一即可:
    • 相对路径写法:根据当前SCSS文件和assets目录的层级关系写相对路径,比如$icon-path: "../../assets/images";
    • 别名写法:用前面配置的别名,写$icon-path: "~@storybook-assets/images";,webpack会自动解析路径,适配任意部署子目录。

验证方式

执行nx run ui-common:build-storybook完成构建后,打开storybook-static目录下的main.*.iframe.bundle.js文件,搜索background-image关键字,确认对应的资源路径已变为assets/xxx.svg或./assets/xxx.svg格式,没有开头的/即可。此时本地直接双击打开index.html资源可正常加载,部署到GitHub Pages子路径下也不会出现404问题。


内容的提问来源于stack exchange,提问作者Shining

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:18:16