如何同时使用 MiniCssExtractPlugin 和 vue-style-loader?



我想在我的组件文件(Home.vue(和单独的文件(style.scss(中使用scss。 与此同时。webpack 生成默认值.css from style.scss - 我使用 MiniCssExtractPlugin 和 vue-style-loader。

我准备了 webpack.config.js但是当我将<style lang="scss" scoped>更改为<style lang="css" scoped>一切正常时,它似乎不正确,否则它不会。<style lang="scss" scoped>什么都不做——没有错误,没有影响。

如何更改 webpack.config.js 以同时使用 MiniCssExtractPlugin 和 vue-style-loader?

webpack.config.js

var path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const isDevelopment = process.env.NODE_ENV
console.log("Dev status: " + (isDevelopment == 'development' ? 'Development' : 'Production'), isDevelopment);
module.exports = {
mode: isDevelopment,
entry: {
'vwp': ['./src/vue/welcome.js'],
'default': './src/scss/style.scss'
},
output: {
path: path.resolve(process.cwd(), 'public/assets/js'),
filename: '[name].js'
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
module: {
rules: [{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /.js$/,
loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/.vue.js/.test(file)
)
},
{
test: /.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /.scss$/,
use: [
'vue-style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
]
}
]
},
plugins: [
new VueLoaderPlugin(),
new CleanWebpackPlugin({
dangerouslyAllowCleanPatternsOutsideProject: true,
cleanOnceBeforeBuildPatterns: ['../css/*', '../js/*'],
cleanAfterEveryBuildPatterns: ['defautl.js'],
dry: false
}),
new MiniCssExtractPlugin({
filename: isDevelopment == 'development' ? '../css/[name].css' : '../css/[name].[hash].css',
chunkFilename: isDevelopment == 'development' ? '../css/[id].css' : '../css/[id].[hash].css'
}),
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['defautl.js']
}),

]
}

欢迎.js

import Vue from 'vue'
import Home from './Home.vue'
Vue.config.productionTip = false
new Vue({
el: '#vwp',
components: { Home },
template: '<Home />'
})

Vue.config.devtools = true

首页

<template>
<div>hello text</div>
</template>
<script>
export default {
name: "Home"
};
</script>
<style lang="scss" scoped>
* {
color: lime;
}
</style>

不需要测试功能。您可以在正则表达式中使用负(?<!...)

rules: [
// SASS and CSS files from Vue Single File Components:
{
test: /.vue.(s?[ac]ss)$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader']
},
// SASS and CSS files (standalone):
{
test: /(?<!.vue).(s?[ac]ss)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
}
]

问题是,如果规则中有正则表达式匹配,WebPack 拒绝工作。我认为它以某种方式标记了已处理的文件。至少在这种情况下是正确的。

但是WebPack是一个非常强大的工具。它可以采用具有两个参数(文件名和条目(的函数,而不是规则参数中的正则表达式。

之后,我确定 vue-loader 将组件文件拆分为三个文件:

  • <component name>.vue.js
  • <component name>.vue最后
  • <component name>.vue.css(或.scss(

注意:SASS 扩展名取决于样式标签的 lang 参数。

接下来,有必要在函数中使用逻辑将这两种情况分开。我的实现在示例中可见。

rules: [
{
test: function(filename, entry){
if(/.s[ac]ss$/.test(filename)){
if(/.vue.s[ac]ss$/.test(filename)){
return false;
}
return true;
}
return false;
},
use: [
{
loader: MiniCssExtractPlugin.loader, 
options:{
}
}, 'css-loader', 'sass-loader']
},      
{
test: /.vue$/,
loader: 'vue-loader',
options: {
}
},
{
test: /.css$/,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: (filename, entry) => {
return /.vue.s[ac]ss/.test(filename);
},
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
}

最新更新