打包
首先来看看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
处理。