问题情境
我们想实现一个两数求和的功能,现将该功能在add.js中实现并导出,在index.js中引用,最后在主页中加载index.js,并输出。
功能实现
需求实现
- 创建add.js实现两数求和:
- 创建入口执行文件index.js,引入add.js模块:
- 在主页index.html中引入入口js并显示输出结果:
结果展示
报错,因为在浏览器中并没有require这个函数,所以浏览器无法解析js中的require函数
解决问题
webpack的bundle.js就是将需要引用的文件内容整合在一起
- 将add.js和index.js的内容拿到index.html中运行
这时浏览器通知我们exports找不到了,因为浏览器同样没有exports这个对象。
- 提供exports
这样虽然解决了erports未定义的问题,但实际上,如果我们在add.js中定义了一些变量,如var a = 123;那么将来我们在引入add.js时,a这个变量也会出现在exports中,这样会导致模块内的环境污染全局或者模块间互相干扰,显然这不是我们想要的,这时我们就需要用到即时函数对模块进行封装,保证模块内的环境相互独立。
- 提供require
这么写只是把文件路径写死,那么require方法是要将某路径下的文件内容导出,如何动态解析不同的文件内容呢,为了解决不同文件对应不同内容,我们需要定义一个结构体。
同样的,为了模块化,环境互相独立原则,我们将require用即时函数包裹起来:
这样整个程序的执行流程就是,自运行执行最外层即时函数,调用了require("index.js");,进入require中执行index.js的内容,发现里面再次引用了require("add.js"),于是递归调用,执行add.js内容后返回exports,此时递归返回的exports被require("index.js")中的add接收,通过console.log(add(2,4))输出结果为6。