• 前端基础之《NodeJS(2)—模块化》


    一、模块化系统

    1、ECMAScript5没有模块化功能(ECMAScript6有了)

    比如jquery和jquery插件,要分别引入jquery、jquery插件。

    2、标准库较少

    3、没有标准接口

    4、缺乏管理系统

    不同包要到不同的官网上找。

    5、在Node中,一个js文件就是一个模块

    二、NodeJS模块化语法—使用ES6语法

    1、node中默认执行ES6语法,import导入、export导出模块会报错

    1. (node:22992) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
    2. (Use `node --trace-warnings ...` to show where the warning was created)
    3. D:\workspace-vscode\NodeJS\module03.js:3
    4. import * as m1 from "./module01.js";
    5. ^^^^^^
    6. SyntaxError: Cannot use import statement outside a module
    7. at wrapSafe (internal/modules/cjs/loader.js:988:16)
    8. at Module._compile (internal/modules/cjs/loader.js:1036:27)
    9. at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    10. at Module.load (internal/modules/cjs/loader.js:937:32)
    11. at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    12. at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    13. at internal/main/run_main_module.js:17:47

    2、解决办法

    (1)执行:npm init -y
    (2)在package.json中添加:"type": "module"

    三、NodeJS模块化语法—使用CommonJS语法

    1、引入函数require()

    说明:
    (1)在node中,可以通过require()函数来引入外部的模块。
    (2)require()可以传递一个文件的路径为参数,node将自动根据路径来引入外部模块。
    (3)使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块。

    2、向外部暴露变量和方法exports

    说明:
    (1)在Node中,每一个js文件中的js代码都是独立运行在一个函数中,而不是全局作用域,所以一个模块中的变量和函数在其他模块中无法访问。
    (2)每个模块对于其他模块都是封闭的,所以要把想暴露的东西暴露出去。
    (3)只需要将需要暴露给外部的变量或方法设置为exports的属性即可。
    (4)相当于exports对象是一个统一的出口。

    3、例子

    module01.js

    1. console.log("我是module01模块");
    2. var school = "xxx三中";
    3. exports.x = 10;
    4. var y = 20;
    5. exports.fn = function(){
    6. }

    module03.js

    1. console.log("我是module03模块");
    2. var md = require("./module01.js");
    3. console.log(md);

    输出:

    1. node .\module03.js
    2. 我是module03模块
    3. 我是module01模块
    4. { x: 10, fn: [Function (anonymous)] }

    四、模块化详解

    1、Node中虽然使用的是CommonJS规范(以前),但是其自身也对规范做了一些取舍。

    2、在Node中引入模块,需要经历如下3个步骤

    (1)路径分析
    (2)文件定位
    (3)编译执行

    3、在Node中,模块分为三类

    (1)一类是底层由C++编写的内建模块
    (2)一类是Node提供的核心模块
    (3)还有一类是用户编写的模块,称为文件模块

    4、模块标识

    我们使用require()引入外部模块时,使用的就是模块标识,我们可以通过模块标识来找到指定的模块。

    模块分成两大类:
    核心模块(由node引擎提供的模块,核心模块的标识就是模块的名字)
    文件模块(由用户自己创建的模块)

    5、global对象

    在node中有一个全局对象global,它的作用和网页中的window类似。
    在全局中创建的变量都会作为global的属性保存。
    在全局中创建的函数都会作为global的方法保存。

    6、如何定义全局变量

    变量名前不加var。

    1. a = 10;
    2. console.log(global.a);

    7、arguments对象

    arguments是伪数组对象。封装函数的实参。
    如何证明每个js模块的代码都是运行在函数里的:

    1. a = 10;
    2. //console.log(global.a);
    3. console.log(arguments);

    输出:

    1. [Arguments] {
    2. '0': {},
    3. '1': [Function: require] {
    4. resolve: [Function: resolve] { paths: [Function: paths] },
    5. main: Module {
    6. id: '.',
    7. path: 'D:\\workspace-vscode\\NodeJS',
    8. exports: {},
    9. parent: null,
    10. filename: 'D:\\workspace-vscode\\NodeJS\\module04.js',
    11. loaded: false,
    12. children: [],
    13. paths: [Array]
    14. },
    15. extensions: [Object: null prototype] {
    16. '.js': [Function (anonymous)],
    17. '.json': [Function (anonymous)],
    18. '.node': [Function (anonymous)]
    19. },
    20. cache: [Object: null prototype] {
    21. 'D:\\workspace-vscode\\NodeJS\\module04.js': [Module]
    22. }
    23. },
    24. '2': Module {
    25. id: '.',
    26. path: 'D:\\workspace-vscode\\NodeJS',
    27. exports: {},
    28. parent: null,
    29. filename: 'D:\\workspace-vscode\\NodeJS\\module04.js',
    30. loaded: false,
    31. children: [],
    32. paths: [
    33. 'D:\\workspace-vscode\\NodeJS\\node_modules',
    34. 'D:\\workspace-vscode\\node_modules',
    35. 'D:\\node_modules'
    36. ]
    37. },
    38. '3': 'D:\\workspace-vscode\\NodeJS\\module04.js',
    39. '4': 'D:\\workspace-vscode\\NodeJS'
    40. }

    有5个参数。

    8、arguments.callee属性

    这个属性保存的是当前执行的函数对象。
    打印当前函数对象:

    1. a = 10;
    2. //console.log(global.a);
    3. console.log(arguments.callee + "");

    输出: 

    1. function (exports, require, module, __filename, __dirname) {
    2. a = 10;
    3. //console.log(global.a);
    4. console.log(arguments.callee + "");
    5. }

    从中可以看到exports和require是哪里来的了。
    exports, require, module, __filename, __dirname这五个,就是上面打印arguments的实参。

    9、五个实参说明

    (1)exports:该对象用来将变量或函数暴露到外部
    (2)require:函数,用来引入外部的模块
    (3)module:代表的是当前模块本身。实际上我们用的exports就是module的属性
    (4)__filename:当前模块的完整路径
    (5)__dirname:当前模块所在的文件夹

    五、exports和module.exports

    1、exports暴露数据

    1. exports.name = "孙悟空";
    2. exports.age = 18;
    3. exports.sayName = function(){
    4. console.log("我是孙悟空");
    5. }

    2、module.exports暴露数据

    1. module.exports = {
    2. name: "猪八戒",
    3. age: 28,
    4. sayName: function(){
    5. console.log("我是猪八戒");
    6. }
    7. }

    module.exports后面可以跟一个对象。
    无论是用exports,还是用module.exports,最终改的都是module.exports属性。

    类似于:

    1. var obj = {};
    2. obj.a = {};
    3. var a = obj.a;
    4. //a 和 obj.a 指向的是同一个对象
    5. console.log(a === obj.a); //true

  • 相关阅读:
    java 链接mongo
    NOI2022游记,未曾设想的道路
    [信息安全] 加密算法:md5摘要算法 / sha256摘要算法
    Linux调试器:gdb的使用
    python 异步线程 实现 异步生产 同步通信
    nginx配置
    ESP32外部中断原理详解及代码示例
    统计信号处理基础 习题解答11-6
    神经网络的三种训练方法,神经网络训练过程图解
    聊聊asp.net core 授权流程
  • 原文地址:https://blog.csdn.net/csj50/article/details/127551111