webpack
文档
官方网站:webpack.js.org/
中文网站:www.webpackjs.com/
1.webpack简介
webpack is a module bundler(模块打包工具)
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
Webpack是⼀一个打包模块化JavaScript的⼯具,它会从⼊口模块出发,识别出源码中的模块化导⼊语句,递归地找出⼊口⽂件的所有依赖,将⼊口和其所有的依赖打包到⼀个单独的⽂件中
是工程化、自动化思想在前端开发中的体现
2.安装webpack
-
环境准备
node.js:nodejs.org/en/
版本参考官⽹发布的最新版本,可以提升webpack的打包速度
-
全局安装(不推荐)
# 安装webpack V4+版本时,需要额外安装webpack-cli
npm install webpack webpack-cli -g
# 检查版本
webpack -v
# 卸载
npm uninstall webpack webpack-cli -g
全局安装webpack,这会将你项目中的webpack锁定到指定版本,造成不同 的项目中因为webpack依赖不同版本⽽导致冲突,构建失败
-
项目安装(推荐)
# 安装最新的稳定版本
npm i webpack webpack-cli -D
# 安装指定版本
npm i -D webpack@<version>
# 安装最新的体验版本 可能包含bug,不要⽤于生产环境
npm i -D webpack@beta
- 检查安装
webpack -v //command not found 默认在全局环境中查找
npx webpack -v// npx帮助我们在项目中的node_modules⾥里里查找webpack ./node_modules/.bin/webpack -v//到当前的node_modules模块⾥指定 webpack
3.启动webpack执行构建
1.webpack 默认配置
- 默认入口模块
- ./src/index.js
- 默认输出
- 名称 main.js
- 路径是 './dist'
- webpack 默认支持多种模块类型:比如CommonJS ESModule AMD
- webpack默认支持js模块和json模块
- webpack4⽀持零配置使⽤,但是很弱,稍微复杂些的场景都需要额外扩 展
2.准备执行构建
- 新建src文件夹
- 新建src/index.js, src/index.json, src/other.js
// index.js
const json = require("./index.json");//commonJS import { add } from "./other.js";//es module console.log(json, add(2, 3));
// index.json
{
"name": "JSON"
}
// other.js
export function add(a, b) {
return a + b
}
3.执行构建
# npx方式
npx webpack
# npm script
npm run test
修改package.json文件
"scripts": {
"test": "webpack"
}
原理就是通过shell脚本在node_modules/.bin目录下创建一个软链接
4.构建成功
我们会发现目录下多出一个 dist 目录,里面有个 main.js ,这个文件是 一个可执行的JavaScript文件,里面包含webpackBootstrap启动函数
5.默认配置
// webpack.config.js
const path = require('path')
module.exports = {
//! 必填 webpack 执行构建入口
entry: './src/index.js',
//! 出口
output: {
//! 将所有依赖的模块合并输出到main.js
filename: 'main.js',
//! 输出文件的存放路径,必须是绝对路径
path: path.resolve(__dirname, './dist')
},
module: {
rules: [
//! loader模块处理(执行顺序从下到上,从右到左)
{
test: /\.css$/,
use: 'style-loader'
}
]
},
plugins: [ //! 插件配置
new HtmlWebpackPlugin()
]
}
4.webpack配置核心概念
webpack有默认的配置文件,叫 webpack.config.js ,我们可以对这个文件进行修改,进行个性化配置
- 使用默认的配置文件:webpack.config.js
- 不使用自定义配置文件:比如webpack.dev.js,可以通过 --config webapcK.dev.js来指定webpack使用哪个配置文件来执行构建
webpack.config.js配置基础结构
module.exports = {
entry: './src/index.js', // 打包入口文件
output: './dist', // 输出结构
mode: 'production', // 打包环境
module: {
rules: [
//! loader模块处理(执行顺序从下到上,从右到左)
{
test: /\.css$/,
use: 'style-loader'
}
]
},
plugins: [ //! 插件配置
new HtmlWebpackPlugin()
]
}
1.entry
指定webpack打包入口文件:Webpack 执行构建的第一步将从 Entry 开始, 可抽象成输入
// 单入口
entry: {
main: './src/index.js'
}
// 相当于简写
entry:"./src/index.js"
// 多入口 entry是个对象
entry: {
index: './src/index.js',
login: './src/login.js'
}
2.output
打包转换后的文件输出到磁盘位置:输出结果,在webpack经过一系列处理并得出最终想要的代码后输出结果
//! 出口
output: {
//! 将所有依赖的模块合并输出到main.js
filename: 'main.js',
//! 输出文件的存放路径,必须是绝对路径
path: path.resolve(__dirname, './dist')
},
// 多入口的处理
output: {
filename: '[name][chunkhash:8].js', // 利用占位符,文件名称不要重复
path: path.resolve(__dirname, './dist') // 输出⽂文件到磁盘的⽬目录,必 须是绝对路路径
}
3.mode
mode用来指定当前的构建环境
- production(默认)
- development
- none
设置mode可以自动触发webpack内置的函数,达到优化的效果
| 选项 | 描述 |
|---|---|
| development | 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 |
| production | 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin. |
如果没有设置,webapck默认mode为 production。模式支持的值为
记住,只设置 NODE_ENV,则不会自动设置 mode。
开发阶段的开启会有利于热更新的处理,识别哪个模块变化
生产阶段的开启会有帮助模块压缩,处理副作⽤等一些功能
4.loader
模块解析,模块转换器,⽤于把模块原内容按照需求转换成新内容。
webpack是模块打包⼯工具,⽽模块不仅仅是js,还可以是css,图片或者其他 格式
但是webpack默认只知道如何处理js和JSON模块,那么其他格式的模块处理,和处理⽅式就需要loader了
常见的loader
style-loader
css-loader
less-loader
sass-loader
ts-loader //将Ts转换成js
babel-loader//转换ES6、7等js新特性语法
file-loader//处理理图⽚片⼦子图
eslint-loader
vue-loader
...
5.module
模块,在 Webpack 里一切皆模块,一个模块对应着一个⽂文件。Webpack 会 从配置的 Entry 开始递归找出所有依赖的模块。
当webpack处理到不认识的模块时,需要在webpack中的module处进行配 置,当检测到是什么格式的模块,使⽤什么loader来处理。
module: {
rules: [
//! loader模块处理(执行顺序从下到上,从右到左)
{
test: /\.xxx$/, // 指定匹配规则
use: {
loader: 'xxx-loader' // 指定使用的loader
}
}
]
},
- 处理静态资源模块: file-loader
原理是把打包⼊口中识别出的资源模块,移动到输出目录,并且返回一 个地址名称
所以我们什什么时候⽤用file-loader呢?
场景:就是当我们需要模块,仅仅是从源代码挪移到打包目录,就可以 使⽤file-loader来处理,txt,svg,csv,excel,图⽚资源啦等等
// 记得先去安装对应loader
npm install file-loader -D
举个栗子
module: {
rules: [
//! loader模块处理(执行顺序从下到上,从右到左)
{
test: /\.(png|jpe?g|gif)$/,
// use使用⼀个loader可以用对象,字符串,两个loader需要用数组
use: [{
loader: 'file-loader',
// options额外的配置,比如资源名称
options: {
// placeholder 占位符 [name]老资源模块的名称
// [ext]老资源模块的后缀
name: '[name]_[hash].[ext]',
// 打包后的存放位置
outputPath: 'images/'
}
}]
}
]
},
// index.js
import pic from './logo.jpg'
var img = new Image()
img.src = pic
img.classList.add('logo')
var root = document.getElementById("root");
root.append(img);
- 处理字体(推荐iconfont)
// css
@font-face {
font-family: webfont;
font-display: swap;
src: url('webfont.woff2') format('woff2')
}
body {
background: red;
font-family: 'webfont' !important;
}
// webpack.config.js
{
test: /\.(eot|ttf|woff|woff2|svg)$/,
use: 'file-loader'
}
-
url-loader file-loader加强版本
url-loader内部使⽤了file-loader,所以可以处理file-loader所有的事情,但 是遇到jpg格式的模块,会把该图片转换成base64格式字符串,并打包 到js里。对小体积的图片比较合适,大图片不合适。
npm install url-loader -D
举个栗子
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
// 小于2048,才换成base64
limit: 2048
}
}
}
]
}
- 样式处理
css-loader分析css模块之间的关系,并合成一个css
style-loader会把css-loader生成的内容,以style挂载到页面的header部分
npm install style-loader css-loader -D
{
test: /\.css$/,
//! css-loader分析css模块之间的关系,并合成一个css
//! style-loader会把css-loader生成的内容,以style挂载到页面的header部分
use: ['style-loader', 'css-loader']
},
{
test: /\.css$/,
use:[
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag' // 将所有的style标签合并成一个
}
}, 'css-loader'
]
}
Less样式处理(Scss一样)
less-loader 把less语法转换成css
npm install less less-loader -D
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
- 样式自动添加前缀:postcss-loader
npm install postcss-loader autoprefixer -D
新建post.config.js
// webpack.config.js
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')({
overrideBrowserslist: ["last 2 versions", ">1%"]
})
]
}
5.plugins
plugin 可以在webpack运⾏行行到某个阶段的时候,帮你做⼀一些事情,类似于⽣生 命周期的概念
扩展插件,在 Webpack 构建流程中的特定时机注⼊入扩展逻辑来改变构建结 果或做你想要的事情。
作⽤用于整个构建过程
HtmlWebpackPlugin
htmlwebpackplugin会在打包结束后,自动⽣生成一个html文件,并把打包生 成的js模块引入到该html中。
npm install html-webpack-plugin -D
配置
title: 用来生成⻚页⾯面的 title 元素
filename: 输出的 HTML 文件名,默认是 index.html, 也可以直接配置带有⼦目录。
template: 模板文件路路径,支持加载器器,比如 html!./index.html
inject: true | 'head' | 'body' | false ,注⼊入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素 中。
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加⼀一个唯⼀一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有⽤用。
cache: true | false,如果为 true, 这是默认值,仅在文件修改之后才会发布文件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML ⻚页⾯面中 chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到页⾯面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块)
// 示例
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [ //! 插件配置
new HtmlWebpackPlugin({
title: 'My App',
filename: 'app.name',
template: './src/index.html'
})
]
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='root'></div>
</body>
</html>
clean-webpack-plugin
clean-webpack-plugin会先删除之前打包生成的dist目录,然后在生成最新的打包后的dist
npm install clean-webpack-plugin -D
示例:
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
plugins: [
new CleanWebpackPlugin()
]
mini-css-extract-plugin
npm install mini-css-extract-plugin -D
示例:
const MiniCssExtractplugin = require('mini-css-extract-plugin')
{
test: /\.css$/,
use: [MiniCssExtractplugin.loader, 'css-loader']
}
new MiniCssExtractplugin({
filename: '[name][chunkhash:8].css'
})
6.sourceMap
源代码与打包后的代码的映射关系,通过sourceMap定位到源代码。 在dev模式中,默认开启,关闭的话 可以在配置⽂文件⾥里里
devtool: 'none'
eval: 速度最快,使用eval包裹模块代码, source-map: 产生 .map ⽂文件 cheap: 较快,不包含列列信息 Module:第三方模块,包含loader的sourcemap(比如jsx to js ,babel的 sourcemap) inline: 将 .map 作为DataURI嵌⼊入,不不单独⽣生成 .map ⽂文件
配置推荐
devtool:"cheap-module-eval-source-map",// 开发环境配置
//线上不不推荐开启
devtool:"cheap-module-source-map", // 线上⽣生成配置