问题描述
问题陈述
我在旧版React应用程序中有一个要求,该应用程序在特定目录中有多个scss文件。没有在组件级别导入CSS,应用程序使用gulp作为构建系统,在其中监视文件更改,吐出相应的CSS文件,将它们合并,最后将链接标记注入index.html文件中(此步骤无需处于观看模式),页面就会重新加载。
需要什么
我们需要将其从gulp配置转移到使用Webpack进行上述步骤。
到目前为止,我已经尝试过-可以正常运行
我最初的想法是(因为我们正在使用react-scripts和react-app-rewired)
- 使用node-sass-chokidar将sass文件编译为CSS并将它们写入特定目录。
- 完成此步骤后,在config-overrides.js中,我使用了一个名为
webpack-concat-plugin
的Webpack插件,将特定目录中的文件合并为一个文件,并将其写入构建文件夹。 - 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;
}
}
解决方法
您可以使用additionalData中的sass-loader选项来创建包含所有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';
。
查看this answer了解更多详细信息。
您不需要发明轮子。...利用webpack的力量。
创建一个root.scss
文件,该文件将导入(使用sass导入)所有相关的scss
文件。
然后从您的应用程序根js文件导入(您将需要提供用于处理sass的加载程序)。
这些步骤将根据您的树将scss文件添加到webpack中,这意味着在开发人员模式下,webpack将监视它们是否需要重新编译。
第二部分是使用html-webpack-plugin
为其构建和注入静态资产。