node
基础,npm
或 yarn
的基本使用ES6
语法webpack
常见配置webpack
高级配置webpack
优化策略ast
抽象语法树webpack
中的 Tapable
webpack
流程,手写 webpack
webpack
中常见的 loader
webpack
中常见的 plugin
中文官网 https://webpack.docschina.org/
中文官方文档 https://webpack.docschina.org/concepts/
WebPack可以理解为一个静态资源打包器,根据文件的入口,通过在内部构建依赖树,将项目中关联到的静态资源打包输出
mode
属性development
或 production
。例如: webpack --mode development
webpack
针对开发模式提供的特性:
浏览器调试工具
注释、开发阶段的详细错误日志和提示
快速和优化的增量构建机制
webpack
针对生产模式提供的特性:
开启所有的优化代码
更小的 bundle
大小
去除掉只在开发阶段运行的代码
Scope hoisting
和 Tree-shaking
CommonsChunkPlugin
插件,它使用内置API optimization.splitChunks
和optimization.runtimeChunk
,这意味着 webpack
会默认为你生成共享的代码块。开箱即用WebAssembly
WebAssembly(wasm)
会带来运行时性能的大幅度提升,由于在社区的热度,webpack4对它做了开箱即用的支持。你可以直接对本地的wasm模块进行 import
或者 export
操作,也可以通过编写 loaders
来直接import C++、 C或者Rust。
支持多种模块类型
共五种:
0 CJS
(0配置)
0CJS
的含义是0配置,webpack4受Parcel打包工具启发,尽可能的让开发者运行项目的成本变低。为了做到0配置,webpack4不再强制需要 webpack.config.js
作为打包的入口配置文件了,它默认的入口为 "./src/index.js'
和默认出口 './dist/main.js'
,对小项目而言是福音,不过还是建议手动配置。
新的插件系统
webpack4
对插件系统进行了不少修改,提供了针对插件和钩子的新API。
变化如下:
sync/callback/promise
作为插件类型。需要 nodeJS
版本 >= 8.9.4,因为新版本使用了很多 JS
的新语法,新版本的 node
做了优化
代码转换:ES6
转 ES5
、Less
,Sass
等转 CSS
文件优化:
代码分割:
模块合并:
自动刷新:代码热更新
代码校验:校验代码规范
自动发布:通过手写插件可以实现自动发布
全局安装容易造成版本不一致,所以选择在项目中安装
# -D 表示开发依赖,上线版本不需要
yarn add webpack webpack-cli -D
新建文件夹(项目目录)
进入目录,执行 yarn init
初始化项目,生成 package.json
项目配置文件
安装开发依赖 webpack
。yarn add webpack webpack-cli -D
,生成node_modules文件夹并下载依赖
在根目录下新建 src
文件夹,在 src
下新建 index.js
并输出一句话。console.log('I am webpack')
测试打包。npx webpack
这条命令可以使用项目中本店安装的 webpack
进行打包,从而避免全局安装 webpack
造成的版本不一致问题。结果默认会在根目录下生成 dist/main.js
文件。
注:手动配置
webpack.config.js
之后会按照配置的入口和出口生成相应的文件
webpack.config.js
的编写(node语法)webpack-dev-server
工具监听代码的更新
webpack-dev-server
是webpack
官方提供的一个小型Express
服务器,可以为webpack打包生成的资源文件提供web
服务。
npm i webpack-dev-server -S -D
在 package.json
中配置脚本,执行 webpack-dev-server
命令。webpack-dev-server
和webpack
命令用法相同的
"script":{
"dev": "webpack-dev-server"
}
执行 npm run dev
,项目开始编译并且以本地服务器方式运行在8080端口(根目录托管在8080首页)
webpack-dev-server 参数配置
webpack-dev-server
打包生成的文件并不是 dist/dist.js
。为了提高效率,会在根目录下生成 dist.js
我们在浏览器中直接访问 localhost:8080/dist.js
就能够直接看到打包好的js文件,但在项目文件中并看不到。所以我们在引用的时候可以直接引用根目录下的 dist.js
文件。webpack.config.js
中配置一般不会直接在
package.json
直接配置 webpack-dev-server,而是选择在webpack.config.js 中添加配置项
webpack.config.js
module.exports={
devServer:{
open: true, //自动打开浏览器
port: 3030, //端口号
progress: true, //显示打包进度
hot: true, //热更新(仅仅设置这里是不够的)
contentBase: "src" //首页默认路径
}
}
WebPack 4版本中只需要配置第1步
{hot:true}
devServer:{
hot: true
}
const webpack = require('webpack')
plugins:[{
new webpack.HotModuleReplacementPlugin() //创建热更新(替换)模块对象,内置在webpack中,不需要单独引入
}]
html-webpack-plugin
插件的使用
html-wepack-plugin
在内存中生成index.html
(入口),并自动注入所有的bundle
npm i html-webpack-plugin -D
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin') //引入插件
module.exports = {
...
plugins:[ //所有的都需要在这里(plugins[...])声明配置
new HtmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), //模板文件
filename: 'index.html' //生成文件名
})
]
}
html-webpack-plugin
会在内存中生成 html
,同时也会把之前内存中的 js
文件自动导入,所以不再需要手动引入本地的js
文件。
loader
的使用Webpack默认只能解析打包
js
文件,打包其他文件(css、img等)都是需要通过相应的loader
。以css文件为例
style-loader
css-loader
的使用在没有使用loader的情况下,尝试引入样式文件,在编译的时候会出现下面的错误:
错误的意思就是说需要一个合适的loader来处理css文件
npm i css-loader style-loader -D
所有的第三方模块都需要在webpack.config.js文件中的module[]节点中的rules中做规则匹配处理
// loader配置,第三方模块加载器的配置
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] } // 调用规则:从后向前
]
}
webpack在打包文件的时候会先校验文件是否为js文件,如果不是就会将文件通过后缀名匹配相应的loader处理。当使用多个loader时,处理规则是有后向前,后面的loader处理的结果依次向前传递,知道处理结束才交给webpack打包
类似的sass、less都是类似的配置
module: {
rules: [
{ test: /\.less$/, use: ['style-loader', 'css-loader','less-loader'] },
{ test: /\.sass$/, use: ['style-loader', 'css-loader','sass-loader'] }
]
}
url-loader
file-loader
的使用url-loader和file-loader可以用来处理项目中引用到的文件地址(多为img)
npm i url-loader file-loader -D
module: {
rules: [
{ test: /\.(jpg|png|jpeg|bmp|gif)$/, use: 'url-loader' } //file-loader 是内部依赖不需要手动配置
]
}
在没有配置的情况下,图片默认会以base64编码的形式引入;也可以通过设置limit属性来限制文件大小:文件大于给定的limit(单位为byte)时会被编码为base64文件,否则不编码。
webpack.config.js
module: {
rules: [
{
test: /\.(jpg|png|jpeg|bmp|gif)$/,
use: [{ loader: "url-loader", options: { limit: 10000 } }]
} // file-loaer是内部依赖不需要配置
]
}
考虑到文件重名问题,图片文件(在未被编码为base64的情况下)会以Hash值命名,我们也可以通过配置自定义文件的名字:options条件name参数
// 源文件名
options: {
limit: 10000 ,
name: '[name].[ext]' //[name]表示源文件名,[ext]是源文件扩展名
}
// 取8位hash值做前缀
options: {
limit: 10000 ,
name: '[hash:8]-[name].[ext]' //[hash:8]表示hash值前8位
}
url-loader
其他类型文件配置字体文件
{ test: /.(ttf|svg|eot|woff|woff2)$/, use: 'url-loader' }
Babel
的使用Babel 可以将 ES6 或是更高级的语法转换为 ES5 语法
# 第一套包
npm i babel-core babel-loader babel-plugin-transform-runtime -S
# 第二套包
npm i babel-preset-env babel-preset-stage-0 -S -D
// webpack.config.js
{
test: /\.js$/,
use: "babel-loader",
exclude: /node_modules/ //排除node_modules
}
注意排除 node_modules
中的 js
文件, 否则导致打包速度非常慢, 而且无法运行
.babelrc 是一个 JSON 文件, 编写必须符合 JSON 规范
{
"presets": ["env", "stage-0"],
"plugins": ["transform-runtime"]
}