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

Ale*_*Ale 6 sass webpack

我想同时在我的组件文件 (Home.vue) 和单独的文件 (style.scss) 中使用 scss。Webpack 从 style.scss 生成 default.css - 我使用 MiniCssExtractPlugin 和 vue-style-loader。

\n\n

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

\n\n

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

\n\n

webpack.config.js

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

欢迎.js

\n\n
import Vue from \'vue\'\nimport Home from \'./Home.vue\'\n\nVue.config.productionTip = false\n\nnew Vue({\n    el: \'#vwp\',\n    components: { Home },\n    template: \'<Home />\'\n})\n\n\nVue.config.devtools = true\n
Run Code Online (Sandbox Code Playgroud)\n\n

首页.vue

\n\n
<template>\n  <div>hello text</div>\n</template>\n\n<script>\nexport default {\n  name: "Home"\n};\n</script>\n\n<style lang="scss" scoped>\n* {\n  color: lime;\n}\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n

小智 5

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

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']
    }
]
Run Code Online (Sandbox Code Playgroud)


小智 4

问题是,如果规则中存在正则表达式匹配,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'
                ]
            }
        ]
    }
Run Code Online (Sandbox Code Playgroud)