使用 Vue 从 Laravel 项目中删除 Mix 时出现问题

Problems removing Mix from a Laravel project with Vue

我想从我的项目中删除 Laravel Mix,以便更快地采用新功能或发布,而不必使用 Mix 的语法或插件或将所有内容放入 webpackConfig 方法中。

我已经创建了一个适用于样式和资产的 Webpack 配置,但我无法使 vue-loader 从静态 .html 文件中的 vue 单个文件组件导入样式:如果我使用 html-webpack-plugin 一切正常,但如果我在静态 .html 文件中包含 .js 包,则样式不会加载。我希望它在静态 .html 文件中工作,以模拟 blade 文件在 php.

中的行为

这是我的设置的简化版本:

webpack.config.js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { VueLoaderPlugin } = require("vue-loader");
const htmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: {
        main: "./src/main.js",
    },
    output: {
        filename: 'js/[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    resolve: {
        extensions: ['.js', '.vue'],
        alias: {
            "vue$": "vue/dist/vue.common.js"
        }
    },
    module: {
        rules: [
            {
                test: /\.((c|sa|sc)ss)$/i,
                use: [
                'vue-style-loader',
                MiniCssExtractPlugin.loader,
                'css-loader', 'postcss-loader', 'sass-loader'
            ],
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader'],
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
        ],  
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css',
        }),
        new htmlWebpackPlugin({
            template: path.resolve(__dirname, "public", "index.html")
        }),
        new CleanWebpackPlugin({
            cleanStaleWebpackAssets: false,
            verbose: true
        }),
        new VueLoaderPlugin()
    ],
};

main.js

import Vue from "vue";
import App from "./App.vue";

new Vue({
    render: (h) => h(App),
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <div class="nav">
        Test nav
    </div>
  </div>
</template>

<style lang="scss">
.nav {
    padding: 30px 0 100px 0;
    font-family: sans-serif;
}
</style>

index.html

(用于生成另一个 index.htmlhtml-webpack-plugin

有了这个一切正常


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Vue app</title>
</head>

<body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
</body>

</html>

index.html(静态文件)

这个不加载 .css 个文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
</head>

<body>
    <div id="app"></div>
    <script src="dist/js/main.js"></script>
</body>

</html>

我试过的

同样在 Laravel Mix 中,样式加载在 <style> 标签内,而不是在单独的 .css 文件中,但这不是问题(两者对我来说都很好)。

通过查看 对 SO 问题的回答 如何从 laravel 混合迁移到纯 Webpack? 我已经打印出一个新的 Laravel Mix 项目的配置,设置最少。

Mix.listen('configReady', function (config) {
  RegExp.prototype.toJSON = RegExp.prototype.toString;
  console.log(JSON.stringify(config));
});

我发现 Laravel Mix 在来自 Vue 的 css 文件和所有其他 css/scss 文件之间使用了两组不同的加载器。

我没有复制他们的配置,因为它涉及很多重复,但幸运的是,我能够找到一个可以完成相同工作的快速设置:

// [...]
module: {
  rules: [
    {
      test: /\.vue\.css$/, // only vue css
      use: [
        'style-loader',
        'css-loader',
        'postcss-loader',
        'sass-loader'
      ]
    },
    {
      test: /\.((c|sa|sc)ss)$/i,
      exclude(modulePath) {
        // exclude vue css
        return modulePath.includes('.vue');
      },
      use: [
        {
          loader: MiniCssExtractPlugin.loader,
          options: {
            publicPath: '../',
          },
        },
        'css-loader', 'postcss-loader', 'sass-loader'
      ]
    },
    // [...]
  ]
}

我不确定这是在 Vue 应用程序中加载 css 的最佳方式,但至少现在我可以复制与原始应用程序相同的情况。

编辑 21 年 1 月 28 日

使用 scss 个文件时,您需要像这样更新第一个测试:

test: /\.vue\.((c|sa|sc)ss)$/i, // only vue css