打包
首先来看看webpack打包生成了什么。平常我们写代码,build之后会发现产生了一坨混合了webpack 相关代码的文件,其实这些wepack函数实现了模块的引入。比如下面的index.js
1 | import { plus } from './plus'; |
plus.js:
1 | export const plus = (a, b) => a + b |
通过webpack build 之后,主要生成了:
1 | (function(modules) { // webpackBootstrap |
这么一坨看上去复杂,其实就是一个即时函数而已:
1 | function webpackBootstrap(modules){...} |
modules是以模块路径为key,以一个函数为value的对象。当这个模块被引用时,相当于就是调用了 __webpack_require__(key),那么__webpack_require__是什么呢:
1 | function __webpack_require__(moduleId){ |
回到最开始,index.js中的import会被转为:
1 | import { plus } from './plus'; |
而在./src/plus.js中,webpack在module.export对象上加了个属性:
1 | { |
__webpack_require__.d即Object.defineProperty的意义:
1 | __webpack_require__.d = function(exports, name, getter) { |
建立引用关系
大概看懂了打包生成文件的结构,那么接下来看看webpack是怎么生成这些东西的呢?让我们跟随下面这一个webpack简易版的代码来进行理解:
1 | // 在这个例子中,我们将创建一个 依赖关系图 并将其用于打包 |
其中createAsset函数通过Ast来分析import,然后添加到该module的dependencies;通过entry入口,来循环入队,分析子module依赖,建立引用关系。
上面的代码里只是最简单的JS文件打包,那么别的文件类型如何处理呢?这就需要Loader了,对JS文件进行createAsset,而对其他文件先用相应Loader进行处理成js模块,再进行引入。
引用:
PS:
同一种文件也能用不同的loader,比如file-loader 和 url-loader:
file-loader可以指定要复制和放置资源文件的位置,以及如何使用版本哈希命名以获得更好的缓存。此外,这意味着 你可以就近管理图片文件,可以使用相对路径而不用担心部署时 URL 的问题。使用正确的配置,webpack将会在打包输出中自动重写文件路径为正确的 URL。url-loader允许你有条件地将文件转换为内联的 base-64 URL (当文件小于给定的阈值),这会减少小文件的 HTTP 请求数。如果文件大于该阈值,会自动的交给file-loader处理。