本质上,webpack 是一个用于现代 JavaScript 应用程序的_静态模块打包工具_。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
1.核心概念
(1).入口(entry):入口指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
(2).出口(output):告诉 webpack 在哪里输出以及如何命名这些文件
(3).loader:让webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上是一个函数。
(4).插件(plugins):loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务
(5).模式(mode):选择 development 或者 production 。
2.配置webpack.config.js
const { resolve } = require("path")
//引入html编译插件
const HtmlWebpackPlugin = require("html-webpack-plugin")
//低版本用extract-text-webpack-plugin分离打包,optimize-css-assets-webpack-plugin压缩,
//高版本使用MiniCssExtractPlugin分离打包,css-minimizer-webpack-plugin压缩。
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
//压缩插件
//const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin")
//语法检查插件
const EslintWebpackPlugin = require("eslint-webpack-plugin")
//定义nodejs的环境使用browseerslist的环境
//process.env.NODE_ENV == "development"
//封装css
const commomCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
}
]
module.exports = {
//定义入口文件
//entry: ["./src/js/index.js", "./src/index.html"],
//定义多个入口文件
entry: {
main: './src/js/index.js',
two: './src/js/two.js'
},
//定义输出文件
output: {
//输出文件名
filename: "js/[name].[contenthash:10].js",
path: resolve(__dirname, "build")
},
//loader配置
module: {
rules: [
{
oneOf: [
{
//js代码配置
test: /\.js$/,
exclude: /node_modules/,
//js兼容性问题
loader: 'babel-loader',
//预设:提示babel做怎么样处理兼容性问题
options: {
presets: [
[
'@babel/preset-env',
{
//按需加载
useBuiltIns: 'usage',
//指定core-js版本
corejs: { version: 3 },
//指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
//开启缓存
cacheDirectory: true
}
},
//css的配置
{
//匹配哪些文件
test: /\.css$/,
//使用哪些loader进行处理
//use数组中loader执行顺序,从右到左,从下到上,依次执行
use: [...commomCssLoader,],
},
//less的配置
{
//配置less文件的打包
test: /\.less$/,
use: [...commomCssLoader, 'less-loader']
// eslint-disable-next-line linebreak-style
},
//图片资源的配置
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
esModule: false,//关闭es6模块语法
outputPath: 'imgs'
}
},
//处理html的img资源
{
test: /\.html$/,
loader: 'html-loader',
},
//处理其他资源
{
exclude: /\.(html|js|css|less|jpg|png|gif|)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media',//打包输出的文件路径
}
},
]
}
]
},
//plugins的配置
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
//压缩html代码
minify: {
//移除空格
collapseWhitespace: true,
//移除注释
removeComments: true
}
}),
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css'
}),
new CssMinimizerWebpackPlugin(),
new EslintWebpackPlugin({
fix: true,
})
],
//开发模式
//mode: "development",
mode: "production",
//开发服务器devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特点:只会在内存中编译打包,不会有任何文件生成
//启动命令: npx webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
//启动压缩
compress: true,
//端口号
port: 3000,
//自动打开浏览器
open: true,
//开启HMR功能,在development模式下
hot: true,
},
devtool: 'source-map',
//将node_modules中的代码单独打包成一个chunk输出
// optimizetion:{
// spliChunks:{
// chunks:"all",
// }
// },
}
3.webpack的优化
webpack性能优化分为开发环境性能优化和生产环境性能优化。
开发环境性能优化分为以下:
- 优化打包构建速度
- 优化代码调试
生产环境性能优化分为:
- 优化打包构建速度
- 优化代码运行的性能
(1)HMR
HMR : hot module replacement 热模块替换
作用:一个模块发生变化不会重新打包全部,只会打包这个模块
(提高构建效率,一般在development下使用)
(2)source-map
source-map:一种提供源码到构建后代码映射技术
作用:如果构建后代码出错了,可以通过映射关系追踪源代码错误
(3)oneof
oneof:这个里面包含的代码只会执行一个匹配的loader
作用:提高构建效率
(4)缓存
缓存:和HMR有点类似不过HMR在development模式,缓存在production模式
作用:提高构建效率一般在production模式
(1)hash:每次webpack构建时都会生成一个唯一的hash值
(2)chunkhash:如果打包来自同一个chunk,那么hash值就一样。
(3)contenthash:根据文件的内容生成hash值,不同文件的hash值都不一样
(5)tree shaking
tree shaking:默认在production开启
作用:去除无用代码,减少代码体积
(6)code spilt
code spit:分割代码主要针对js代码
作用:方便代码管理
(7)懒加载&预加载
懒加载: 用的时候在加载
预加载 prefetch: 浏览器有空闲,再加载
作用:优化用户体验
(8)PWA
PWA: (Progress web apps) 渐进式网络开发应用程序。
作用:可离线访问,优化用户体验
(9)多进程
多进程:开启多个打包,加快打包速度
作用:加快构建,进程开启大概要6秒,对于小体积的根本不算优化,只有体积较大,才能体现出优势
(10)externals
externals:排除一些不打包的包
作用:减少代码体积
(11)dll
dll:会单独的对某些库进行单独打包,将多个库打包成一个chunk。
作用:可以对第三方库单独打包,提高构建效率,减少重复打包的次数