webpack.dev.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const ESLintPlugin = require('eslint-webpack-plugin');
function getStyle(pre) {
return [
'vue-style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
},
},
},
pre
].filter((item) => !!item)
}
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'static/js/[name].[contenthash:10].js',
chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',
assetModuleFilename: 'static/media/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.css$/i,
use: getStyle(),
},
{
test: /\.less$/i,
use: getStyle('less-loader')
},
{
test: /\.s[ac]ss$/i,
use: getStyle('sass-loader')
},
{
test: /\.styl$/,
use: getStyle('stylus-loader')
},
// 其他资源
{
test: /\.(woff2?|ttf|mp3|mp4)/,
type: 'asset/resource',
},
// 图片资源
{
test: /\.(jpe?g|png|svg)/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 10kb
}
}
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false
}
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' }),
new VueLoaderPlugin(),
new ESLintPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules'
})
],
optimization: {
splitChunks: {
// include all types of chunks
chunks: 'all',
},
},
mode: 'development',
devtool: 'eval-source-map',
devServer: {
port: 3000,
historyApiFallback: true,
hot: true,
open: true
}
}
webpack.prod.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const ESLintPlugin = require('eslint-webpack-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require("terser-webpack-plugin");
function getStyle(pre) {
return [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
],
},
},
},
pre
].filter((item) => !!item)
}
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'static/js/[name].[contenthash:10].js',
chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',
assetModuleFilename: 'static/media/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.css$/i,
use: getStyle(),
},
{
test: /\.less$/i,
use: getStyle('less-loader')
},
{
test: /\.s[ac]ss$/i,
use: getStyle('sass-loader')
},
{
test: /\.styl$/,
use: getStyle('stylus-loader')
},
// 其他资源
{
test: /\.(woff2?|ttf|mp3|mp4)/,
type: 'asset/resource',
},
// 图片资源
{
test: /\.(jpe?g|png|svg)/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 10kb
}
}
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false
}
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({ template: './public/index.html' }),
new VueLoaderPlugin(),
new ESLintPlugin({
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules'
}),
new MiniCssExtractPlugin({
filename: 'static/style/[name].[contenthash:10].css',
chunkFilename: 'static/js/[name].[contenthash:10].chunk.css',
})
],
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
new TerserPlugin()
],
splitChunks: {
// include all types of chunks
chunks: 'all',
},
},
mode: 'production',
devtool: 'source-map',
}