头图:公主链接宫子可爱,想rua


起因是看Vue-cli关于项目构建目标的官方文档时看到了这么一段话

反复看了几遍始终找不到头猪,再查找了关于Js模块规范的相关资料后终于算是理解了不少orz。

Javascript中的模块规范

JS模块规范有好几种:AMDAMD yes!,UMD,CMD,CommonJS,ES6 Module

CommonJS

CommonJS被称为是“民间”的模块标准,nodejs的模块规范就是参照CommonJS实现的,在此之前JS没有模块这个概念,因此当要使用第三方的JS代码时,要把代码都拷贝进去导致最终的JS代码过于冗长。在CommonJS中模块可以被多次加载,但是只会在第一次加载时运行一次,之后将会把运行结果缓存,若之后再次加载,就直接读取缓存结果。

特点

模块的加载属于同步加载,即会阻塞代码的运行,因此会在一定程度上影响性能。

语法

  • 导入:require(./pathToModule)
  • 导出:module.exportsexports

AMD

AMD(Asynchronous Module Definition),顾名思义AMD采用了异步方式来导入模块,即模块的导入不会阻塞线程,使用AMD导入模块可以使网页还在加载的时候并行地加载JS脚本。一旦脚本加载完成将调用define通知RequireJS脚本已经加载并且执行,然后RequireJS将调用脚本的主函数并传入已初始化的模块。

语法

  • 导入:require(./path/to/modulefunction(moduleRefer){//use module}
  • 导出:define(function(){return //exports something..})

UMD

UMD(Universal Module Definition)同时兼容了AMD和CommonJS规范,不仅如此它还支持全局引用

ES6 Module

ESM(简称)是ES6的最新语法支持规范,其思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量,它会自动为代码开启严格模式,此外每个模块只加载一次,若再次加载则直接从内存中读取。其次需要注意的是,importexport指令只能在模块的顶层,不能在封闭的代码块中使用,import()语句则可以在代码块中实现异步动态按需加载

语法

  • 导入:import {..} from 'pathToModule'import('path/to/module').then()
  • 导出:exportexport default

在总结完几种JS模块规范后再回头看官方文档的描述,其中提到的默认导出内容其实指的就是使用export default导出模块的方法,其遵循ESM规范,而具名导出则是类似export const A = 42这样的导出方法。如果项目时遵循的是UMD规范或者CommonJS规范,需要使用通过export default方法导出的模块就不能只是简单地模块引用.*而是要模块引用.default.*。具体可以看下面的例子:

//array.mjs 导出模块
var arr = [1, 2, 3];
const reduceArr = function() {
    console.log(arr.reduce((x, y) => String(x) + String(y)));
};
export default {
    func: reduceArr,
}

//main.js 导入模块
async function _import() {
    const mymodule = await
    import ('./array.mjs');
    mymodule.default.func();// .default 来调用模块
}
_import();

其中main.js遵循CommonJS规范,不能通过require()来导入ES6模块的原因是require()采用的同步加载,而ES6模块内部可以使用顶层await命令,导致导入模块时会报错,无法同步加载模块。
至于官方文档出现的const myLib = require('mylib').default,我认为应该是Vue项目在打包的时候对代码做了处理,使得CommonJS能够通过require()的方式导入ES6模块。

参考文章

https://www.ruanyifeng.com/blog/2020/08/how-nodejs-use-es6-module.html
https://juejin.cn/post/6844903469933920263
https://segmentfault.com/a/1190000012419990
https://stackoverflow.com/questions/47344897/what-does-synchronous-vs-asynchronous-loading-mean
https://www.runoob.com/w3cnote/es6-module.html

最后修改:2021 年 12 月 09 日 03 : 34 PM
如果觉得我的文章对你有用,请随意赞赏