提示:看到我 请让我滚去学习
文章目录
前言
浅谈require和import
- require 是 CommonJS 的模块加载方法,主要用于 Node.js 环境。它是在运行时同步加载模块的,这意味着只有当 require 函数执行完,才能继续执行后面的代码
- import 是 ES6 的模块加载方法,主要用于现代浏览器环境,也被 Node.js v14 及以上版本支持(需要在 package.json 中设置 “type”: “module”)。它是在编译时就确定模块依赖关系的,也就是说 import 语句是静态的,不能在运行时改变。
注意:在 Node.js 中使用 import 时,文件扩展名必须是 .mjs,或者在 package.json 中设置 “type”: “module”,并且导入的模块也必须是 ES6 模块。
ES6 vs CommonJS
ES6 vs CommonJS:import 是 ES6(ECMAScript 2015)的语法,而 require 是 CommonJS 的语法。ES6 模块是 JavaScript 语言标准的一部分,而 CommonJS 模块是 Node.js 的模块系统。
1.静态 vs 动态:import 是静态的,意味着你不能在运行时改变你要导入的模块。另一方面,require 是动态的,你可以在运行时决定要导入哪个模块。
- Tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码的过程。它依赖于 ES6 的模块系统的静态结构特性。
ES6:ES6 模块是静态的,这意味着你不能动态地导入或导出模块。这使得编译器(如 Babel)和打包工具(如 Webpack、Rollup)可以在编译阶段确定哪些模块和模块的哪些部分被使用了。这样,它们就可以删除未使用的代码,从而减少最终的打包大小。这就是所谓的 “tree shaking”。
CommonJS:相比之下,CommonJS 模块是动态的,这意味着你可以动态地导入或导出模块。这使得在编译阶段很难确定哪些模块和模块的哪些部分被使用了。因此,CommonJS 模块不支持 tree shaking。
2.顶级作用域:import 只能在顶级作用域中使用,而 require 可以在任何地方使用。
3.异步 vs 同步:import 可以异步加载模块(使用 import() 语法),而 require 是同步加载模块。
4.默认导出和命名导出:import 可以同时导入默认导出和命名导出,而 require 需要分别处理默认导出和命名导出。
- 当使用module.exports命名导出时require会加载整个文件生成对象,在读取对象上命名导出方法。
- 当使用exports命名导出时import会加载命名导出的方法,其他方法不加载。
CommonJS
CommonJS 使用 exports 导出模块, require 导入模块
具体规范如下:
- 如果一个 JS 文件中存在 exports 或者 require,该 js 时一个模块。
- 模块内的所有代码均为隐藏代码,包括全局变量、全局函数,这些全局的内容均不应该对全局变量造成任何污染。
- 如果一个模块需要暴露一些 API 提供给外部使用,需要通过 exports 导出,exports是一个空的对象, 可以为该对象添加需要导出的内容。
- 如果一个模块需要导入其他模块,通过 require 实现,require 是一个函数,传入模块的路径即可返回该模块导出的整个内容。
- 在 nodejs 导入自定义模块,要使用相对路径,以./或者…/开头。
//index.js
module.exports = {
// 导出部分
};
// 或者
exports.xxx;
//导入
const onj = require("./index.js");
node 对 CommonJS 的实现
为了实现 CommonJS 规范,nodejs 对模块做出了以下处理:
- 为了高效的执行,仅加载必要的模块。 node 只有执行到require函数时才会加载并执行模块。
- 为了隐藏模块中的代码,nodejs 执行模块时,会将模块中的代码放置到一个函数中执行,以保证不污染全局变量,
- 为了保证顺利的导出模块内容
○ 在模块开始执行前,初始化一个值module.exports = {}
○ module.exports = {} 即为模块的导出值
○ 为了方便开发者便捷的导出,有声明了一个变量 exports = module.exports
(function (module) {
module.exports