mc9*_*c92 6 build sass webpack sass-loader webpacker
当我们切换到使用Webpack来处理SASS文件时,我们注意到在某些情况下,构建时间变得非常缓慢。在使用SpeedMeasurePlugin测量了构建的不同部分的性能之后,似乎sass-loader是罪魁祸首……它很容易花费10s来构建(在进行一些修复之前通常花费20s),这比我们更长。 d喜欢。
我很好奇,如果人们还有其他策略可以优化构建我没有涵盖的Sass资产。在这一点上,我已经经历了很多(对于其中一些来说是多次),但似乎仍然无法将构建时间降低得足够低。就目标而言,当前的大规模重建(例如更改许多文件中使用的组件)可能很容易花费10-12秒,我希望尽可能将其降低到5s。
我们尝试了多种不同的解决方案,其中一些可行,而其他解决方案却无济于事。
includePaths
用于从node_modules加载的SASS-在我发现的git问题上建议使用此方法,在该问题上sass-loader遇到了称为“自定义进口商”的问题。我的理解是,通过使用includePaths,SASS能够依靠那些提供的绝对路径,而不是使用效率低下的算法来解析路径到诸如node_modules的位置从一些简要的统计数据来看,我们似乎在150个SASS文件中散布了约1.6万行SASS代码。有些文件的代码量很大,而其他代码的代码量却很少,这些文件的LOC平均值约为107 LOC /文件。
以下是正在使用的配置。该应用程序是Rails应用程序,因此许多Webpack配置都是通过Webpacker gem处理的。
{
"mode": "production",
"output": {
"filename": "js/[name].js",
"chunkFilename": "js/[name].js",
"hotUpdateChunkFilename": "js/[id]-[hash].hot-update.js",
"path": "myApp/public/packs",
"publicPath": "/packs/"
},
"resolve": {
"extensions": [".mjs", ".js", ".sass", ".scss", ".css", ".module.sass", ".module.scss", ".module.css", ".png", ".svg", ".gif", ".jpeg", ".jpg"],
"plugins": [{
"topLevelLoader": {}
}],
"modules": ["myApp/app/assets/javascript", "myApp/app/assets/css", "node_modules"]
},
"resolveLoader": {
"modules": ["node_modules"],
"plugins": [{}]
},
"node": {
"dgram": "empty",
"fs": "empty",
"net": "empty",
"tls": "empty",
"child_process": "empty"
},
"devtool": "source-map",
"stats": "normal",
"bail": true,
"optimization": {
"minimizer": [{
"options": {
"test": {},
"extractComments": false,
"sourceMap": true,
"cache": true,
"parallel": true,
"terserOptions": {
"output": {
"ecma": 5,
"comments": false,
"ascii_only": true
},
"parse": {
"ecma": 8
},
"compress": {
"ecma": 5,
"warnings": false,
"comparisons": false
},
"mangle": {
"safari10": true
}
}
}
}],
"splitChunks": {
"chunks": "all",
"name": false
},
"runtimeChunk": true
},
"externals": {
"moment": "moment"
},
"entry": {
"entry1": "myApp/app/assets/javascript/packs/entry1.js",
"entry2": "myApp/app/assets/javascript/packs/entry2.js",
"entry3": "myApp/app/assets/javascript/packs/entry3.js",
"entry4": "myApp/app/assets/javascript/packs/entry4.js",
"entry5": "myApp/app/assets/javascript/packs/entry5.js",
"entry6": "myApp/app/assets/javascript/packs/entry6.js",
"entry7": "myApp/app/assets/javascript/packs/entry7.js",
"entry8": "myApp/app/assets/javascript/packs/entry8.js",
"landing": "myApp/app/assets/javascript/packs/landing.js",
"entry9": "myApp/app/assets/javascript/packs/entry9.js",
"entry10": "myApp/app/assets/javascript/packs/entry10.js",
"entry11": "myApp/app/assets/javascript/packs/entry11.js",
"entry12": "myApp/app/assets/javascript/packs/entry12.js",
"entry13": "myApp/app/assets/javascript/packs/entry13.js",
"entry14": "myApp/app/assets/javascript/packs/entry14.js",
"entry15": "myApp/app/assets/javascript/packs/entry15.js"
},
"module": {
"strictExportPresence": true,
"rules": [{
"parser": {
"requireEnsure": false
}
}, {
"test": {},
"use": [{
"loader": "file-loader",
"options": {
"context": "app/assets/javascript"
}
}]
}, {
"test": {},
"use": ["myApp/node_modules/mini-css-extract-plugin/dist/loader.js", {
"loader": "css-loader",
"options": {
"sourceMap": true,
"importLoaders": 2,
"localIdentName": "[name]__[local]___[hash:base64:5]",
"modules": false
}
}, {
"loader": "postcss-loader",
"options": {
"config": {
"path": "myApp"
},
"sourceMap": true
}
}],
"sideEffects": true,
"exclude": {}
}, {
"test": {},
"use": ["myApp/node_modules/mini-css-extract-plugin/dist/loader.js", {
"loader": "css-loader",
"options": {
"sourceMap": true,
"importLoaders": 2,
"localIdentName": "[name]__[local]___[hash:base64:5]",
"modules": false
}
}, {
"loader": "postcss-loader",
"options": {
"config": {
"path": "myApp"
},
"sourceMap": false,
"plugins": [null, null]
}
}, {
"loader": "sass-loader",
"options": {
"sourceMap": false,
"sourceComments": true
}
}],
"sideEffects": true,
"exclude": {}
}, {
"test": {},
"use": ["myApp/node_modules/mini-css-extract-plugin/dist/loader.js", {
"loader": "css-loader",
"options": {
"sourceMap": true,
"importLoaders": 2,
"localIdentName": "[name]__[local]___[hash:base64:5]",
"modules": true
}
}, {
"loader": "postcss-loader",
"options": {
"config": {
"path": "myApp"
},
"sourceMap": true
}
}],
"sideEffects": false,
"include": {}
}, {
"test": {},
"use": ["myApp/node_modules/mini-css-extract-plugin/dist/loader.js", {
"loader": "css-loader",
"options": {
"sourceMap": true,
"importLoaders": 2,
"localIdentName": "[name]__[local]___[hash:base64:5]",
"modules": true
}
}, {
"loader": "postcss-loader",
"options": {
"config": {
"path": "myApp"
},
"sourceMap": true
}
}, {
"loader": "sass-loader",
"options": {
"sourceMap": true
}
}],
"sideEffects": false,
"include": {}
}, {
"test": {},
"include": {},
"exclude": {},
"use": [{
"loader": "babel-loader",
"options": {
"babelrc": false,
"presets": [
["@babel/preset-env", {
"modules": false
}]
],
"cacheDirectory": "tmp/cache/webpacker/babel-loader-node-modules",
"cacheCompression": true,
"compact": false,
"sourceMaps": false
}
}]
}, {
"test": {},
"include": ["myApp/app/assets/javascript", "myApp/app/assets/css"],
"exclude": {},
"use": [{
"loader": "babel-loader",
"options": {
"cacheDirectory": "tmp/cache/webpacker/babel-loader-node-modules",
"cacheCompression": true,
"compact": true
}
}]
}, {
"test": "myApp/node_modules/jquery/dist/jquery.js",
"use": [{
"loader": "expose-loader",
"options": "jQuery"
}, {
"loader": "expose-loader",
"options": "$"
}]
}, {
"test": "myApp/node_modules/popper.js/dist/umd/popper.js",
"use": [{
"loader": "expose-loader",
"options": "Popper"
}]
}, {
"test": "myApp/node_modules/scroll-depth/jquery.scrolldepth.js",
"use": [{
"loader": "expose-loader",
"options": "scrollDepth"
}]
}]
},
"plugins": [{
"environment_variables_plugin": "values don't really matter in this case I think"
}, {
"options": {},
"pathCache": {},
"fsOperations": 0,
"primed": false
}, {
"options": {
"filename": "css/[name]-[contenthash:8].css",
"chunkFilename": "css/[name]-[contenthash:8].chunk.css"
}
}, {}, {
"options": {
"test": {},
"cache": true,
"compressionOptions": {
"level": 9
},
"filename": "[path].gz[query]",
"threshold": 0,
"minRatio": 0.8,
"deleteOriginalAssets": false
}
}, {
"pluginDescriptor": {
"name": "OptimizeCssAssetsWebpackPlugin"
},
"options": {
"assetProcessors": [{
"phase": "compilation.optimize-chunk-assets",
"regExp": {}
}],
"assetNameRegExp": {},
"cssProcessorOptions": {},
"cssProcessorPluginOptions": {}
},
"phaseAssetProcessors": {
"compilation.optimize-chunk-assets": [{
"phase": "compilation.optimize-chunk-assets",
"regExp": {}
}],
"compilation.optimize-assets": [],
"emit": []
},
"deleteAssetsMap": {}
}, {
"definitions": {
"$": "jquery",
"jQuery": "jquery",
"jquery": "jquery",
"window.$": "jquery",
"window.jQuery": "jquery",
"window.jquery": "jquery",
"Popper": ["popper.js", "default"]
}
}, {
"definitions": {
"process.env": {
"MY_DEFINED_ENV_VARS": "my defined env var values"
}
}
}, {
"options": {}
}]
}
Run Code Online (Sandbox Code Playgroud)
我认为有几个问题:
1:可能是因为您没有指定要测试的文件(因此 webpack 可能会搜索所有内容):
...
"test": {},
"use": ["myApp/node_modules/mini-css-extract-plugin/dist/loader.js", {
"loader": "css-loader"
}
...
Run Code Online (Sandbox Code Playgroud)
尝试test: {}
用test: /\.(sa|sc|c)ss$/
或
test: /\.module.(sa|sc|c)ss$/
if using css 模块替换
1b:test
也尝试修改其他加载器中的密钥,例如 babel 通常只需要查找 js/ts(x) 文件,因此如果是这种情况请指定。
1c:也尝试使用包含/排除属性
2:该配置中有 4 个 css-loader 实例 - 除非您是服务器端渲染,否则您只需要两个(一个用于 sc/sa/css 模块,一个用于普通 sa/sc/ss)
这是一个示例 css 加载器配置,我希望它对您有所帮助(提示:每个项目加载 css 的方式通常有所不同,因此请务必检查 webpack/css-loader 文档中的模块选项)
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: true,
modules: {
namedExport: true,
},
},
},
{
loader: 'css-loader',
options: {
sourceMap: !isProd,
importLoaders: 2,
esModule: true,
modules: {
auto: true,
namedExport: true,
},
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: !isProd,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: !isProd,
},
},
]
}
Run Code Online (Sandbox Code Playgroud)
陷阱:webpack 加载器是反向处理的,因此对于此示例配置,处理顺序是 sass -> postcss -> css -> minicss
不幸的是,对于 webpack 的 css 问题很少有直接/直接的答案,需要深入研究文档并找出您的项目需要哪些选项。
归档时间: |
|
查看次数: |
625 次 |
最近记录: |