1

问题陈述

我在一个旧的 React 应用程序中有一个要求,它在特定目录中有多个 scss 文件。CSS 不是在组件级别导入的,应用程序使用 gulp 作为构建系统,它监视文件更改,吐出相应的 CSS 文件,合并它们,最后在 index.html 文件中注入一个链接标签(这一步不需要处于监视模式)并且页面被重新加载。

需要什么

对于上述步骤,我们需要将其从 gulp 配置转移到使用 Webpack。

到目前为止我所尝试的 - 什么有效

我最初的想法是(因为我们使用的是 react-scripts 和 react-app-rewired)

  1. 使用 node-sass-chokidar 将 sass 文件编译成 CSS 并写入特定目录。
  2. 完成此步骤后,在 config-overrides.js 中,我使用了一个名为 的 Webpack 插件webpack-concat-plugin,将特定目录中的文件合并为一个文件并将其写入构建文件夹。
  3. index.html 有一个指向该文件位置的链接标签

以上步骤在生产模式下工作。

到目前为止我尝试过的 - 什么不起作用

我也在尝试在开发模式下实现相同的功能,但我无法弄清楚“每次 node-sass-chokidar 吐出 css 文件时我如何运行 webpack-concat-plugin(它在监视模式下运行并且每当 scss 文件更改时运行)”。我尝试创建一个自定义 Webpack 插件并使用监视模式来点击,但我不确定上述问题。webpack 插件看起来像这样。

const pluginName = 'ConcatCSSPlugin';
const ConcatPlugin = require('webpack-concat-plugin');

class ConcatCSSOnFileChangeWebpackPlugin {
  apply(compiler) {
    compiler.hooks.watchRun.tap(pluginName, compilation => {
      console.log('The webpack hook is running');
      /* How should I invoke the ConcatPlugin */
    });
  }
}

module.exports = ConcatCSSOnFileChangeWebpackPlugin;

config-overrides.js 看起来像这样

module.exports = {
  webpack: function override(config, env) {
    if (env === 'production') {
      config.plugins.push(new ConcatPlugin({
        outputPath: 'build/styles',
        fileName: 'style.css',
        injectType: 'none',
        filesToConcat: ['./dist/compiled-css/**.css'],
        attributes: {
            async: true
        }
      }), new TestPlugin());

      config.stats = {
        all: true
      }
    }
    return config;
  }
}
4

2 回答 2

1

你不需要发明轮子......利用 webpack 的力量。

创建一个root.scss将导入(使用 sass 导入)所有相关文件的scss文件。

然后从你的应用程序根 js 文件中导入它(你需要提供加载器来处理 sass)。

这些步骤会将您的 scss 文件添加到 webpacks 中,这取决于您的树,这意味着在开发模式下,webpack 将监视它们并重新编译所需的任何内容。

第二部分是html-webpack-plugin用于构建和注入静态资产。

于 2020-10-09T23:34:12.060 回答
1

您可以使用sass-loader中的additionalData选项来创建一个伪根文件,其中包含您所有的 scss 文件。为确保仅附加一次,您可能需要使用以下内容:

let appendedOnce = false;

const sassLoaderRule = {
  loader: 'sass-loader',
  options: {
    additionalData: function (content) {
      if (appendedOnce) return content;

      appendedOnce = true;

      return `
        @import 'fileOne.scss'; 
        @import 'fileTwo.scss'; 
        @import 'etc.scss';
      ` + content;
    }
  }
}

此外,如果要导入的文件太多,您可以使用node-sass-glob-importer代替写:@import './**/*.scss';。查看此答案以获取更多详细信息。

于 2020-10-15T08:00:58.893 回答