开篇词:webpack现代化前端应用的基石
“webpack应该是现代化前端开发的基石,也是目前前端生产力的代名词”。
框架给出的CLI只是个黑盒工具。
模块化仅是一个思想,或者说一个理论。
Loader机制和插件机制是webpack架构中的两个核心特性。
01讲:webpack究竟解决了什么问题
最初的目标是实现前端项目的模块化,即如何在前端项目中更高效地管理和维护项目中的每一个资源。
模块化的演进过程
文件划分方式,一个个JS文件,完全依赖约定实现,很原始
缺点:
- 模块直接在全局工作,大量模块成员污染全局作用域;
- 没有私有空间,所有模块内的成员都可以在模块外部被访问或者修改;
- 一旦模块增多,容易产生命名冲突;
- 无法管理模块与模块之间的依赖关系;
- 在维护的过程中也很难分辨每个成员所属的模块。
命名空间方式
- 约定每个模块值暴露一个全局对象,然后将其挂载在
window
上。 - 但模块成员的内容依然可以被修改
- 约定每个模块值暴露一个全局对象,然后将其挂载在
IIFE(立即执行函数)
- 将每个模块成员都放在一个立即执行函数所形成的私有作用域中
- 对于需要暴露的成员,则放在
window上
暴露 - 这就保证了私有成员只能通过闭包的形式访问
IIFE 依赖参数
- 通过参数表明这个模块的依赖
这以上说得都是代码中模块代码的组织问题,但没有解决模块代码的加载问题。
所以需求就是:
- 一个统一的模块化标准规范
- 一个可以自动加载模块的基础库
CommonJS(Node.js中,同步机制) => AMD(异步的,require.js, define) => CMD(sea.js) 所以要用到AMD规范,还得引入require.js这个库。
标准规范:
- 在Node.js环境汇总,遵循CommonJS规范来组织模块
- 在浏览器环境中,遵循ES Modules规范
ES Modules是要重点学习的规范。
Webpack 以模块化思想为核心,帮助开发者更好的管理整个前端工程。
02讲:如何使用webpack实现模块化打包
对于模块化打包方案或工具的设想或者说是诉求
- 能够将散落的模块打包在一起
- 能够编译代码中的新特性
- 能够支持不同种类的前端资源模块
webpack是webpack的核心模块,webpack-cli是webpack的CLI程序,用来在命令行调用webpack。
Webpack 4 以后的版本支持零配置的方式直接启动打包,整个过程会按照约定将 src/index.js 作为打包入口,最终打包的结果会存放到 dist/main.js 中。
webpack.config.js 是一个运行在 Node.js 环境中的 JS 文件,也就是说我们需要按照 CommonJS 的方式编写代码,这个文件可以导出一个对象,我们可以通过所导出对象的属性完成相应的配置选项。
三种工作模式
- production模式,启动内置优化插件,自动优化打包结果,打包速度慢
- development模式,自动优化打包速度,添加一些调试过程中的辅助插件
- none模式下,运行最原始的打包,不做任何额外的处理
03讲:如何通过Loader实现特殊资源加载
webpack想要实现的是整个前端项目的模块化,项目中的各种资源(包括CSS文件、图片等)都应该属于需要被管理的模块。
webpack 不仅仅是JavaScript模块的打包工具,还是整个前端工程的模块的打包工具。
Webpack 并没有强制要求我们必须以 JS 文件作为打包入口,只是在绝大多数情况下,我们会用 JS 文件作为打包入口,因为 JS 文件才是程序的逻辑入口,以 JS 文件作为入口相对更合理。
css-loader 只会把 CSS 模块加载到 JS 代码中,而并不会使用这个模块。
其实 Webpack 加载资源文件的过程类似于一个工作管道,你可以在这个过程中依次使用多个 Loader,但是最终这个管道结束过后的结果必须是一段标准的 JS 代码字符串。
style-loader 的作用总结一句话就是,将 css-loader 中所加载到的所有样式模块,通过创建 style 标签的方式添加到页面上。
Loader 是 Webpack 实现整个前端模块化的核心。因为只有通过不同的 Loader,Webpack 才可以实现任何类型资源的加载。
这里的 use 中不仅可以使用模块名称,还可以使用模块文件路径,这点与 Node 中的 require 函数是一样的。
04讲:如何利用插件机制横向拓展webpack的构建能力
webpack的插件机制的目的是为了增强webpack在项目自动化构建方面的能力。解决的是项目中出了资源模块打包以外的其他工作。
插件常见的应用场景
- 实现自动在打包之前清除dist目录
- 自动生成应用所需要的HTML文件
- 根据不同环境为代码注入类似API地址这种可变化的部分
- 拷贝不需要参与打包的资源文件到输出目录
- 压缩webpack打包完成后输出的文件
- 自动发布打包结果到服务器实现自动部署
clean-webpack-plugin,用于自动清理dist目录
html-webpack-plugin,用于自动将打包文件注入HTML页面
copy-webpack-plugin,用于自动将目标目录的文件复制到dist目录
webpack的插件机制就是我们在软件开发中最常见的钩子机制
- compiler hooks
- compilation hooks
- javascriptParser hooks
webpack 要求我们的插件必须是一个函数或者是一个包含apply方法的对象。
Webpack 为每一个工作环节都预留了合适的钩子,我们在扩展时只需要找到合适的时机去做合适的事情就可以了。
这种钩子机制又叫作面向切面编程(AOP),是软件工程中实现插件机制最常见的方式,如果你在以后的开发工作中有类似的需求,那钩子机制一定是最好的选择。而且对于使用 JavaScript 的开发者而言,实现面向切面编程其实也很容易,很多时候我们都会采用事件机制去实现这种编程模式。
05讲,探索webpack的运行机制与核心工作原理
- webpack就是借助文件后缀名才配对相应的loader吗