CommonJS
概述
CommonJS 是一个为了解决 Web 浏览器之外环境(如 Node.js)中模块生态系统而创建的项目。该项目由 Mozilla 工程师 Kevin Dangoor 于 2009 年 1 月开始,最初命名为 ServerJS。
What I’m describing here is not a technical problem. It’s a matter of people getting together and making a decision to step forward and start building up something bigger and cooler together. —Kevin Dangoor
2009 年 8 月,该项目更名为 CommonJS
,以显示 API 的更广泛适用性。CommonJS
与 Ecma International 小组 TC39 没有关联,致力于 ECMAScript
,但 TC39 的一些成员参与了该项目。
2013 年 5 月,Node.js
的软件包管理器 npm 的作者 Isaac Z. Schlueter 表示,CommonJS
正在被 Node.js 淘汰,并被核心 Node.js 开发人员所避免。
虽然如此,但是依旧有很多项目是遵循 CommonJS
规范,所以我们依然需要去了解它。
CommonJS 介绍
在 CommonJS
规范中,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。模块必须通过 module.exports
导出对外的变量或接口,通过require()
来导入其他模块的输出到当前模块作用域中。
模块导出
// num.js
var num = 5;
var addNum = function(value) {
return value + num;
};
// 通过 module.exports 的语法导出 addNum 函数
module.exports.addNum = addNum;
模块导入
// index.js
// 通过 require 的语法来导入 num 模块
var num = require("./num.js");
console.log(num.addNum(1)); // 6
路径映射
答案
解析
ts 提供了两种模块解析策略
- Node
- Classic
ts 提供了两种模块导入方式
- 相对模块导入
- 非相对模块导入
相对模块导入方式如:
- import { animal } from ‘./animal’
非相对模块导入方式如:
- import { animal } from ‘animal’
// 文件路径 /root/page/index.ts import { animal } from “animal”;
对于题目中的代码块,解析策略为:
- /root/page/node_modules/animal.js
- /root/page/node_modules/animal/package.json(如果指定了”main”属性)
- /root/page/node_modules/animal/index.js
- /root/node_modules/animal.js
- /root/node_modules/animal/package.json(如果指定了”main”属性)
- /root/node_modules/animal/index.js
- /node_modules/animal.js
- /node_modules/animal/package.json(如果指定了”main”属性)
- /node_modules/animal/index.js
所以正确答案为 A B。
动态 import
/* 动态 import */
// 传统的import 打包时合并为一个文件,无法按需加载
import sum from './sum'
document.getElementById('button').addEventListener('click', () => {
alert(sum(1,2))
})
// 需要同时修改 tsconfig.json的module: 'esnext' 才支持这种语法 即一代的模块系统
// 动态的import() 动态的导入JS文件 写法1
document.getElementById('button').addEventListener('click', () => {
import('./sum').then(module => {
alert(module.default(1,2)) // 默认是default
}
})
// 动态的import() 动态的导入JS文件 写法2
// webpack 独有语法,将打包的文件以指定的名字进行文件命名如 sum.bundle.js
document.getElementById('button').addEventListener('click', async () => {
const sum = await import(/* webpackChunckName: "sum" */ './sum')
alert(sum.default(1, 2))
})
答案
解析
动态 import 结合 webpack 可以实现按需加载,实现性能优化。
在 ts 中使用动态 import 需要配置
// tsconfig.json
{
"compilerOptions": {
// 或者 "module": "commonjs",
"module": "esnext",
...
},
}
题目中提供了两种动态 import 的方式。是正确的。