一、概述
1.1 webpack的作用
提供友好的前端模块化开发支持,以及代码混淆、处理浏览器短JavaScript的兼容性、性能优化等强大的功能。
1.2 使用webpack的好处
重心可以放在实现具体的功能上,兼容问题可以不考虑交给webpack处理,提高前端开发的效率和可维护性。
1.3 举例
例如现在有有个项目使用es6的语法,在js中使用import语句导入了第三方的包。直接在浏览器中运行是会报错的。这个时候webpack就会派上用场了!
二、webpack的使用初体验
2.1 安装
先初始化一个空项目
npm init -y
npm install npm i webpack@5.5.1 webpack-cli@4.5.0 -D
然后在根目录下创建webpack.config.js配置文件:
module.exports = {
mode: 'development'
}
// development: 开发环境、不会对打包环境生成进行代码压缩和性能优化、打包速度快、适合开发阶段使用。
// production: 会压缩、会优化,打包速度慢,适合发布阶段使用。
再在package.json中配置运行命令:
"dev": "webpack" // dev这个命名是可以随便取
运行该命令后会在根目录中多出一个dist文件夹,其中有main.js就是编译后的js代码。可以在index.html中直接使用,不会有兼容性问题。
2.2 webpack.config.js配置文件
这个文件用于设置如何打包工程。
默认约定:
默认入口文件是src->index.js | 默认的输出文件路径为dist-> main.js
const path = require('path')
module.exports = {
mode: 'development',
// mode: 'production'
entry: path.join(__dirname, './src/index.js'), // 入口文件
output: {
path: path.join(__dirname, './dist'), // 输出文件名称
filename: 'bundle.js' // 输出文件的名称
}
}
可以通过devServer节点来设置更多的配置项,如修改项目端口。
module.exports = {
devServer: {
open: true, // 自动打开浏览器
host: '127.0.0.1', // 实时打包使用的主机地址
port: 80, // 端口号
}
}
三、 webpack插件
3.1 插件的作用
让webpack使用起来更方便,举例两个常用的插件:
- webpack-dev-server: 类似于node.js的nodemon工具,每次修改源码后就会自动打包。
- html-webpack-plugin:自定制index.html页面的内容
3.2 安装插件
安装webpack-dev-server:
npm i webpack-dev-server@3.11.0 -D
配置装webpack-dev-server
修改package.josn文件
"dev": "webpack serve"
如果执行命令后出现报错,看看是否是webpack-cli版本不对应。
打包成功后会在本地起一个8080端口的服务器,但是直接访问这个端口不会显示index.html页面,因此就引出了html-webpack-plugin,将index.html复制一份到根目录,这样就可以直接访问到index.html。
tip: 不配置webpack-dev-server,打包后的文件会存放在实际的物理磁盘上。 配置了则存放在内存上(在根目录,但是不可见),即不会实时更新。
安装html-webpack-plugin
npm i html-webpack-plugin@4.5.0 -D
配置html-webpack-plugin
// 导入构造函数
const HtmlPlugin = require('html-webpack-plugin')
// 实例化对象
const htmlplugin = new HtmlPlugin({
template: './src/index.html', // 模板文件
filename: './index.html' // 存放路径
})
module.exports = {
mode: 'development',
plugins: [htmlplugin], // 挂载插件实例对象
}
该插件也是复制到项目的根目录中的index.html页面,也被放到了内存中,且会在复制的index.html 页面底部 自动注入打包好的bundle.js文件。
四、webpack中的loader
webpack默认只能打包处理.js结尾的模块,其他非.js后缀名结尾的模块,webpack默认是处理不了的,需要调用loader加载器才可以正常打包,否则会报错。
loader的作用: 协助webpack打包处理特定的文件模块:
- css-loader打包处理.css相关的文件
- less-loader打包处理.less相关的文件
- babel-loader打包处理webpack无法处理的高级JS语法
4.1 打包处理css文件
新建一个css文件夹,并在该文件夹下创建一个index.css样式。在index.js导入(一切皆模块化,也可以导入css)
import './css/index.css'
// 安装两个
npm i style-loader@2.0.0 css-loader@5.0.1
安装完成后需要进行配置,在webpack.config.js的module->rules, 添加loader规则:
module.exports = {
module: { // 所有巅峰文件模块的匹配规则
rules: [ // 文件后缀名的匹配规则,test表示匹配的文件类型,use表示对应的调用的loader
{test: /.css$/, use: ['style-loader', 'css-loader']}
]
}
}
注意: use数组中指定的loader顺序是固定的; 多个loader的调用顺序是从后往前调用
4.2 打包处理less
npm i less-loader@7.1.0 less@3.12.2 -D
{test: /.less$/, use: ['style-loader','css-loader','less-loader']}
4.3 打包处理样式表中于url路径相关的文件
如果样式中存在背景图引入了图片等资源, webpack默认是处理不了这些的。
#box {
width: 400px;
height: 120px;
background-color: red;
background: url("../img/new_head.jpg");
}
// 安装对应的加载器
npm i url-loader@4.1.1 file-loader@6.2.0 -D
// 配置
{
test: /\.jpg|png|gif$/,
use: ['url-loader?limit=22229']
}
// limit: 这个参数是用于指定图片大小的,单位是字节byte。只要小于等于limit大小的图片,才会被转为base64格式的图片。
4.4 loader的另一种配置方式
{
test: /\.jpg|png|gif$/,
use: {
loader: 'url-loader', // 指定要调用的loader
options: { // 指定参数项
limit: 22229
}
}
}
4.5 babel处理高级语法
例如class类,static等关键字,这些webpack默认是处理不了的。此时就需要安装babel。
// 安装
npm i babel-loader@8.2.1 @babel/core@7.12.3 @babel/plugin-proposal-class-properties@7.12.1 -D
// 配置
{
test: /\.js$/,
// exclude表示排除,不处理第三方的库
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options:{
// 声明一个插件用于转化class中的高级语法
plugins: ['@babel/plugin-proposal-class-properties']
}
}
}
五、打包发布
开发环境下,打包生成的文件是存放在内存中的,无法获取到最终打包成的文件。且在开发环境下,打包的文件不会进行代码的压缩和性能优化。
5.1 整理打包后的文件
// 在package.json新增build命令
// mode用于指定打包模式
"build":"webpack --mode production"
但是,这么打包出来的文件是比较杂乱的。整理dist打包文件需要进行额外的配置:
// 1. js文件统一放到js文件夹下
entry: path.join(__dirname, './src/index.js'), // 入口文件
output: {
path: path.join(__dirname, './dist'), // 输出文件名称
filename: 'js/bundle.js' // 输出文件的名称
},
// 在url-loader插件中配置
{
test: /\.jpg|png|gif$/,
use: {
loader: 'url-loader', // 指定要调用的loader
options: { // 指定参数项
limit: 22229 ,
outputPath: 'image'
}
}
}
5.2 自动清理dist目录下的旧文件
为了在每次打包发布是自动清理掉dist目录中的旧文件,可以安装并配置clean-webpack-plugin插件。
npm i clean-webpack-plugin@3.0.0 -D
// 在入口文件index.js使用
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new CleanWebpackPlugin()
plugins: [cleanPlugin]
5.3 Source Map
开发环境下webpack默认开启了Source Map功能。默认生成的Source Map在程序运行出错时,记录的是生成后的代码位置。导致运行时报错的位置和源代码的行数不一致。
// webpack.config.js中再添加一项配置即可
devtool: 'eval-source-map'
可以直接在控制台提示错误行的位置(仅限在开发模式中使用),并定位到具体的源代码。
在生产环境下,如果省略了dev'tool选项,则最终生成的文件中不包含Source Map。这能防止源代码通过Sorce Map的形式暴露给他人。但这不方便定位到错误代码位置,可以只定位行数不暴露源码。
devtool: 'nosources-source-map', // 只定位行数,不暴露源码
devtool: 'source-map', // 定位行数并暴露源码
六、总结
实际开发中不需要自己配置webpack,有现成的脚手架 CLI 可以一键生成webpack项目,开箱即用。但是需要webpack的基本概念。