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

配置数组:如何在每次Sass编译前注入钩子 #16075

解决Webpack 4.x中Sass编译前修改文件内容的方案

方案一:自定义前置Loader(推荐)

Webpack的Loader按从右到左的顺序执行,我们可以在sass-loader之前添加自定义Loader,专门处理Sass文件内容的修改,完全契合编译前介入的需求。

  1. 新建自定义Loader文件(如sass-preprocessor-loader.js):
const fs = require('fs');
const path = require('path');

module.exports = function(source) {
  // 这里编写你的内容修改逻辑,示例:替换Sass中的占位变量为共享配置
  const yourSharedConfig = this.options.siteConfig; // 从Webpack配置传递的共享配置
  const modifiedSource = source.replace(
    /@import "shared-config";/,
    `$site-config: ${JSON.stringify(yourSharedConfig).replace(/"/g, "'")};`
  );
  return modifiedSource;
};
  1. 在Webpack配置中引入该Loader,注意顺序要放在sass-loader之前(数组中靠后的位置,因为执行顺序反向):
const path = require('path');

module.exports = {
  // 传递共享配置给Loader
  siteConfig: { /* 你的多站点共享配置数组 */ },
  // ...其他Webpack配置
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
          {
            loader: path.resolve(__dirname, './sass-preprocessor-loader.js'),
          }
        ],
      },
    ],
  },
};

方案二:利用Webpack Compiler钩子拦截模块

通过监听Webpack的模块加载钩子,在Sass文件进入sass-loader前拦截并修改内容:

const fs = require('fs');

module.exports = {
  // ...其他Webpack配置
  plugins: [
    {
      apply(compiler) {
        // 监听模块解析前的钩子
        compiler.hooks.normalModuleFactory.tap('SassPreHook', (nmf) => {
          nmf.hooks.afterResolve.tap('ModifySassContent', (result) => {
            // 仅处理Sass文件
            if (result.resource.match(/\.s[ac]ss$/i)) {
              // 读取原文件内容并修改
              const originalContent = fs.readFileSync(result.resource, 'utf8');
              const modifiedContent = originalContent.replace(
                /\$default-theme/g,
                '$custom-theme: #2c3e50;'
              );
              // 替换模块的原始内容
              result.loaders.unshift({
                loader: 'string-replace-loader',
                options: {
                  search: originalContent,
                  replace: modifiedContent,
                },
              });
            }
            return result;
          });
        });
      }
    }
  ]
};

为什么之前的方法无效?

  • sass-loader的选项仅用于配置Sass编译器的行为(如includePaths、sourceMap等),没有提供直接修改源文件内容的入口。
  • webpack-shell-plugin的before钩子是在Webpack启动前执行脚本,此时还未开始处理具体模块文件,无法触达即将编译的Sass内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 13:24:24