前端模块化规范 ---- CommonJS和ESModule

前言

大家好,我是Lesedi,是一名自学前端的小菜鸟, 一名准大三的学生,暑期找了个实习,工作量不多,就想着扩充一下知识边界,为了激励自己,所以决定以发博客的形式来检验自己的掌握的情况。由于才疏学浅,难免会有遗漏或是错误的地方,欢迎各位大佬批评指正,如果我的文章能帮助到您,不甚荣幸!

概述

​ 在早期的JavaScript中是没有模块化的概念的,引用第三方包时都是把变量直接绑定在全局环境下---全局引入

这种全局引入的方式,会带来两个大的问题

  • 变量污染:所有脚本都在全局上下文中绑定变量,如果出现重名,后面的变量就会覆盖掉前面的变量,造成变量污染
  • 依赖混乱:当多个脚本有相互依赖的时候,它们彼此间的关系就不明确,很容易混淆

    在这种背景下,就急需“模块化”的开发来对代码进行规范,所以涌现出多种JavaScript模块化规范 ---> 到如今我们用的最多的、需要重点了解的有两种 ---> CommonJSES Moudle

模块化给我们带来的好处

  • 避免了变量污染:因为每个模块是独立的,所以变量或函数名重名不会造成影响
  • 提高了可维护性:因为每个模块是独立的,各司其职,在后续迭代或者维护的时候,只用在需要的模块进行修改即可
  • 性能优化:异步加载模块的页面性能非常好

CommonJS

​ CommonJS的发明者希望它能让客户端和服务端使用同一套规范。但CommonJS主要还是应用于服务端,它最开始是叫ServerJS,被应用于Node服务端

该规范最核心的理念就是:把每一个文件都看成一个模块

CommonJS的特点

  • 每个文件都是独立的模块,有独立的作用域
  • 文件可以被重复引用、加载,第一次加载时会被缓存,之后再引用就直接读取缓存
  • 加载某个模块时,module.exports 输出的是值的拷贝,一旦这个值被输出,模块内再发生变化不会影响已经输出的值

CommonJS里面的三个核心变量

  • exports:记录当前模块导出的变量
  • module:记录当前模块的详细信息
  • require:对外部的模块进行导入

示例:

//a.js
function test() {
    console.log('一个模块化实例');
}

function sayHi() {
    console.log('你好哇');
}

//不导出的话,默认外部是无法访问到的

//导出该方法,使其向外界暴露
// module.exports = test
//当要同时导出多个方法时,这样写
module.exports = {
    //ES6的字面量加强写法
    // test: test,
    test,
    sayHi
}
//index.js
//require是引入外部文件的关键字,接收的参数是外部文件的路径
let moduleA = require('./a')  
//这里test()方法被赋值给了moduleA,所以调用时也要使用moduleA。当然这里的名字是自定义的,前后对应即可

console.log(moduleA.test, moduleA.sayHi);   //[Function: test] [Function: sayHi]
//调用该方法
moduleA.test() //一个模块化实例
moduleA.sayHi() //你好哇

ES6Module

ES6Module的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
NodeJS可以通过mjs后缀或者在package.json添加"type": "module"来使用,通常选择后者,一劳永逸!

"type": "module"
//这个字段有两个取值 ---> commonjs、module,默认是common,所以如果不进行设置,node默认是遵循commonJS规范的

用法示例:

//ModuleA.js
const ModuleA = {
    printInfo() {
        console.log('这是ESModule!');
    }
}
//这种方法只能导出一个
export default ModuleA
//ModuleB.js
const ModuleB = {
    whoIam() {
        return "I am Lesedi"
    }
}

//这种导出方法可以导出多个
export {
    ModuleB
    //...
}
//index.js
import ModuleA from "./Module.js/ModulaA.js";
//用export导出,就要用解构的方法导入 ---> {}包裹住
import {ModuleB} from "./Module.js/ModuleB.js"


ModuleA.printInfo() //这是ESModule!

console.log(ModuleB.whoIam()); //I am Lesedi

总结与展望

这算是我第一篇正式的博客文章,心情是比较忐忑的,如果有写的不到位的地方,还希望各位能够帮忙指出,感谢!
最后,希望自己能够坚持下去,能够定期的产出一些文章

宣传一波

这是我的个人网站,里面有我做的一些笔记,网站,目前还比较简陋,各位如果有心情的话,可以去逛逛,网址☞ www.lesedi.xyz

你可能感兴趣的:(前端javascript)