谢谢你们看我扯手艺,近来在对webpack2
举行的设置举行梳理和进修,webpack
是在客岁运用vue
最先打仗的,个人感觉webpack
融入到编程过程当中,供应了模块化,将种种类型的文件都算作模块,经由过程差别的 loader
举行处置惩罚和代码构造,是一个比较新鲜的编程体验,应该说webpack
的编程实用场景比较普遍,能够比较轻易的引入第三方的种种 npm 模块举行运用, 轻易疾速开辟事情。
盘算写几篇文章(假如能对峙的话= =)来总结下 webpack
,文章不是教你怎样运用webpack
,而是让你更好的相识你在运用的webpack
是怎样去运转的 ,想来想去,第一篇就先引见下webpack
天生的文件,是怎样去实行的。
webpack 的天生信息
起首我们要先经由过程 webpack 去天生文件(好一句空话),文章一切的代码都会在文章最背面给出链接,下面是本文章运用的代码的目次:
我们如今只需关注js
目次,内里有两个进口 app.js
、bar.js
,然后会援用 es5,es6中的种种测试模块,详细人人能够看代码。然后代码一跑!只见命令行蹭蹭蹭跑出来了很多信息,像下面一样:
起首我们来看下天生的信息:
Asset
: 这个一看就邃晓是天生的文件相对于设置中output.path
的途径,能够看到图中天生的文件都是在output.path
底下的;然后我们细致看下文件名,比方第一个0.fb6d7f4.js
,是由[name/chunkname].[hash/chunkhash].js
构成的,这个能够在output.filename
中设置,关于hash
和chunkhash
的区分,这个背面会特地经由过程一篇文章举行简介。Size
: 这个就没啥好说的,就是天生文件的大小Chunks
: 我们会看到有些Chunks
是两个数字,有些是一个,实在还能够涌现更多,经由我的一堆试验= =,发明Chunks
中的第一个数字,就是这个文件的ChunkId
,然背面的是当前这个文件依靠的文件的ChunkId
,从图中我们能够看到,第一个文件的ChunkId
是0
,它依靠的是ChunkId
为3
的manifest.a890c12.js
Chunk Names
: 这个就是这个天生文件的chunkName
,能够用于文件定名,能够看到假如没有在entry
中指定,那末chunkName
会即是chunkId
递次加载流程
相识了天生的信息,接下来我们把项目跑起来(能够用 anywhere
跑项目),经由过程chrome developer tool
能够看到要求状况
能够看到要求了页面html以后,按递次离别加载了 manifest
,index
,0
,2
文件,这里我们先来剖析下文件的支解和加载流程。
支解
能够看到页面的 js 被支解成为了4个文件,一般来讲,一个项目定义了一个 entry point
,webpack
会以这个entry point
作为进口,举行代码回溯,假如存在System.import
或者是require.ensure
的异步模块挪用,webpack
会对运用的模块举行零丁打包,比方文件中的0
、2
这两个 js,假如没有异步模块挪用,那末会将一切的代码天生在一个文件中,webpack
为了使得打包的代码举行优化,能够运用CommonsChunkPlugin
插件对代码举行处置惩罚,将库文件零丁打包,经由过程划定规矩天生对应的 chunk
文件,个中的manifest
为 默许的 chunk
,个中包括了打包文件的runtime
信息,另有webpackJsonp
模块加载的封装库,一切的天生模块都是采纳webpackJsonp
举行封装的。
manifest
从上面的图中能够看到,浏览器按递次离别加载了 manifest
,index
,0
,2
文件,个中manifest
相当于webpack
的runtime
东西,用于做模块加载,其他文件是逻辑文件; manifest
中封装了webpackJsonpCallback
要领和__webpack_require__
要领,下面我们来举行剖析:
webpackJsonpCallback(chunkIds, moreModules, executeModule)
:webpackJsonpCallback
是chunk封装的包装要领,webpack
在天生每个chunk
的时刻都是经由过程这个要领举行包装的,我们在上面看到的chunksId
,会作为第一个参数,被包括进这个chunk
的module
会被以数组的情势传入第二个参数moreModules
中,假如这个chunk
中包括能够实行的modules
,须要将moduleId
传入第三个参数executeModule
中,下面是 这个要领的代码片断:
这个要领主要做了下面几件事:加载chunk
我们能够看到这个要领用第一个轮回离别将
chunkIds
处置惩罚进入installedChunks
对象中,installedChunks
对象用于纪录chunk
的加载状况,离别用0
示意当前的chunkId
已加载完成,用一个长度为3的数组示意当前的chunk
正在加载中,数据中实在存储着加载过程当中的resolve
要领、reject
要领和pormise
对象,这类只在经由过程require.ensure
或者是System.import
才会涌现。因而我们能够看到,第一个for
轮回中推断假如chunkId
在 installedChunks 中存在且不为0,则推断是异步加载的模块已加载胜利,将chunk
的resolve
要领传入resolves
数组,然后背面运转,然后将chunk
对应的状况设置为0
。假如推断以后不存在,这以为这是一个同步加载的chunk
,直接设置为0
,示意chunk
已加载终了。加载 module
加载
module
的逻辑比较简单,推断纯不存在这个module
以后,将 其写入modules
参数当中运转须要实行的
module
假如
executeModule
存在,则对个中对应moduleId
的模块举行运转
__webpack_require__
: 这个对象包括了多个要领,主要用于module
和chunk
的加载,处置惩罚和运转,下面我们一个一个剖析:__webpack_require__(moduleId)
:代码以下
这个要领吸收一个moduleId
,构建一个 module 对象存入installedModules
中,而且初始化这个module
, 末了返回module.export
__webpack_require__.e(chunkId)
: 这个要领用于经由过程异步的体式格局加载 chunk 文件,代码以下:
这个要领整体来讲就是加载一个script
文件,天生一个promise
对象,当 script 加载完成后运转,又会实行前面的webpackJsonpCallback
注册chunk
,然后promise.resolve
。这内里须要注重的是红框内里的东西,这个涉及到一个优化点,假如没有在运用CommonsChunkPlugin
零丁打包manifest
,那末一般来讲他会和你指定的其他库经由过程CommonsChunkPlugin
打包在一起,那末你会发明纵然你只是修改了库以外的逻辑,库文件天生的文件的hash
或者是chunkhash
也是会变的,缘由就在于manifest
中红框部份是动态天生的,致使文件的 hash 发生变化,不利于缓存,因而发起零丁打包manifest
__webpack_require__.oe
:定义一个一致的错误处置惩罚函数__webpack_require__.p
:这个是和webpack
的output.publicPath
对应的值__webpack_require__.o
:Object.prototype.hasOwnProperty
的封装
前面几个要领在ES5
的情形下面已充足运转这个模块体系,我们都晓得webpack2
加入了对ES6 MODULE
的支撑,下面几个__webpack_require__
是为ES6
运用的:__webpack_require__.d
:代码以下:
这个是用于ES6
中定名的export
比方 webpack 碰到这类export
,会对其用__webpack_require__.d
举行包装,变成:__webpack_require__.i
:用于返回一个准确的上下文的函数归去,针对的是export
直接为一个可运转要领的时刻
以上就是webpack manifest
中的大部份主要的函数,实在主要就是经由过程webpackJsonpCallback
来注册载入对应的chunk
文件,经由过程__webpack_require__
来处置惩罚模块的关联。
总结
全部webpack
的在运转时都是经由过程 manifest
去做掌握处置惩罚的, webpackJsonpCallback
对应的是对加载的chunk
文件的处置惩罚,__webpack_require__
是对加载模块的处置惩罚,相识这些能够使我们更好的去优化我们的代码,协助我们去调试代码,协助我们在复杂状况下去解决问题供应一些其他的思绪。
末了附上代码:先引见下,webpack-base
是我在运用webpack
的过程当中本身总结的一套脚手架,文档还没有完美,假如须要文档能够在issue
内里提,本次的项目在分支上面开辟,代码点击这里