前两篇文章中,有小伙伴给我留言说怎么没有模块化相关的知识点,模块化在面试中被问到的概率非常大,但因为前几篇文章篇幅实在太长了些,所以模块化知识点单独这篇文章给大家聊聊。
先说说什么是模块化,就是将独立的功能代码封装成一个独立的文件,其他模块需要使用,在进行引用。
模块化有利于代码的拆分和架构上的解耦,模块化在服务端领域已经早已成熟,nodejs 也已经支持模块化。
而在浏览器上,js 脚本是异步载入的,脚本按照编码顺序依次执行,依赖关系只能按照编码顺序来控制。因此前端早早就有了模块化技术,可每天醒来前端就多一个名词多一个框架的,发展实在迅猛,就前端模块化这些年的积累就有好几种,我们依次来看看。
commonjs
先看伴随 nodejs
而诞生的 commonjs
规范。commonjs 规范应用于 nodejs 应用中,在 nodejs 应用中每个文件就是一个模块,拥有自己的作用域,文件中的变量、函数都是私有的,与其他文件相隔离。
CommonJS规范规定,每个模块内部, module
变量代表当前模块。这个变量是一个对象,它的 exports
属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。(引用阮一峰老师的描述)
举个栗子看看模块化后的文件该怎么写
// util\index.jslet name = 'now';let age = 18;let fun = () => {
console.log('into fun'); name = 'change'}module.exports = {
name, fun}console.log(module)// appJsBridge\index.jsvar { name, fun } = require('./util/index.js')
上面这个文件有两个变量,一个函数,通过 module.exports 暴露变量 name 和函数 fun ,age 这个变量就是私有的,外部无法直接访问,如果想让 age 变量全局都可以访问,那么可以改成 global.age = 18
,但这样子会污染全局作用域,会导致意想不到的惊喜(吓)。
我们看看 util\index.js 打印出来的 module
module 中有这些属性
module.id 模块的识别符,通常是带有绝对路径的模块文件名。module.filename 模块的文件名,带有绝对路径。module.loaded 返回一个布尔值,表示模块是否已经完成加载。module.parent 返回一个module对象,表示调用该模块的模块,如果改该模块没有被引用,那么 parent 就是 null module.children 返回一个module数组,表示该模块要用到的其他模块。module.exports 表示模块对外输出的值。module.paths 这个用于 require 查找该文件的位置。
在开发中我们常使用的就是 module.exports , 通过 module.exports 输出的对象就是引用方 require 出来的值