赞
踩
Node.js支持两种模块系统:CommonJS 和 ESModules(ESM),它们在语法和功能上有一些不同。
CommonJS 是 Node.js 最早支持的模块规范,由于它的出现在ES6之前,因此采取的是同步加载模块的方式。这在服务端是可接受的,因为文件都在本地,同步加载不会引起明显的延迟问题。但是这样的加载方式不适合用在客户端,因为它会导致浏览器在等待模块下载和解析的期间挂起。
require
函数来导入模块,如 const module = require('module_name')
。module.exports
对象,如 module.exports = value
或 exports.value = value
。ESModules 是ES6引入的官方标准化模块系统,支持静态导入和导出。静态模块结构允许JavaScript引擎优化加载和解析。
import
关键字导入模块,例如 import { something } from 'module_name'
。export
关键字导出模块,例如 export function doSomething() { ... }
或 export default class MyClass{ ... }
。ESModules设计为可以异步加载,这使其更适合于用在浏览器环境中,不过Node.js现在也支持ESModules。
加载机制:
模块解析:
require
路径解析算法基于文件系统运作,并且可以省略文件后缀或指向文件夹。导出值:
require()
执行完毕,模块内部的变化不会影响这个值。模块上下文:
this
是 undefined
,CommonJS 和 ESModules 由于它们各自的特点,在不同的应用场景下会有所偏好。下面列举了它们的典型应用场景:
import()
)和静态代码分析,这有利于前端工具进行代码拆分,以懒加载的方式优化应用加载性能。Node.js已经提供了某些语法糖和特性来平滑CommonJS到ESModules的过渡,如import()
动态导入语法来异步加载CommonJS模块等。
选择使用CommonJS还是ESModules很大程度上依赖于项目的目标环境、工具链支持、代码库的现状以及个人或团队的偏好。随着技术演进,社区正在向ESModules靠拢,但在稳定性、交付和兼容性要求很高的情况下,CommonJS仍然是一个合理而且可靠的选择。
导出示例:
// myModule.js
const myFunction = () => {
console.log('Hello, CommonJS!');
}
// 给exports对象添加属性
exports.myFunction = myFunction;
导入示例:
// app.js
const myModule = require('./myModule.js');
myModule.myFunction(); // 输出: 'Hello, CommonJS!'
导出示例:
// myModule.js
export const myFunction = () => {
console.log('Hello, ESModules!');
}
导入示例:
// app.js
import { myFunction } from './myModule.js';
myFunction(); // 输出: 'Hello, ESModules!'
此外,下面的示例说明了CommonJS如何在运行时加载模块,而ESModules则在编译时加载模块。
// 假设我们在运行代码之前并不知道我们需要加载的模块版本,我们可以在运行时动态地确定。
let version = 'v1';
if (someCondition) {
version = 'v2';
}
const module = require(`./module${version}.js`);
// 在ESModules中,不能这样动态加载模块,因为所有的import都会在编译时被处理。
// 下面的代码无法运行,会提示错误。
let version = 'v1';
if (someCondition) {
version = 'v2';
}
// 报错
import module from `./module${version}.js`;
但是,ESModules 提供了一种动态导入的方法,可以在运行时异步加载模块:
let version = 'v1';
if (someCondition) {
version = 'v2';
}
import(`./module${version}.js`)
.then(module => {
// 使用模块
})
.catch(err => {
// 处理加载错误
});
在这个例子中,import()
返回一个 Promise,加载完模块后会被解析,因此动态导入必须在 Promise 或 async/await 上下文中处理。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。