当前位置:   article > 正文

Nodejs模块加载研究_add a symlink to it from project's node_modules/

add a symlink to it from project's node_modules/

博客迁移:不恰饭的小站
不恰饭的小站

1. 这个功能是什么

NodeJS 中有两种模块加载方式:CommonJS,ECMAScript modules;前者为 NodeJS 内部实现,ES Modules 为 JS 标准加载方式。

1.1. CommonJS

在 Node.js 模块系统中,每个文件都被视为一个单独的模块。

1.2. ECMAScript modules

ECMAScript 模块是打包 JavaScript 代码以供重用的官方标准格式。使用 import 和 export 导入导出模块。
Node.js 默认将 JavaScript 代码视为 CommonJS 模块。可以通过.mjs 文件扩展名,package.json 'type’字段,将 JavaScript 代码将 ECMAScript 视为模块

2. 这个功能如何实现

2.1. CommonJS

2.1.1. 模块包装器

Nodejs 中的模块是可执行的,nodejs 使用类似以下语法将模块封装为函数

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});
  • 1
  • 2
  • 3

通过这种方式

  1. 它将顶级变量(用 var、const 或 let 定义)的作用域限定在模块上,而不是全局对象上。
  2. 通过将模块内的数据导出到对象(exports,module),供外部调用者使用,同时引入了在模块内可使用的变量(__filename, __dirname)

3. 这个功能相关的参与者与接口

3.1. CommonJS 接口

3.1.1. __dirname

文件绝对路径所在的目录

3.1.2. __filename

文件的绝对路径

3.1.3. exports module.exports

exports 是 module.exports 的简写,两者关系如下相关资料

  • exports 只能使用语法来向外暴露内部变量:如http://exports.xxx = xxx;
  • module.exports 既可以通过语法,也可以直接赋值一个对象。

伪代码实现说明

function require(/* ... */) {
  const module = { exports: {} };
  ((module, exports) => {
    // Module code here. In this example, define a function.
    function someFunc() {}
    exports = someFunc;
    // At this point, exports is no longer a shortcut to module.exports, and
    // this module will still export an empty default object.
    module.exports = someFunc;
    // At this point, the module will now export someFunc, instead of the
    // default object.
  })(module, module.exports);
  return module.exports;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

建议不要使用 exports,因为 module.exports 都能做,还不会出错

3.2. ES modules

3.2.1. specifier (区分符)

区分符 specifier 指以下文句中的 ‘path’

import { sep } from 'path'
  • 1

specifier 有如下形式

  1. 相对路径。它们引用相对于导入文件位置的路径。对于这些文件,文件扩展名总是必需的。如 ‘./startup.js’ or ‘…/config.mjs’
  2. 包名。它们可以通过包名引用包的主入口点,也可以根据示例分别引用以包名作为前缀的包内的特定特性模块。
  3. 绝对路径。直接和显式地引用了一个完整的路径。‘file:///opt/nodejs/config.js’.

4. CommonJS 与 ECMAScript modules 互操作

4.1. import

import 语句(import * from ‘xxx’)只允许在 ES 模块中使用,但在 CommonJS 中支持动态 import()表达式来加载 ES 模块。

4.2. require

只用来加载 CommonJS 模块

4.3. CommonJS Namespaces

CommonJS 模块由一个 module.exports 对象组成。可以导出任何类型的对象

5. 示例

5.1. commonjs

5.1.1. 使用 module.exports 导出

  • 库文件
function add(a, b) {
  return a + b;
}

module.exports = add;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 主函数文件
let add_commonjs_modules_exports = require('./modules/add_commonjs_modules_exports.js');
console.log(add_commonjs_modules_exports(1, 2));
  • 1
  • 2

5.1.2. 使用 exports 导出

  1. 给 exports 的成员赋值
  • 库文件
function add(a, b) {
  return a + b;
}

exports.add = add;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 主函数文件
let add_commonjs_exports = require('./modules/add_commonjs_exports.js');
console.log(add_commonjs_exports.add(1, 2));
  • 1
  • 2
  1. 给 exports 赋值(此方法无法导出)
  • 库文件
function add(a, b) {
  return a + b;
}

exports = add; //此种方式无法导出任何内容

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 主函数文件
let add_commonjs_exports_error = require('./modules/add_commonjs_exports_error.js');
console.log(add_commonjs_exports_error(1, 2)); //此种有错误,模块内容有误
  • 1
  • 2

5.2. ESModules

5.2.1. 使用 export 导出,注意其中 default 使用

  • 库文件
export function add(a, b) {
  return a + b;
}

export default add; //用于 import XXX from ""这种简写形式

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 主函数文件
import * as fun from './modules/add_ES_export.mjs';
console.log(fun);
console.log(fun.add(1, 2));
/*
fun.add = function (a, b) { //由export导出的为const
  return a - b;
};*/
fun.default.add = function (a, b) {
  //由export导出的为const,但其对象属性可修改
  return a - b;
};
console.log(fun.add(1, 2));
console.log(fun.default.add(1, 2));

import { add } from './modules/add_ES_export.mjs';
console.log(add(1, 2));

import a from './modules/add_ES_export.mjs'; //等价于 import { default as a } from './modules/add_ES_export.mjs';
console.log(a);

import { default as b } from './modules/add_ES_export.mjs';
console.log(b);


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

5.3. 用 import 加载 commonjs 模块

  • 库文件
function add(a, b) {
  return a + b;
}

module.exports = add;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 主程序文件
import * as c from './modules/add_commonjs_modules_exports.js'; //es中调用commonjs模块
console.log(c.default(1,2));

import add1 from './modules/add_commonjs_modules_exports.js';
console.log(add1(1,2));
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/65911
推荐阅读
相关标签
  

闽ICP备14008679号