使用Vue开发SPA时,如果想在组件中用 CSS Modules 来替代 scoped
控制CSS作用域,只需要在Webpack的 vue-loader
中写上相关配置即可。然而在基于Laravel的项目中就没有那么容易了。Laravel默认采用了 laravel-mix
作为构建工具,不太方便自己定制配置。
根据官网文档的说明,首先尝试用 mix.webpackConfig()
来覆盖相应的配置项:
mix.webpackConfig({
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
cssModules : {
localIdentName: '[name]-[hash:base64:5]',
camelCase: true,
}
}
}
]
}
});
然而这并不起作用!
于是想到直接去修改 laravel-mix 的源码,在 node_modules\laravel-mix\src\builder\webpack-rules.js
文件中找到 vue-loader 的rules,在 options
中添加一项 CSS module
的配置,这次可以正常编译运行了!
cssModules : {
localIdentName: '[name]-[hash:base64:5]',
camelCase: true,
}
这样其实不是最佳的解决方案,毕竟修改了源码,有没有可能直接在 webpack.mix.js
中搞定呢?
在Google搜索了一大圈也没找到合理的方案,可能是这样的需求比较少见。后来发现在该项目的 GitHub Issues 上有人遇到的类似的问题,终于在最后看到了解决方案。由于Laravel 5.5默认自带的是 laravel-mix^1.0
,我们必须先升级到最新版本(我使用的是 v2.11.1):
npm install laravel-mix@latest
接下去可以调用新增的 extend
方法来实现我们的需求,代码如下:
mix.extend('cssModules', function(webpackConfig) {
webpackConfig.module.rules.forEach( module => {
if(module.loader !== 'vue-loader')
return;
module.options.cssModules = {
localIdentName: '[name]-[hash:base64:5]',
camelCase: true,
};
});
});
关于 Extending Mix 的详细使用可以查看官方文档
最后在编译打包资源之前,调用我们自定义注册的 cssModules
方法:
mix.cssModules()
.js('resources/assets/js/app.js', 'public/js')
.version();
大功告成! 这下我们可以在Vue组件中使用 CSS Modules 的写法了。同样的方法也可以用于注入其它相关的配置,如 vue-i18n
,遇到相关需求的可以自行尝试。
网友评论