应用场景
当我们在scss样式文件中想使用其他已经声明好的scss变量文件,通常会这么做:
// style.scss
@import "variables.scss";
body {
color: $theme-color;
}
随着项目越来越大,每个样式文件都需要用到全局定义好的变量,这时就变得非常的笨重,弊端就暴露出来了。
下面来看看怎么去解决这个问题
安装sass-resouces-loader
npm i sass-resources-loader -D
sass-resources-loader 是什么? 官方是这么解释的:
这个加载器将 @import 您的SASS资源放入每个required SASS模块中。因此,您可以在所有SASS样式中使用共享变量和mixin,而无需在每个文件中手动导入它们。使用CSS模块!
可以这么去理解,当你新建了一个scss文件,这个loader会自动在顶部引入您指定的变量文件,这就能解决上述问题了。
react配置
如果使用的是官方提供的脚手架create-react-app 那就再好不过了,配置方式如下:
1、打开 config/webpack.config.js
2、找到如下代码
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
3、修改成如下
{
test: sassRegex,
exclude: sassModuleRegex,
// 看源码可以看出来 getStyleLoaders 返回的是一个数组,所以我们可以用 concat把他合并
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
).concat({
// 这行的意思是引入加载器 sass-resources-loader
loader: 'sass-resources-loader',
options: {
// 这里是需要引入全局的资源文件,它可以是一个字符串或者是一个数组, 通常用数组去代替。
resources: ['./src/assets/scss/_variables.scss', './src/assets/scss/mixins.scss']
}
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
4、启动项目即可
vue配置
vue配置就要分脚手架版本了,目前有 2.x和3.x, 大部分项目都陆续升级到3.x了,建议升级下。
vue-cli 2.x配置
1、打开 build/utils.js
2、找到 generateLoaders 函数, 大概是这样子
function generateLoaders (loader, loaderOptions) {
const loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
3、修改成如下
function generateLoaders (loader, loaderOptions) {
const loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
if (loader === 'sass') {
loaders.push({
loader: 'sass-resources-loader',
options: {
// 注意这里是引入全局变量
resources: ['./src/assets/scss/_variables.scss', './src/assets/scss/mixins.scss']
},
});
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
vue-cli 3.x配置
我认为cli 3.x的配置会更人性化一些,统一配置在根项目的 vue.config.js 中,升级会变得更容易。
配置如下
// vue.config.js
const path = require('path');
module.exports = {
chainWebpack: config => {
const oneOfsMap = config.module.rule('scss').oneOfs.store
oneOfsMap.forEach(item => {
item
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: [path.resolve(__dirname, './src/assets/scss/variables.scss'), path.resolve(__dirname, './src/assets/scss/mixins.scss')]
})
.end()
})
}
}
总结
在中大型的项目中,sass-resources-loader是必不可少的,或者是其他的方法,这将大大的减少项目中的代码量,使得维护变得更容易。