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

时间:2019-12-17 11:59:20

标签: webpack sass

我想在组件文件(Home.vue)和单独的文件(style.scss)中使用scss 同时。 Webpack从style.scss生成default.css-我使用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']
    }),


  ]
}

welcome.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

Home.vue

<template>
  <div>hello text</div>
</template>

<script>
export default {
  name: "Home"
};
</script>

<style lang="scss" scoped>
* {
  color: lime;
}
</style>

2 个答案:

答案 0 :(得分:2)

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

但是WebPack是一个非常强大的工具。可以使用带有两个参数(文件名和条目)的函数来代替rule参数中的正则表达式。

之后,我确定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'
                ]
            }
        ]
    }

答案 1 :(得分:2)

不需要测试功能。您可以在您的 RegEx 中使用否定回顾 (?<!...)

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']
    }
]