如何在laravel-mix中使用CSS Modules

使用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,遇到相关需求的可以自行尝试。

你可能感兴趣的:(如何在laravel-mix中使用CSS Modules)