详解webpack 最简打包结果分析
现在的webpack不再是入门噩梦,过去webpack最让人心塞的莫过于配置文件,而webpack4诞生随之而来的是无配置webpack。
使用webpack4,至少只需要安装webpack和webpackcli。所以大家完全可以自己打一个最简单的包,还能修改插件对比前后的区别。
npmiwebpackwebpack-cli-D安装后,因为webpack4会默认src为入口目录,所以先新建src/index.js。
//src/index.js
import{sth}from'./shouldImport'
importotherfrom'./shouldImport'
lettest='thisisavariable'
exportdefault{
a:test+','+sth,
other,
}
为了更了解webpack 导入机制所以再新建src/shouldImport.js。
//src/shouldImport.js
exportletsth='somethingyouneed'
exportdefault{
others:'',
}
然后运行node_modules/.bin/webpack--modedevelopment即可在dist/main.js看到打包后的文件。
但是默认设置中模块文件会被eval包裹导致不便查看,所以需要再在设置做一点修改,把devtool属性改为'source-map':
//在根目录新建webpack.config.js文件
module.exports=mode=>{
if(mode==='production'){
return{}
}
return{
devtool:'source-map',
}
}
然后再打包应该就能看到类似一下的文件结构,开发环境下打包得到的文件自带注释,理解起来不难:
;(function(modules){
//webpackBootstrap
//Themodulecache模块缓存
varinstalledModules={}
//Therequirefunction请求函数
function__webpack_require__(moduleId){
//Checkifmoduleisincache
//检查模块是否在缓存
if(installedModules[moduleId]){
returninstalledModules[moduleId].exports
}
//Createanewmodule(andputitintothecache)
//创建新模块并放进缓存
varmodule=(installedModules[moduleId]={
i:moduleId,
l:false,
exports:{},
})
//Executethemodulefunction
//执行模块函数(有点不懂为什么this要传入module.exports)
modules[moduleId].call(
module.exports,//this
module,//模块对象本身
module.exports,//模块对象的exports属性
__webpack_require__//请求函数最终返回模块输出,传入用于请求其他模块
)
//Flagthemoduleasloaded
//加载完成标志
module.l=true
//Returntheexportsofthemodule
//返回模块的输出
returnmodule.exports
}
//exposethemodulesobject(__webpack_modules__)
//暴露所有模块对象
__webpack_require__.m=modules
//exposethemodulecache
//暴露模块缓存
__webpack_require__.c=installedModules
//Object.prototype.hasOwnProperty.call
__webpack_require__.o=function(object,property){
returnObject.prototype.hasOwnProperty.call(object,property)
}
//definegetterfunctionforharmonyexports
//为ES6export定义getter函数
__webpack_require__.d=function(exports,name,getter){
if(!__webpack_require__.o(exports,name)){
//检查属性是否存在
Object.defineProperty(exports,name,{enumerable:true,get:getter})
}
}
//define__esModuleonexports
//于export定义__esModule
__webpack_require__.r=function(exports){
if(typeofSymbol!=='undefined'&&Symbol.toStringTag){
Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'})
}
Object.defineProperty(exports,'__esModule',{value:true})
}
//createafakenamespaceobject
//创建代用命名空间对象
//mode&1:valueisamoduleid,requireit
//value是模块id,必要
//mode&2:mergeallpropertiesofvalueintothens
//合并value所有属性到ns
//mode&4:returnvaluewhenalreadynsobject
//ns已经是对象时返回value
//mode&8|1:behavelikerequire
//表现如require
__webpack_require__.t=function(value,mode){
if(mode&1)value=__webpack_require__(value)
if(mode&8)returnvalue
if(mode&4&&typeofvalue==='object'&&value&&value.__esModule)
returnvalue
varns=Object.create(null)
__webpack_require__.r(ns)
Object.defineProperty(ns,'default',{enumerable:true,value:value})
if(mode&2&&typeofvalue!='string')
for(varkeyinvalue)
__webpack_require__.d(
ns,
key,
function(key){
returnvalue[key]
}.bind(null,key)
)
returnns
}
//getDefaultExportfunctionforcompatibilitywithnon-harmonymodules
//用于兼容非ES6模块的getDefaultExport函数
__webpack_require__.n=function(module){
vargetter=
module&&module.__esModule
?functiongetDefault(){
returnmodule['default']
}
:functiongetModuleExports(){
returnmodule
}
__webpack_require__.d(getter,'a',getter)
returngetter
}
//__webpack_public_path__
__webpack_require__.p=''
//Loadentrymoduleandreturnexports
//加载入口模块并返回export
return__webpack_require__((__webpack_require__.s='./src/index.js'))
})({
'./src/index.js':
/*!exportsprovided:default*/
function(module,__webpack_exports__,__webpack_require__){
'usestrict'
__webpack_require__.r(__webpack_exports__)//于export定义__esModule
/*harmonyimport*/
var_shouldImport__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(
'./src/shouldImport.js'
)
lettest='thisisavariable'
/*harmonydefaultexport*/
__webpack_exports__['default']={
a:test+','+_shouldImport__WEBPACK_IMPORTED_MODULE_0__['sth'],
other:_shouldImport__WEBPACK_IMPORTED_MODULE_0__['default'],
}
},
'./src/shouldImport.js':
/*!exportsprovided:sth,default*/
function(module,__webpack_exports__,__webpack_require__){
'usestrict'
__webpack_require__.r(__webpack_exports__)
/*harmonyexport(binding)*/
__webpack_require__.d(__webpack_exports__,'sth',function(){
returnsth
})
letsth='somethingyouneed'
__webpack_exports__['default']={
others:'',
}
},
})
源文件中的所有import和export都会转换为对应的辅助函数。
- import对应__webpack_require__
- export对应__webpack_exports__['default']直接赋值和__webpack_require__.d。
整理一下整个流程:
- 定义__webpack_require__及其辅助函数
- 使用__webpack_require__引入入口模块
- __webpack_require__函数载入模块,将模块放到模块缓存
- 调用模块
- 同样使用__webpack_require__读取依赖(回到第3步)
- 运行模块内部功能
- 使用__webpack_exports__['default']直接赋值和__webpack_require__.d输出
- 运行结束
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。