一.webpack基础
1.简单配置
1.1 安装依赖
javascript
$ npm install webpack webpack-cli -D # 安装到本地依赖
1.2 工作模式
webpack4之后支持0配置打包
webpack提供了三种模式:
- development,开发模式,打包更加快速,省了代码优化步骤
- production,生产模式,打包比较慢,会开启 tree-shaking 和 压缩代码
- none,不使用任何默认优化选项
如何配置:
javascript
module.exports = {
mode: 'development',
};
1.3 配置文件
虽然webpack之后支持0配置打包,但是实际项目中我们通常需要通过配置文件来打包,以便满足不同的需求。
javascript
const path = require('path')
module.exports = {
mode: 'development', // 模式
entry: './src/index.js', // 打包入口地址
output: {
filename: 'bundle.js', // 输出文件名
path: path.join(__dirname, 'dist') // 输出文件目录
}
}
1.4 Loader
Loader的作用是将webpack不认识的内容转换为认识的内容。以下是一些常用loader,
1.4.1 style-loader、css-loader、sass-loader
用途:
- style-loader 用于将
css
编译完成的样式,挂载到页面style
标签上。 - css-loader 用于识别
.css
文件, 处理css
必须配合style-loader
共同使用,只安装css-loader
样式不会生效。 - sass-loader,将sass语言转换成css语言。
配置:
javascript
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
],
include: /src/,
},
]
}
}
1.4.2 postcss-loader
**用途:**用于补充css样式各种浏览器内核前缀
配置:
方式一:在webpack.config.js中配置
javascript
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')
]
}
}
]
}
方式二:在根目录创建 postcss.config.js
javascript
module.exports = {
plugins: [
require("autoprefixer")({
//兼容浏览器的最近两个版本
//兼容市场占有率大于1%的浏览器(世界的)
overrideBrowserslist: ["last 2 versions", ">1%"],
}),
],
};
1.4.3 babel-loader
**用途:**将Es6+ 语法转换为Es5语法。
安装:
javascript
cnpm i babel-loader @babel/core @babel/preset-env -D
- babel-loader 这是使babel和webpack协同工作的模块
- @bable/core 这是babel编译器核心模块
- @babel/preset-env 这是babel官方推荐的预置器,可根据用户的环境自动添加所需的插件和补丁来编译Es6代码
配置:
javascript
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
presets: [
['@babel/preset-env', { targets: "defaults"}]
]
}
}
},
]
}
}
1.4.4 ts-loader
**用途:**用于配置项目typescript
安装:
javascript
cnpm i ts-loader typescript -D
配置:
tsconfig.json
javascript
{
"compilerOptions": {
"declaration": true,
"declarationMap": true, // 开启map文件调试使用
"sourceMap": true,
"target": "es5", // 转换为Es5语法
}
}
webpack.config.js
javascript
module.exports = {
entry: "./src/index.ts",
output: {
path: __dirname + "/dist",
filename: "index.js",
},
module: {
rules: [
{
{
test: /\.ts$/,
use: "ts-loader",
}
}
]
}
}
1.4.5 file-loader
用途: 用于处理文件类型资源,如**jpg
** ,png
等图片。返回值为**publicPath
**为准。
安装:
javascript
cnpm i file-loader -D
配置:
javascript
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name]_[hash:8].[ext]",
publicPath: "https://www.baidu.com" //路径前缀
}
}
]
}
]
}
}
1.4.6 url-loader
用途:url-loader
也是处理图片类型资源,只不过它与**file-loader
** 有一点不同,url-loader
可以设置一个根据图片大小进行不同的操作,如果该图片大小大于指定的大小,则将图片进行打包资源,否则将图片转换为base64
字符串合并到js
文件里
安装:
javascript
cnpm i url-loader -D
配置:
javascript
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg)$/,
use: [
{
loader: "url-loader",
options: {
name: "[name]_[hash:8].[ext]",
limit: 10240, // 这里单位为(b) 10240 => 10kb
// 这里如果小于10kb则转换为base64打包进js文件,如果大于10kb则打包到dist目录
}
}
]
}
]
}
}
1.4.7 eslint-loader
**用途:**用于检查代码是否符合规范,是否存在语法错误。
安装:
javascript
cnpm i eslint-loader eslint -D
配置:
.eslintrc.js
javascript
module.exports = {
root: true,
env: {
browser: true,
},
rules: {
"no-alert": 0, // 禁止使用alert
"indent": [2, 4], // 缩进风格
"no-unused-vars": "error" // 变量声明必须使用
}
}
webpack.config.js
javascript
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: ["eslint-loader", "ts-loader"],
enforce: "pre",
exclude: /node_modules/
},
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/
}
]
}
}
1.5 插件(plugin)
与 Loader 用于转换特定类型的文件不同,插件(Plugin)可以贯穿 Webpack 打包的生命周期,执行不同的任务
1.5.1 HotModuleReplacementPlugin
作用: 模块热更新插件 。Hot-Module-Replacement
的热更新是依赖于 webpack-dev-server
,后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面,HRM
是只更新修改的部分。
配置:
javascript
const webpack = require('webpack')
plugins: [
new webpack.HotModuleReplacementPlugin(), // 热更新插件
]
1.5.2 html-webpack-plugin
作用: 生成 html 文件 。将 webpack 中entry
配置的相关入口 chunk
和 extract-text-webpack-plugin
抽取的 css 样式 插入到该插件提供的template
或者templateContent
配置项指定的内容基础上生成一个 html 文件,具体插入方式是将样式link
插入到head
元素中,script
插入到head
或者body
中。
配置:
javascript
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, '/index.html'),
minify: {
// 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true, // 压缩内联css
},
inject: true,
}),
]
inject 有四个选项值
- true:默认值,
script
标签位于html
文件的body
底部 - body:
script
标签位于html
文件的body
底部(同 true) - head:
script
标签位于head
标签内 - false:不插入生成的 js 文件,只是单纯的生成一个
html
文件
1.5.3clean-webpack-plugin
作用: clean-webpack-plugin
用于在打包前清理上一次项目生成的 bundle 文件,它会根据 output.path
自动清理文件夹;这个插件在生产环境用的频率非常高,因为生产环境经常会通过 hash 生成很多 bundle 文件,如果不进行清理的话每次都会生成新的,导致文件夹非常庞大。
配置:
javascript
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'),
}),
new CleanWebpackPlugin(), // 所要清理的文件夹名称
]
1.5.4extract-text-webpack-plugin
**作用:**将 css 成生文件,而非内联 。该插件的主要是为了抽离 css 样式,防止将样式打包在 js 中引起页面样式加载错乱的现象
配置:
javascript
const ExtractTextPlugin = require('extract-text-webpack-plugin')
plugins: [
// 将css分离到/dist文件夹下的css文件夹中的index.css
new ExtractTextPlugin('css/index.css'),
]
1.6 区分环境
本地开发和部署线上,通常是有不同的需求
本地环境:
- 需要更快的构建速度
- 需要打印 debug 信息
- 需要 live reload 或 hot reload 功能
- 需要 sourcemap 方便定位问题
- ...
生产环境:
- 需要更小的包体积,代码压缩+tree-shaking
- 需要进行代码分割
- 需要压缩图片体积
- ...
针对不同的需求,首先要做的就是做好环境的区分
1.本地安装 cross-env
javascript
npm install cross-env -D
2.配置启动命令
package.json
javascript
"scripts": {
"dev": "cross-env NODE_ENV=dev webpack serve --mode development",
"test": "cross-env NODE_ENV=test webpack --mode production",
"build": "cross-env NODE_ENV=prod webpack --mode production"
},
3.在 Webpack 配置文件中获取环境变量
javascript
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
console.log('process.env.NODE_ENV=', process.env.NODE_ENV) // 打印环境变量
const config = {
entry: './src/index.js', // 打包入口地址
output: {
filename: 'bundle.js', // 输出文件名
path: path.join(__dirname, 'dist') // 输出文件目录
},
module: {
rules: [
{
test: /\.css$/, //匹配所有的 css 文件
use: 'css-loader' // use: 对应的 Loader 名称
}
]
},
plugins:[ // 配置插件
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
module.exports = (env, argv) => {
console.log('argv.mode=',argv.mode) // 打印 mode(模式) 值
// 这里可以通过不同的模式修改 config 配置
return config;
}
1.7 devServer
1.安装webpack-dev-server
javascript
npm intall webpack-dev-server
当版本
version >= 4.0.0
时,需要使用 devServer.static 进行配置,不再有devServer.contentBase
配置项。
2.配置本地服务
javascript
// webpack.config.js
const config = {
// ...
devServer: {
contentBase: path.resolve(__dirname, 'public'), // 静态文件目录
compress: true, //是否启动压缩 gzip
port: 8080, // 端口号
// open:true // 是否自动打开浏览器
},
// ...
}
module.exports = (env, argv) => {
console.log('argv.mode=',argv.mode) // 打印 mode(模式) 值
// 这里可以通过不同的模式修改 config 配置
return config;
}
为什么要配置 contentBase ?
因为 webpack 在进行打包的时候,对静态文件的处理,例如图片,都是直接 copy 到 dist 目录下面。但是对于本地开发来说,这个过程太费时,也没有必要,所以在设置 contentBase 之后,就直接到对应的静态目录下面去读取文件,而不需对文件做任何移动,节省了时间和性能开销。
1.8 资源模块的使用
webpack5 新增资源模块(asset module),允许使用资源文件(字体,图标等)而无需配置额外的 loader。
资源模块支持以下四个配置:
asset/resource
将资源分割为单独的文件,并导出 url,类似之前的 file-loader 的功能.asset/inline
将资源导出为 dataUrl 的形式,类似之前的 url-loader 的小于 limit 参数时功能.asset/source
将资源导出为源码(source code). 类似的 raw-loader 功能.asset
会根据文件大小来选择使用哪种类型,当文件小于 8 KB(默认) 的时候会使用 asset/inline,否则会使用 asset/resource
配置文件
javascript
// ./src/index.js
const config = {
// ...
module: {
rules: [
// ...
{
test: /\.(jpe?g|png|gif)$/i,
type: 'asset',
generator: {
// 输出文件位置以及文件名
// [ext] 自带 "." 这个与 url-loader 配置不同
filename: "[name][hash:8][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 50 * 1024 //超过50kb不转 base64
}
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
type: 'asset',
generator: {
// 输出文件位置以及文件名
filename: "[name][hash:8][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 超过100kb不转 base64
}
}
},
]
},
// ...
}
module.exports = (env, argv) => {
console.log('argv.mode=',argv.mode) // 打印 mode(模式) 值
// 这里可以通过不同的模式修改 config 配置
return config;
}