webpack的官方文档是https://webpack.js.org/
webpack的中文官方文档是https://webpack.docschina.org/
点击DOCUMENTATION来到文档页:
- API:API,提供相关的接口,可以自定义编译的过程(比如自定义loader和Plugin可以参考该位置的API)
- BLOG:博客,等同于上一个tab的BLOG,里面有一些博客文章;
- CONCEPTS:概念,主要是介绍一些webpack的核心概念,比如入口、出口、Loaders、Plugins等等,但是这里并没有一些对它们解析的详细API;
- CONFIGURATION:配置,webpack详细的配置选项,都可以在这里查询到,更多的时候是作为查询手册;
- GUIDES:指南,更像是webpack提供给我们的教程,我们可以按照这个教程一步步去学习webpack的使用过程;
- LOADERS:loaders,webpack的核心之一,常见的loader都可以在这里查询到用法,比如css-loader、babel-loader、less�loader等等;
- PLUGINS:plugins,webpack的核心之一,常见的plugin都可以在这里查询到用法,比如BannerPlugin、CleanWebpackPlugin、MiniCssExtractPlugin等等;
- MIGRATE:迁移,可以通过这里的教程将webpack4迁移到webpack5等;
前端开发的复杂化
前端开发目前我们面临哪些复杂的问题呢?
- 比如开发过程中我们需要通过
模块化的方式
来开发; - 比如也会使用一些高级的特性来加快我们的开发效率或者安全性,比如通过
ES6+
、TypeScript
开发脚本逻辑,通过sass
、less
等方式来编写css样式代码; - 比如开发过程中,我们还希望
实时的监听文件的变化来并且反映到浏览器上
,提高开发的效率; - 比如开发完成后我们还需要
将代码进行压缩、合并以及其他相关的优化
; - 等等….
前端三个框架的脚手架
目前前端流行的三大框架:Vue、React、Angular
- 但是事实上,这三大框架的创建过程我们都是借助于脚手架(CLI)的;
- 事实上
Vue-CLI
、create-react-app
、Angular-CLI
都是基于webpack
来帮助我们支持模块化
、es6
、TypeScript
、打包优化
等的;
Webpack是什么?
webpack is a static module bundler for modern JavaScript applications.
webpack是一个静态的模块化打包工具,为现代的JavaScript应用程序
我们来对上面的解释进行拆解:
- 打包bundler:webpack可以将帮助我们进行打包,所以它是一个打包工具
- 静态的static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器);
- 模块化module:webpack默认支持各种模块化开发,ES Module、CommonJS、AMD等;
-
现代的modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了webpack的出现和发展;
工作中的webpack
日常工作来说,比如在开发vue、react、angular等项目的过程中我们需要一些特殊的配置:比如给某些目录结构起别名
,让我们的项目支持sass、less等预处理器
,希望在项目中手动的添加TypeScript的支持
,都需要对webpack进行一些特殊的配置工作。
当然,除了日常工作之外,如果我们希望将在原有的脚手架上来定制一些自己的特殊配置提供性能:比如安装性能分析工具
、使用gzip压缩代码
、引用cdn的资源
,公共代码抽取
等等操作,甚至包括需要编写属于自己的loader和plugin
。
对于想要在前端领域进阶成为高级前端开发工程师,甚至是架构师的前端开发者来说,webpack等构建工具是必须学习的,包括其中的一些高级特性和原理,都是要熟练掌握的。企业在招聘高级前端工程师或者架构师时,必然会对webpack和其他的构建工具有比较高的要求。
vue-cli-service运行过程
Webpack的依赖
Webpack的运行是依赖Node环境
的,所以我们电脑上必须有Node环境
- 所以我们需要先安装Node.js,并且同时会安装npm;
- 我当前电脑上的node版本是v15.4.0,npm版本是7.0.15(你也可以使用nvm或者n来管理Node版本);
- Node官方网站:https://nodejs.org/
Webpack的安装
webpack的安装目前分为两个:webpack
、webpack-cli
那么它们是什么关系呢?
- 执行webpack命令,会执行node_modules下的.bin目录下的webpack;
- webpack在执行时是依赖webpack-cli的,如果没有安装就会报错;
- 而webpack-cli中代码执行时,才是真正利用webpack进行编译和打包的过程;
- 所以在安装webpack时,我们需要同时安装webpack-cli(第三方的脚手架事实上是没有使用webpack-cli的,而是类似于自己的vue-service-cli的东西)
npm install webpack webpack-cli –g # 全局安装
npm install webpack webpack-cli –D # 局部安装
传统开发存在的问题
我们的代码存在什么问题呢?某些语法浏览器是不认识的(尤其在低版本浏览器上)
- 1.使用了ES6的语法,比如const、箭头函数等语法;
- 2.使用了ES6中的模块化语法;
- 3.使用CommonJS的模块化语法;
- 4.在通过script标签引入时,必须添加上
type="module"
属性;
显然,上面存在的问题,让我们在发布静态资源时,是不能直接发布的,因为运行在用户浏览器必然会存在各种各样的兼容性问题。
- 我们需要通过某个工具对其进行打包,让其转换成浏览器可以直接识别的语法;
webpack默认打包
我们可以通过webpack
进行打包,之后运行打包之后
的代码
- 在目录下直接执行 webpack 命令
webpack
生成一个dist文件夹,里面存放一个main.js的文件,就是我们打包之后的文件:
- 这个文件中的代码被压缩和丑化了;
- 我们暂时不关心他是如何做到的,后续我讲webpack实现模块化原理时会再次讲到;
- 另外我们发现代码中依然存在ES6的语法,比如箭头函数、const等,这是因为默认情况下webpack并不清楚我们打包后的文件是否需要转成ES5之前的语法,后续我们需要通过babel来进行转换和设置;
我们发现是可以正常进行打包的,但是有一个问题,webpack是如何确定我们的入口的呢?
- 事实上,当我们运行webpack时,webpack会查找
当前目录下的 src/index.js作为入口
; - 所以,如果当前项目中没有存在src/index.js文件,那么会报错;
当然,我们也可以通过配置来指定入口和出口
npx webpack --entry ./src/main.js --output-path ./build
Webpack命令行选项
我们可以通过命令行选项
来指定入口文件路径和webpack生成文件的路径
npx webpack --entry ./src/main.js --output-path ./build
npx webpack 意思是输入./node_modules/.bin/webpack来运行webpack,即使用项目局部安装的webpack
--entry 指定应用程序的入口文件,例如 ./src/main.js
--output-path webpack 生成文件的输出位置,例如 ./dist
还有如下常用的命令行选项:
--config 提供 webpack 配置文件的路径,例如 ./webpack.config.js
--env 当它是一个函数时,传递给配置的环境变量
--watch 监听文件变化
--hot 启用 HMR
https://webpack.docschina.org/api/cli/#flags
Wepack的全局安装和局部安装
一般在我们的项目中都会选择局部安装webpack
,因为如果使用全局的,合作同一个项目的同事电脑上全局安装的webpack的版本可能存在差异,比如我安装的版本是5,同事安装的版本是4,还有可能是3的,这样使用全局webpack打包的时候就会出问题
如何在项目中局部安装webpack?
- 1.执行npm init 生成package.json文件
npm init
- 2.执行下面命令局部安装webpack,webpack-cli
npm install webpack webpack-cli -D
-
3.在package.json中配置脚本
- 4.执行
npm run build
进行打包,此时优先使用当前目录下的./node_modules/.bin/webpack
(即局部安装的webpack)进行打包,
只有在本项目局部没有安装webpack的情况下才会使用全局的webpack进行打包
Webpack配置文件
在通常情况下,webpack需要打包的项目是非常复杂的,并且我们需要一系列的配置来满足要求,默认配置必然是不可以的。
我们可以在根目录下创建一个webpack.config.js
文件,来作为webpack的配置文件:
webpack.config.js
const path = require('path')
//当使用webpack打包的时候,webpack会自动去项目根目录下寻找webpack.config.js这个配置文件,加载里面的配置,根据配置选项进行打包
module.exports = {
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist') //输出文件路径必须是一个绝对路径
}
}
继续执行webpack命令,依然可以正常打包
webpack
指定配置文件
但是如果我们的配置文件并不是webpack.config.js的名字,而是其他的名字呢?
- 比如我们将webpack.config.js修改成了 wk.config.js;
- 这个时候我们可以通过 --config 这个命令行选项 来指定对应的配置文件;
webpack --config wk.config.js
但是每次这样执行命令来对源码进行编译,会非常繁琐,所以我们可以在package.json中增加一个新的脚本:
之后我们执行 npm run build来打包即可
Webpack依赖图
webpack到底是如何对我们的项目进行打包的呢?
- 事实上webpack在处理应用程序时,它会根据命令或者配置文件找到入口文件;
- 从入口开始,会生成一个 依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(比如.js文件、css文件、图片、字体等);
- 然后遍历图结构,打包一个个模块(根据文件的不同使用不同的loader来解析);