










npm i webpack webpack-cli webpack-dev-server -D
npm i vue -S
npm i vue-loader -D
npm i @babel/core babel-loader @vue/cli-plugin-babel -D
npm i less less-loader css-loader style-loader postcss postcss-loader postcss-preset-env -D
npm i clean-webpack-plugin -D
npm i html-webpack-plugin -D
npm i copy-webpack-plugin -D
module.exports = {
mode: 'development'
// ...
}
module.exports = {
mode: 'production'
// ...
}
npm i webpack-merge -D
const merge = require('webpack-merge')
const devConfig = require('./webpack.dev')
const prodConfig = require('./webpack.prod')
const isProduction = process.env.NODE_ENV === 'production'
const commonConfig = {
// ...
}
const baseConfig = isProduction ? prodConfig : devConfig
const defaultConfig = merge(commonConfig, baseConfig)
module.exports = defaultConfig
...
"scripts": {
"serve": "NODE_ENV=development webpack serve --config ./webpack.common.js",
"build": "NODE_ENV=production webpack --config ./webpack.common.js",
},
...
entry: './src/main.js' // 相对路径
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist'),
// publicPath: `//xxx.com/`,
chunkFilename: '[name].[contenthash].js'
}
resolve: {
extensions: [".js", ".json", '.ts', '.jsx', '.vue'],
alias: {
'@': path.resolve(__dirname, './src')
}
}
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
esModule: false
}
}
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
// ...
]
}
module: {
rules: [
{
test: /\.(png|svg|gif|jpe?g)$/,
type: 'asset',
generator: {
filename: "img/[name].[hash:4][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 30 * 1024
}
}
},
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name].[hash:3][ext]'
}
},
// ...
]
}
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: ['babel-loader']
}
// ...
]
}
module: {
rules: [
{
test: /\.vue$/,
use: ['vue-loader']
}
// ...
]
}
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { DefinePlugin } = require('webpack')
plugins: [
new HtmlWebpackPlugin({
title: '设置的标题',
template: './public/index.html'
}),
new DefinePlugin({
BASE_URL: '"./"'
}),
new VueLoaderPlugin()
]
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { DefinePlugin } = require('webpack')
const path = require('path')
const { merge } = require('webpack-merge')
const devConfig = require('./webpack.dev')
const prodConfig = require('./webpack.prod')
const isProduction = process.env.NODE_ENV === 'production'
const commonConfig = {
entry: './src/main.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist'),
// publicPath: `//xxx.com/`,
chunkFilename: '[name].[contenthash].js'
},
resolve: {
extensions: [".js", ".json", '.ts', '.jsx', '.vue'],
alias: {
'@': path.resolve(__dirname, './src')
}
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
esModule: false
}
},
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'less-loader'
]
},
{
test: /\.(png|svg|gif|jpe?g)$/,
type: 'asset',
generator: {
filename: "img/[name].[hash:4][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 30 * 1024
}
}
},
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name].[hash:3][ext]'
}
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: ['babel-loader']
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '设置的标题',
template: './public/index.html'
}),
new DefinePlugin({
BASE_URL: '"./"'
}),
new VueLoaderPlugin()
]
}
const baseConfig = isProduction ? prodConfig : devConfig
const defaultConfig = merge(commonConfig, baseConfig)
module.exports = defaultConfig
devServer: {
hot: true,
hotOnly: true,
port: 8080,
open: false,
compress: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'https://api.github.com',
pathRewrite: { "^/api": "" },
changeOrigin: true
}
}
}
告知 webpack 为目标(target)指定一个环境。默认值为 "browserslist",如果没有找到 browserslist 的配置,则默认为 "web"
target: 'web',
devtool: 'cheap-module-source-map',
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
hot: true,
port: 8080,
open: false,
compress: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'https://api.github.com',
pathRewrite: { "^/api": "" },
changeOrigin: true
}
}
}
}
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
// ...
plugins: [
new CleanWebpackPlugin(),
// ...
]
}
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// ...
plugins: [
// ...
new CopyWebpackPlugin({
patterns: [
{
from: 'public',
globOptions: {
ignore: ['**/index.html']
}
}
]
})
]
}
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'production',
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: 'public',
globOptions: {
ignore: ['**/index.html']
}
}
]
})
]
}
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
module.exports = {
plugins: [
require('postcss-preset-env')
]
}
{
"name": "vue-app-base",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "NODE_ENV=development webpack serve --config ./webpack.common.js",
"build": "NODE_ENV=production webpack --config ./webpack.common.js",
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.16.0",
"@vue/cli-plugin-babel": "^4.5.15",
"babel-loader": "^8.2.3",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.0.0",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"postcss": "^8.4.4",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.0.1",
"style-loader": "^3.3.1",
"vue": "^2.6.14",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0",
"webpack-merge": "^5.8.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
npm i css-minimizer-webpack-plugin mini-css-extract-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 需自行安装 需webpack5版本
···
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // 压缩css 文件
{
loader: 'css-loader',
options: {
importLoaders: 1,
esModule: false
}
},
'postcss-loader'
]
},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
}
]
...
plugins:[
...
new MiniCssExtractPlugin({ // 抽离css 插件
filename: "[name].css",
}),
]
}
···
...
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 需自行安装 需webpack5版本
module.exports = {
mode: 'production',
// ...
optimization: {
minimize: true, // 开启代码压缩
minimizer: [
new CssMinimizerPlugin() // 插件使用 cssnano 优化和压缩 CSS
]
},
// ...
}
splitChunks: {
chunks: 'all', // async initial all
minSize: 20000,
maxSize: 20000,
minChunks: 1,
cacheGroups: {
syVendors: {
test: /[\\/]node_modules[\\/]/,
filename: 'js/[id]_vendor.js',
priority: -10,
},
default: {
minChunks: 2,
filename: 'js/chunk_[id].js',
priority: -20,
}
}
}
const TerserPlugin = require("terser-webpack-plugin"); // webpack5自带插件
module.exports = {
mode: 'production',
// ...
optimization: {
usedExports: true, // 开启tree shaking ,需结合terser-webpack-plugin 来实现
minimize: true, // 开启代码压缩
minimizer: [
new TerserPlugin({
extractComments: false
})// js代码压缩的插件
// ...
]
}
}
npm i purgecss-webpack-plugin -D
const PurgecssPlugin = require('purgecss-webpack-plugin') // 需自行安装
module.exports = {
mode: 'production',
// ...
plugins:[
// ...
new PurgecssPlugin({ // 移除未使用的css代码
paths: glob.sync(`${path.resolve(__dirname, './src')}/**/*`, { nodir: true }),
})
]
}
npm i webpack-bundle-analyzer -D
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
module.exports = {
mode: 'production',
plugins: [
//...
new BundleAnalyzerPlugin()
]
}
npm i eslint -D
npx eslint --init
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:vue/essential",
"standard"
],
"parserOptions": {
"ecmaVersion": 13,
"sourceType": "module"
},
"plugins": [
"vue"
],
"rules": {
"vue/html-self-closing": [0]
}
};
npm i eslint-loader -D
...
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: ['babel-loader']
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: 'eslint-loader',
enforce: "pre"
},
...
如果是 Vue 2.x 项目,配置了 eslint-plugin-vue 插件和 extends 后,template 校验还是会失效,因为不管是 ESLint 默认的解析器 Espree 还是 babel-eslint 都只能解析 JS,无法解析 template 的内容。
配置解析器
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"plugin:vue/essential",
"standard"
],
"parserOptions": {
"parser": "babel-eslint", // 补充
"ecmaVersion": 13,
"sourceType": "module"
},
"plugins": [
"vue"
],
"rules": {
"vue/html-self-closing": [0]
}
};
node_modules
dist
public
"lint": "eslint --fix --ext .js,.vue src --ignore-path .eslintignore"
npm install prettier eslint-config-prettier -D
{
"arrowParens": "always",
"singleQuote": true,
"trailingComma": "none",
"semi": false
}
build/*.js
src/assets
public
dist
node_modules
"prettier": "prettier --write ."
npm install pre-commit -D
npm install mrm@2 -D
npx mrm lint-staged
{
"scripts": {
"prepare": "husky install"
},
"devDependencies": {
"husky": "^6.0.0",
"lint-staged": "^11.0.0",
"mrm": "^2.6.2",
"prettier": "2.3.0"
},
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
}
}
npx husky add .husky/pre-commit "npx lint-staged"
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
# 启动 git hooks
cd .. && husky install shop-web/.husky
# 添加 pre-commit 钩子
npx husky add .husky/pre-commit "cd shop-web && npx lint-staged"
# 安装 lint-staged
npm install lint-staged -D
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
#!/bin/sh
"$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
规范 commit 为 git commit -m ''feat(*):提交名称'
npm install --save-dev @commitlint/config-conventional @commitlint/cli
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
}
{
"name": "vue2-webpack-demo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "NODE_ENV=development webpack serve --config ./webpack.common.js",
"build": "NODE_ENV=production webpack --config ./webpack.common.js",
"lint": "eslint --fix --ext .js,.vue src --ignore-path .eslintignore ",
"prettier": "prettier --write .",
"prepare": "husky install"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.4",
"@vue/cli-plugin-babel": "^4.5.15",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.3",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.0.0",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.2.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-vue": "^8.2.0",
"glob": "^7.2.0",
"html-webpack-plugin": "^5.5.0",
"husky": "^7.0.4",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"lint-staged": "^12.1.2",
"mini-css-extract-plugin": "^2.4.5",
"mrm": "^2.6.2",
"postcss": "^8.4.4",
"postcss-loader": "^6.2.1",
"postcss-preset-env": "^7.0.1",
"pre-commit": "^1.2.2",
"prettier": "^2.5.1",
"purgecss-webpack-plugin": "^4.1.3",
"vue": "^2.6.14",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0",
"webpack-merge": "^5.8.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
],
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
}
}
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 需自行安装 需webpack5版本
const { DefinePlugin } = require('webpack')
const path = require('path')
const { merge } = require('webpack-merge')
const devConfig = require('./webpack.dev')
const prodConfig = require('./webpack.prod')
const isProduction = process.env.NODE_ENV === 'production'
const commonConfig = {
entry: './src/main.js',
output: {
filename: '[name].[contenthash:8].js',
path: path.resolve(__dirname, './dist'),
// publicPath: `//xxx.com/`,
chunkFilename: '[name].[contenthash:8].js'
},
resolve: {
extensions: ['.js', '.json', '.ts', '.jsx', '.vue'],
alias: {
'@': path.resolve(__dirname, './src')
}
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // 压缩css 文件
{
loader: 'css-loader',
options: {
importLoaders: 1,
esModule: false
}
},
'postcss-loader'
]
},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
},
{
test: /\.(png|svg|gif|jpe?g)$/,
type: 'asset',
generator: {
filename: 'img/[name].[contentHash:4][ext]'
},
parser: {
dataUrlCondition: {
maxSize: 30 * 1024
}
}
},
{
test: /\.(ttf|woff2?)$/,
type: 'asset/resource',
generator: {
filename: 'font/[name].[contentHash:3][ext]'
}
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: ['babel-loader']
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: 'eslint-loader',
enforce: 'pre'
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({ // 抽离css 插件
filename: "[name].[contentHash:4].css",
}),
new HtmlWebpackPlugin({
title: '设置的标题',
template: './public/index.html'
}),
new DefinePlugin({
BASE_URL: '"./"'
}),
new VueLoaderPlugin()
]
}
const baseConfig = isProduction ? prodConfig : devConfig
const defaultConfig = merge(commonConfig, baseConfig)
module.exports = defaultConfig
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
hot: true,
port: 8080,
open: false,
compress: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'https://api.github.com',
pathRewrite: { '^/api': '' },
changeOrigin: true
}
}
}
}
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const TerserPlugin = require("terser-webpack-plugin"); // webpack5自带插件
const PurgecssPlugin = require('purgecss-webpack-plugin') // 需自行安装
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 需自行安装 需webpack5版本
const glob = require('glob')
const path = require('path')
module.exports = {
mode: 'production',
optimization: {
usedExports: true, // 开启tree shaking ,需结合terser-webpack-plugin 来实现
minimize: true, // 开启代码压缩
minimizer: [
new TerserPlugin({
extractComments: false
}),// js代码压缩的插件
new CssMinimizerPlugin() // 插件使用 cssnano 优化和压缩 CSS
],
splitChunks: {
chunks: 'all', // async initial all
minSize: 20000,
maxSize: 20000,
minChunks: 1,
cacheGroups: {
syVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
},
default: {
minChunks: 2,
priority: -20,
}
}
}
},
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: 'public',
globOptions: {
ignore: ['**/index.html']
}
}
]
}),
new PurgecssPlugin({ // 移除未使用的css代码
paths: glob.sync(`${path.resolve(__dirname, './src')}/**/*`, { nodir: true }),
}),
new BundleAnalyzerPlugin()
]
}
module.exports = {
presets: ['@vue/cli-plugin-babel/preset']
}
module.exports = {
plugins: [require('postcss-preset-env')]
}
{
"arrowParens": "always",
"singleQuote": true,
"trailingComma": "none",
"semi": false
}
module.exports = {
env: {
browser: true,
es2021: true
},
extends: ['plugin:vue/essential', 'standard'],
parserOptions: {
parser: 'babel-eslint',
ecmaVersion: 13,
sourceType: 'module'
},
plugins: ['vue'],
rules: {
'vue/html-self-closing': [0]
}
}
.eslintignore
node_modules
dist
public
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。