Commonjs规范
学习过webpack的小伙伴想必都知道什么是commonjs规范了吧,就是我们写webpack.config.js时,导入导出的方式。
- 有没有人和我一个想法想知道它的实现原理呢?
- 因为我们知道commonjs的导入和导出是需要借助webpack编译才能正常使用
- 那我们来研究研究它们是如何实现这个编译过程的吧
- 首先模块化的本质就是隔离控件,证明他们是有作用域隔绝的
- 那么我们就先来一个立即执行函数
我们先来看看commonjs的代码是什么样的吧
- 我们随便创建个js文件然后在里面随便写点东西
const dateFormate=(date)=>{
return '1232-23-23'
}
module.exports={
dateFormate
}
我们这样就导出了一个dateFormate函数
接下来我们再创建一个文件夹引入该函数
const {dateFormate} = require('./js/formate')
console.log(dateFormate('abc'));
这样就再一个文件中引入了我们刚刚导出的函数了
- 接下来让我们分析一下他们的结构
- 有两个文件,我们可以看作两个对象或者函数
- 还有他们的存在打包之后是不会影响其他的函数的,再引入文件内随便修改都是为所谓的
- 那么我们就应该有一个独立的作用域,避免影响其他的文件了
(function(){
//pass
}())
这样我们就得到了一个独立的作用了,不会被外界所影响
- 接下来是什么呢?
- 我们看看这个导出函数的文件,首先它是一个js文件,那么我们就可以把他抽象为一个对象
- 以导入的时候的路径作为他的key
(function(){
var __webpack_module__ = {
'./js/formate':function(module){
const dateFormate=(date)=>{
return '1232-23-23'
}
module.exports={
dateFormate
}
}
}
}())
代码中的module我待会会告诉大家从何而来,
- 这个代码就是commonjs 导出的原理了
- 我们在js中写的代码最后会被webpack编译成这样子
- 我们可以看到 我们导出的时候写的path被当成了以key值,被导出的函数被编译成了对应的value值 -接下来我们看看他是如何实现导入的
(function(){
//定义一个对象
//模块的路径(key):函数(value)
var __webpack_module__ = {
'./js/formate':function(module){
const dateFormate=(date)=>{
return '1232-23-23'
}
module.exports={
dateFormate
}
}
}
//定义一个对象,作为加载模块的缓存
var __webpack_module_cache__={}
//这个我们可以当成我们的 导入的require函数,而这个moduleId就是路径
var __webpack__require__ = function(moduleId){
//1.我们先判断一下 __webpack_module_cache__ 里面有没有保存之前的值
//有的话我们就直接返回出去就可以了
if(__webpack_module_cache__[moduleId]!=undefined){
return __webpack_module_cache__[moduleId].exports
}
//2.给module和__webpack_module_cache__[moduleId]变量赋值同一个对象
var module = __webpack_module_cache__ = {exports:{}}
//3.加载执行模块
__webpack_module__[moduleId](module,module.exports,__webpack_module_cache__)
//4.导出module.exports {dateFormate:function}
return module.exports
}
}())
- 以上我们已经完了大部分了
- 接下来就是如何导出这一块东西了
(function(){
//定义一个对象
//模块的路径(key):函数(value)
var __webpack_module__ = {
'./js/formate':function(module){
const dateFormate=(date)=>{
return '1232-23-23'
}
module.exports={
dateFormate
}
}
}
//定义一个对象,作为加载模块的缓存
var __webpack_module_cache__={}
//这个我们可以当成我们的 导入的require函数,而这个moduleId就是路径
var __webpack__require__ = function(moduleId){
//1.我们先判断一下 __webpack_module_cache__ 里面有没有保存之前的值
//有的话我们就直接返回出去就可以了
if(__webpack_module_cache__[moduleId]!=undefined){
return __webpack_module_cache__[moduleId].exports
}
//2.给module和__webpack_module_cache__[moduleId]变量赋值同一个对象
var module = __webpack_module_cache__ = {exports:{}}
//3.加载执行模块
__webpack_module__[moduleId](module,module.exports,__webpack_module_cache__)
//4.导出module.exports {dateFormate:function}
return module.exports
}
//具体开始执行代码逻辑
(function(){
const {dateFormate} = __webpack__require__('./js/formate')
console.log(dateFormate('asdasd'))
})()
}())
以上就是commonjs的导入导出原理了
- 如果有多个文件,那么只要多个块级作用域就可以避免互相影响了
结尾
- 到这里我们就结束啦,希望大家都可以好好学习
- 接下来我们会给大家带来webpack-loader的篇章,敬请期待!