webpack.config.js
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const workers = require('os').cpus().length;
module.exports = {
entry: "./src/main.js",
output: {
path: path.resolve(__dirname, './dist'),
filename: "js/index.js",
chunkFilename:"js/[name].js",
clean: true,
},
mode: process.env.NODE_ENV,
devServer: {
port: 8080,
hot: true,
// open: true,
proxy: {}
},
plugins: [
new htmlWebpackPlugin({
template: "./src/index.html"
}),
new ESLintPlugin({
exclude: "node_modules",
context: path.resolve(__dirname, './src'),
cache: true,
cacheLocation: path.resolve(__dirname, "./node_modules/.cache/eslintcache")
}),
new MiniCssExtractPlugin({
filename: 'css/[hash:10]-[name].css',
chunkFilename: '[id].css',
})
],
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin({
parallel: workers, //启用多进程打包
}),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: [
["gifsicle", { interlaced: true }],
["jpegtran", { progressive: true }],
["optipng", { optimizationLevel: 5 }],
[
"svgo",
{
plugins: [
"preset-default",
"prefixIds",
{
name: "sortAttrs",
params: { xmlnsOrder: "alphabetical" }
}
]
},
],
],
}
},
}),
],
},
// devtool: "source-map",//生成map文件用于定位错误
module: {
rules: [
{
test: /\.css$/i,
// use: ["style-loader", "css-loader"],
use: [...CssProcess()]
},
{
test: /\.less$/i,
use: [...CssProcess("less-loader")],
},
{
test: /\.s[ac]ss$/i,
use: [...CssProcess("sass-loader")],
},
{
test: /\.styl$/,
use: [...CssProcess(),
{
loader: 'stylus-loader',
options: {
stylusOptions: {
compress: true
}
}
},
]
},
{
test: /.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024//小于10kb将图片转换为base64,减少请求数量
}
},
generator: {
filename: 'public/imgs/[hash:10]-[name][ext]'
}
},
{
test: /\.html$/i,
loader: "html-loader"
},
{
test: /\.(eot|ttf|woff|woff2|svg|mp3|mp4|avi)$/,
type: "asset/resource",
generator: {
filename: "public/media"
}
},
{
test: /\.(m?js|ts)$/,
exclude: /(node_modules|bower_components)/,
use: [
{
loader: "thread-loader",
// 有同样配置的 loader 会共享一个 worker 池
options: {
workers,
workerParallelJobs: 50,
// 额外的 node.js 参数
workerNodeArgs: ['--max-old-space-size=1024'],
// 允许重新生成一个僵死的 work 池,这个过程会降低整体编译速度,并且开发环境应该设置为 false
poolRespawn: false,
// 闲置时定时删除 worker 进程,默认为 500(ms),可以设置为无穷大,这样在监视模式(--watch)下可以保持 worker 持续存在
poolTimeout: 2000,
// 池分配给 worker 的工作数量,默认为 200,降低这个数值会降低总体的效率,但是会提升工作分布更均一
poolParallelJobs: 200,
// 池的名称,可以修改名称来创建其余选项都一样的池
name: "my-pool"
},
},
{
loader: 'babel-loader',
options: {
cacheDirectory: true, // 开启缓存
cacheCompression: false, // 关闭压缩
plugins: ["@babel/plugin-transform-runtime"], //减小压缩体积
// presets: ['@babel/preset-env']
}
}
]
}
],
}
}
function CssProcess(type) {
if (type == "sass-loader" || type == "less-loader" || type == "stylus-loader") {
return [
MiniCssExtractPlugin.loader, //替换style-loader
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env'],
],
},
},
},
type,
];
} else {
return [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
['postcss-preset-env'],
],
},
},
},
]
}
}
babel.config.js
// babel设置预设
// babel/preset-env // 编译使用最新javascript语言预设
// babrl/preset-reset // 编译使用react jsx预设
// babel/preset-typescript // 编译typescript预设
module.exports = {
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3
},
// 指定兼容性做到那个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: 17
}
}
]
]
}
.eslintrc.js
module.exports = {
extends: ["eslint:recommended"],
env: {
node: true,
browser: true
},
parserOptions: {
ecmaVersion: 6,
sourceType: "module"
},
rules: {
"no-var": 2
},
plugins:["import"]
}
package.json
{
"name": "test1",
"version": "1.0.0",
"description": "",
"main": "./src/assets/js/main.js",
"scripts": {
"dev": "cross-env NODE_ENV=\"development\" webpack-dev-server",
"build": "cross-env NODE_ENV=\"production\" npx webpack --config ./webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/plugin-transform-runtime": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"babel-loader": "^9.1.2",
"core-js": "^3.29.0",
"cross-env": "^7.0.3",
"css-loader": "^6.7.3",
"css-minimizer-webpack-plugin": "^4.2.2",
"eslint": "^8.35.0",
"eslint-plugin-import": "^2.27.5",
"eslint-webpack-plugin": "^4.0.0",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.5.0",
"image-minimizer-webpack-plugin": "^3.8.1",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-optipng": "^8.0.0",
"imagemin-svgo": "^10.0.1",
"less": "^4.1.3",
"less-loader": "^11.1.0",
"mini-css-extract-plugin": "^2.7.2",
"postcss": "^8.4.21",
"postcss-loader": "^7.0.2",
"postcss-preset-env": "^8.0.1",
"sass": "^1.58.3",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"stylus": "^0.59.0",
"stylus-loader": "^7.1.0",
"svgo": "^3.0.2",
"terser-webpack-plugin": "^5.3.6",
"thread-loader": "^3.0.4",
"url-loader": "^4.1.1",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1",
"imagemin": "^8.0.1"
},
"browserslist": [
"last 6 version",
"> 1%",
"not dead"
]
}