【问题标题】:How to use MiniCssExtractPlugin and vue-style-loader at the same time?如何同时使用 MiniCssExtractPlugin 和 vue-style-loader?
【发布时间】:2020-04-09 22:21:55
【问题描述】:

我想在我的组件文件 (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

首页.vue

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

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

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

【问题讨论】:

    标签: webpack sass


    【解决方案1】:

    不需要测试功能。你可以在你的 RegEx 中使用否定的后向 (?&lt;!...)

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

    【讨论】:

    • 太棒了。我整天都在苦苦挣扎,试图弄清楚如何从 vue 模板中提取 css。遵循每个装载机指南并没有帮助。你认为这是因为他们没有完全支持 Webpack 5,还是......?
    • s?[ac]ss 是优雅的正则表达式,匹配 .scss.sass.css ... 但是它也将匹配 .ass,这就是我现在将所有 CSS 命名的名称带哈哈的文件
    【解决方案2】:

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

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

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

    • &lt;component name&gt;.vue.js
    • &lt;component name&gt;.vue 最后是
    • &lt;component name&gt;.vue.css(或.scss

    注意: SASS 扩展依赖于 style 标签的 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'
                    ]
                }
            ]
        }
    

    【讨论】:

    • 感谢分享。我一直在尝试在我的网站/vuewapp 中包含 VueJs 和常规 scss,并使用您概述的功能方法解决了我的问题,而不是尝试通过正则表达式排除文件。
    猜你喜欢
    • 2019-05-04
    • 2019-04-22
    • 2018-12-20
    • 2019-04-15
    • 2021-03-11
    • 2018-02-03
    • 2019-12-20
    • 2017-10-10
    • 2019-09-04
    相关资源
    最近更新 更多