在根目录创建config文件夹,里面分别创建webpack.dev.js(开发环境)和webpack.prod.js(生产环境)配置文件。
webpack.dev.js文件配置。
const ESLintPlugin = require('eslint-webpack-plugin'); //语法检查插件
const HtmlWebpackPlugin = require('html-webpack-plugin'); //处理html文件的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //解析css的插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");//压缩css的插件
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");//压缩图片的插件
const path = require('path') //处理路径
const os = require("os"); //获取cpu的内核数量,
const TerserPlugin = require("terser-webpack-plugin");//压缩js的插件
// 核数
const threads = os.cpus().length;
// 获取处理样式的loder (由于很多css的loader用法很相似,因此提取出公共部分代码)
function getStyleLoder(pre) {
return [ //执行顺序从下到上
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
pre //如需使用其他loader可以通过传参的方式引入
].filter(Boolean) //过滤掉undefined
}
module.exports = {
// 打包入口文件
entry: './src/main.js',
// 文件输出配置
output: {
// 输出路径
// path: path.resolve(__dirname, 'dist'),
// 开发环境没有输出-可以配置 undefined
path: undefined,
// 输出的文件名
filename: 'static/js/[name].js',
// 自动清空上传打包的资源
// 开发环境没有输出打包资源所以不用配置
// clean:true
// 打包输出其他文件命名
chunkFilename:'static/js/[name].chunk.js',
// 图片 字体等通过type:asset处理资源命名方式
assetModuleFilename:'static/image/[hash:10][ext][query]'
},
// 加载器
module: {
rules: [ //loder配置
{
oneOf: [{ //处理css文件
test: /\.css$/,
use: getStyleLoder()
},
{//处理less文件
test: /\.less$/,
use: getStyleLoder("less-loader")
},
{//处理sass scss文件
test: /\.s[ac]ss$/,
use: getStyleLoder("sass-loader")
},
{//处理styl文件
test: /\.styl$/,
use: getStyleLoder("stylus-loader")
},
{//处理图片资源
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 //小于10kb转base64格式 减少请求次数
}
},
// generator: { //图片输出位置--开发环境无需配置
// filename: 'static/image/[hash:10][ext][query]'
// }
},
{ //处理字体图标音视频等其他资源文件
test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
type: "asset/resource",
// generator: { //输出位置--开发环境无需配置
// filename: 'static/media/[hash:10][ext][query]'
// }
},
{ //处理js文件 解决低版本浏览器对js的兼容问题
test: /\.m?js$/,
// exclude: /(node_modules)/, //排除node_modules文件夹
include: path.resolve(__dirname, '../src'), //只处理src文件夹下面的js文件(exclude|include 两者选择其一即可)
use: [{
loader: 'thread-loader', //开启多进程
options: {
works: threads //进程数量
}
},
{
loader: 'babel-loader',
options: {
// presets: ['@babel/preset-env'] //babel预设也可抽离出单独文件进行配置(babel.config.js)文件
cacheDirectory: true, //开启babel缓存
cacheCompression: false, //关闭缓存文件压缩
plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
},
}
]
}
]
}
]
},
// 插件
plugins: [
new ESLintPlugin({ //代码检查
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules', //默认值,排除node_modules文件夹
cache:true, //开启缓存
cacheLocation:path.resolve(__dirname,'../node_modules/.cache/eslintcache'),
threads //开启多进程
}),
new HtmlWebpackPlugin({ //处理html文件 自动引入资源
template: path.resolve(__dirname, '../public/index.html')
}),
new MiniCssExtractPlugin(),//解析css的插件
// new CssMinimizerPlugin(),
// new TerserPlugin({
// parallel:threads//开启多进程
// })
],
//webpack5之后 官方建议把处理文件压缩的插件放在optimization配置项里面
optimization: { //压缩的操作也可以放着
minimizer: [
// 压缩css
new CssMinimizerPlugin(),
// 压缩js
new TerserPlugin({
parallel: threads //开启多进程
}),
// 压缩图片-按照官方写即可
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",
},
},
],
},
],
],
},
},
}),
],
// 代码分割配置
splitChunks: {
chunks: 'all'
}
},
// 开发服务器: 内存中运行
devServer: {
host: "localhost", // 启动服务器域名
port: "3000", // 启动服务器端口号
open: true, // 是否自动打开浏览器
hot: true, //开启HDM(热更新)
},
// 模式
mode: 'development',
// 用于配置soutceMap(源文件映射),
// 当代码报错时,能够清晰的显示出是具体对于源文件的哪一行报错
devtool: "cheap-module-source-map",
}
module.exports = {
// 继承 Eslint 规则
// 如需使用vue或者react 此处直接继承官方的写法即可 (vue-app|react-app)
extends: ["eslint:recommended"],
env: {
node: true, // 启用node中全局变量
browser: true, // 启用浏览器中全局变量
},
parserOptions: {
ecmaVersion: 6, //es6
sourceType: "module", //es module
},
// 如需重构,在下面配置即可覆盖
rules: {
"no-var": 2, // 不能使用 var 定义变量
},
plugins:['import'] //允许使用import关键词引入文件
};
module.exports = {
presets: [
//智能预设,能够编译ES6语法
// 如果使用vue和react可以直接使用方法预设 presets:['react-app'] | presets:['vue-app']
['@babel/preset-env', {
//usage 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加。
useBuiltIns: 'usage',
corejs: 3 //确定corejs的版本
}],
]
}
"browserslist": [
"last 2 version",
"> 1%",
"not dead"
],
“last 2 version":兼容到浏览器最新的两个版本
“> 1%” :兼容99%的浏览器
“not dead”:摒弃已经废弃的浏览器
到此为止开发环境的webpack配置已经完成可通过命令:webpack serve --config ./config/webpack.dev.js进行开发环境的打包操作。
const ESLintPlugin = require('eslint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');
const os = require("os");
const WorkboxPlugin = require('workbox-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
// 核数
const threads = os.cpus().length;
const path = require('path')
// 获取处理样式的loder
function getStyleLoder(pre) {
return [ //执行顺序从下到上
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
pre
].filter(Boolean)
}
module.exports = {
// 入口
entry: './src/main.js',
// 输出
output: {
// 输出路径
path: path.resolve(__dirname, '../dist'),
// 入口文件打包输出文件名
filename: 'static/js/[name].js',
// 自动清空上传打包的资源
clean: true,
// 打包输出其他文件命名
chunkFilename:'static/js/[name].chunk.js',
// 图片 字体等通过type:asset处理资源命名方式
assetModuleFilename:'static/image/[hash:10][ext][query]'
},
// 加载器
module: {
rules: [ //loder配置
{
oneOf: [{
test: /\.css$/,
use: getStyleLoder()
},
{
test: /\.less$/,
use: getStyleLoder("less-loader")
},
{
test: /\.s[ac]ss$/,
use: getStyleLoder("sass-loader")
},
{
test: /\.styl$/,
use: getStyleLoder("stylus-loader")
},
{
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 //小于10kb转base64 减少请求次数
}
},
// generator: { //图片输出位置
// filename: 'static/image/[hash:10][ext][query]'
// }
},
{ //字体图标音视频等其他资源文件
test: /\.(ttf|woff2?|mp3|mp4|avi)$/,
type: "asset/resource",
// generator: { //输出位置
// filename: 'static/media/[hash:10][ext][query]'
// }
},
{ //处理js文件 兼容 todo
test: /\.m?js$/,
// exclude: /(node_modules)/, //排除node_modules
include: path.resolve(__dirname, '../src'), //只处理src文件夹下面的js文件
use: [{
loader: 'thread-loader', //开启多进程
options: {
works: threads //进程数量
}
},
{
loader: 'babel-loader',
options: {
// presets: ['@babel/preset-env']
cacheDirectory: true, //开启babel缓存
cacheCompression: false, //关闭缓存文件压缩
plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
},
}
]
}
]
}
]
},
// 插件
plugins: [
new ESLintPlugin({ //代码检查
context: path.resolve(__dirname, '../src'),
exclude: 'node_modules', //默认值,排除node_modules文件夹
cache: true, //开启缓存
cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintcache'),
threads //开启多进程
}),
new HtmlWebpackPlugin({ //处理html文件 自动引入资源
template: path.resolve(__dirname, '../public/index.html')
}),
new MiniCssExtractPlugin({ //提取css成单独的文件
filename: 'static/css/[name].[contenthash:10].css',
chunkFilename: 'static/css/[name].chunk.[contenthash:10].css',
}),
// new CssMinimizerPlugin(),
// new TerserPlugin({
// parallel:threads//开启多进程
// })
// js按需加载 缓存
new PreloadWebpackPlugin({
rel:'preload',
as:'script'
// rel:'prefetch'
}),
new WorkboxPlugin.GenerateSW({
// 这些选项帮助快速启用 ServiceWorkers
// 不允许遗留任何“旧的” ServiceWorkers
clientsClaim: true,
skipWaiting: true,
}),
],
optimization: { //压缩的操作也可以放着
minimizer: [
// 压缩css
new CssMinimizerPlugin(),
// 压缩js
new TerserPlugin({
parallel: threads //开启多进程
}),
// 压缩图片
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",
},
},
],
},
],
],
},
},
})
],
// 代码分割配置
splitChunks: {
chunks: 'all'
},
runtimeChunk: {
name:(entrypoint)=>`runtuime~${entrypoint.name}.js`,
}
},
// 开发服务器: 内存中运行
// 生产模式不需要
// devServer: {
// host: "localhost", // 启动服务器域名
// port: "3000", // 启动服务器端口号
// open: true, // 是否自动打开浏览器
// },
// 模式
mode: 'production',
devtool: "source-map",
}
"scripts": {
"start": "npm run dev",
"dev": "webpack serve --config ./config/webpack.dev.js",
"build": "webpack --config ./config/webpack.prod.js"
},
即开发环境打包命令:npm start 或者 yarn start
生产环境打包命令:npm run build 或者 yarn run build
特别感谢:尚硅谷
本人webpack初学者,如有大神有高见随时求打扰,如有不解也可在评论区相互探讨相互进步。
给个小赞谢谢