一.webpack介绍
1.webpack的由来
初始网页开发时所有的js方法都放在同一个js文件中,这就出现了一个问题,一旦系统出现什么问题,要去找问题很麻烦,代码不便于维护。
接着,使用面向对象的开发方式, 把每一个对象的逻辑操作用一个单独的js封装起来,解决了代码不便于维护的问题。但是紧接着出现了另一个问题,js文件的增多,页面加载时需要进行多个http请求,这样也免得加载就会变慢。而且从js代码中看不出来文件的位置,容易差错。还需要注意文件引用的顺序,这样的代码依旧不易维护。
为了解决这些问题,出现了一种新的写法,在html中仅仅引用一个js文件,这个js文件中在需要使用其他的js文件中的内容时,直接在这个js文件中引用。但是使用平时的ES Moudule模块引入方法(import),浏览器无法识别这种语句。这个时候就需要Webpack对这个代码进行翻译,让浏览器能够识别。
2.webpack 是什么?
webpack
是一个现代 JavaScript
应用程序的静态模块打包器,当 webpack
处理应用程序时,会递归构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle
。
3.webpack 的核心概念
- entry: 入口
- output: 输出
- loader: 模块转换器,用于把模块原内容按照需求转换成新内容
- 插件(plugins): 扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要做的事情
4.webpack loader
style-loader
动态创建style
标签,将css
插入到head
中.css-loader
负责处理@import
等语句。babel-loader
,负责将ES6语法转换为ES5语法兼容IEless-loader
负责处理编译.less
文件,将其转为css
二.webpack的安装操作
1.webpack的安装
npm i webpack webpack -cli --global // 全局安装webpack
npm i webpack webpack -cli --save-dev // 局部安装webpack
webpack -v // 查看安装是否成功
2.webpack插件的安装
npm i html-webpack-plugin -D // 安装html-webpack-plugin插件
3.webpack loader的安装
npm i --save-dev css-loader ts-loader
npm i babel-loader @babel/core @babel/preset-env -D
4.webpack常用命令
npm i webpack-dev-server -D // 作用主要是开发时有热更新
npx webpack-dev-server
三.webpack的基本配置
1.entry
入口起点(entry point)指示webpack应该使用哪个模块来作为构建它的内部依赖图的开始。当进入入口之后,webpack会找出有哪些模块和库是入口起点(直接或者间接)依赖的
// 单一入口打包
module.exports = {
entry: './src/index.js', // 入口js文件的路径
};
// 多入口打包
// 1.共享方法
module.exports = {
entry: {
index: {
import: './src/index.js',
dependOn: 'shared' // 分享相同的引入文件
},
another: {
import: './src/another-module.js',
dependOn: 'shared'
},
shared: 'lodash' // 分享相同的引入文件
}
};
// 2.使用webpack自带splitChunks
module.exports = {
entry: {
index: './src/index.js',
another: './src/another-module.js',
},
optimization: {
splitChunks: {
chunks: 'all', // 全部分割
}
}
};
2.output
输出是指打包后生成的文件名称、路径等相关配置
module.exports = {
output: {
filename: 'bundle.js', // 输出js文件的文件名
path: path.resolve(__dirname, './dist'), // 输出保存到该文件夹下 必须要是绝对路径 所以得引入nodejs模块path __dirname为当前文件所在路径,第二个参数相当于基于这个路径下的路径
clean: true,// 每次打包删除上一次打包的文件
assetModuleFilename: 'images/[contenthash][ext]' // 打包资源指定的文件名 contenthash是webpack自带默认生成 ext为后缀
},
};
3.loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import
或 “load(加载)” 模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的得力方式。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript 或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import
CSS 文件!
1.基本格式
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' },
{
test: /\.png$/,
type: 'asset/resource', // 会打包成本地资源文件
generator: {
filename: 'images/[contenthash][ext]'
}
},
{
test: /\.svg$/,
type: 'asset/inline', // 会打包成data URL base64编码的文件
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'] // 从右往左解析,先把css处理完了,再用style-loader解析把css放入head
}
],
},
};
2.模块资源类型
asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现(8k以下用inline,以上用resource)
4.plugin
插件 是 webpack 的 支柱 功能。Webpack 自身也是构建于你在 webpack 配置中用到的 相同的插件系统 之上!
插件目的在于解决 loader 无法实现的其他事。Webpack 提供很多开箱即用的 插件。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 访问内置的插件
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
},
],
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' }),
],
};
5.devtool
devtool: 'inline-source-map', // 可以把打包后的js下的代码变成可读的,并且可以看到报错的具体位置
开启前
开启后
6.mode
主要有production、development和none三种配置
开发阶段的开启会有利于热更新的处理,识别哪个模块变化
生产阶段的开启会有帮助模块压缩,处理副作用等一些功能
// 生产环境打包命令
npx webpack --env production // 生产环境下会压缩代码
npx webpack --env development // 开发环境下不会压缩代码
module.exports = (env) => {
return {
mode: env.production ? 'production' : 'development', // 环境设置
}
}
7.optimization
主要是做一些打包优化
optimization: { // 优化
minimizer: [
new CssMinimizerWebpackPlugin()
],
splitChunks: {
// chunks: 'all', // 全部分割
cacheGroups: { // 缓存引入的依赖文件,这样打包后浏览器不需要重新解析
vendor: {
test: /[\\/]node_modules[\\/]/, // 获取node_modules文件夹下的文件
name: 'vendor',
chunks: 'all'
}
}
}
}
四.webpack插件
使用各种插件前要先在webpack.config.js文件最上方引入
const HtmlWebpackPlugin = require('html-webpack-plugin')
1.html-webpack-plugin
该插件的基本作用就是生成html文件
// 安装
npm i html-webpack-plugin -D
new HtmlWebpackPlugin({
template: './index.html', // 使用的html模板
filename: 'app.html', // 输出的html文件名
inject: 'body' // 决定script标签在什么位置,默认是header里
}),
2.mini-css-extract-plugin
MiniCssExtractPlugin插件可以抽离css单独link引入
// 安装
npm i mini-css-extract-plugin -D
new MiniCssExtractPlugin({
filename: 'styles/[contenthash].css', // 指定打包后的css文件名 默认main.css
})
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'] // 从右往左解析,先把css处理完了,再用style-loader解析把css放入head
}
3.css-minimizer-webpack-plugin
压缩CSS文件,提高运行速度
// 安装
npm i css-minimizer-webpack-plugin -D
optimization: { // 优化
minimizer: [
new CssMinimizerWebpackPlugin()
]
}
4.terser-webpack-plugin
压缩js文件
// 安装
npm i terser-webpack-plugin -D
五.拆分配置文件
1.在项目根目录下新建开发和生产js文件
2.修改开发环境和生产环境的配置
1.开发环境
开发环境不需要压缩文件,所以删除这两项配置
开发环境下不需要刷新缓存和根路径所以删除
mode改为开发环境的值
mode: ‘development’, // 环境设置
2.生产环境
删除devtool: ‘inline-source-map’, 因为不需要寻找报错信息
mode改为生产环境的值
mode: ‘production’, // 环境设置
删除devServer
3.抽取公共config
在webpack下新建webpack.config.common.js和webpack.config.js
在webpack.config.common.js中将生产和开发都需要的打包配置提取出来
在webpack.config.dev.js和webpack.config.prod.js中重复的代码删掉
安装webpack-merge
npm i webpack-merge -D
最后在webpack.config.js中新增配置
const { merge } = require('webpack-merge')
const commonConfig = require('./webpack.config.common') // 公共配置
const productionConfig = require('./webpack.config.prod') // 生产环境配置
const developmentConfig = require('./webpack.config.dev') // 开发环境配置
module.exports = env => {
switch(true) {
case env.production:
return merge(commonConfig, productionConfig)
case env.development:
return merge(commonConfig, developmentConfig)
default:
return new Error('No matching configuration found')
}
}
在package.json中配置
"scripts": {
"build": "webpack -c ./config/webpack.config.js --env production",
"start": "webpack serve -c ./config/webpack.config.js --env development"
},