使用 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.html
和 html-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>
我试过的
- 构建期间未使用
html-webpack-plugin
(未更改)
- 为 $vue 使用不同的别名:(
vue$: "vue/dist/vue.runtime.esm.js"
)(没有改变)
- 不使用
mini-css-extract-plugin
(css 即使使用 html-webpack-plugin
也不会加载)
同样在 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
我想从我的项目中删除 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.html
和 html-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>
我试过的
- 构建期间未使用
html-webpack-plugin
(未更改) - 为 $vue 使用不同的别名:(
vue$: "vue/dist/vue.runtime.esm.js"
)(没有改变) - 不使用
mini-css-extract-plugin
(css 即使使用html-webpack-plugin
也不会加载)
同样在 Laravel Mix 中,样式加载在 <style>
标签内,而不是在单独的 .css
文件中,但这不是问题(两者对我来说都很好)。
通过查看
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