|
| 1 | + |
| 2 | +// 模块 |
| 3 | +const circle = require('./shape/circle'); |
| 4 | +console.log(`半径为 3 的圆的面积为: ${circle.area(3)}`); // 半径为 3 的圆的面积为: 28.274333882308138 |
| 5 | + |
| 6 | +const Square = require('./shape/square'); |
| 7 | +const mySquare = new Square(4); |
| 8 | +console.log(`mySquare 的面积为: ${mySquare.area()}`); // mySquare 的面积为: 16 |
| 9 | + |
| 10 | +// 主模块 |
| 11 | +const isMain = require.main === module; |
| 12 | +if (isMain) console.log(`main module: ${require.main.filename} `);// main module: /.../module/index.js |
| 13 | + |
| 14 | +// 获取模块加载名 |
| 15 | +const cycleName = require.resolve('./shape/circle'); |
| 16 | +console.log(`${cycleName}`); // /.../module/index.js |
| 17 | + |
| 18 | +// 模块加载缓存, |
| 19 | +const Square1 = require('./shape/square'); // square.js 中的 console.log 只输出一次 |
| 20 | +const Square2 = require.cache[require.resolve('./shape/square')].exports; |
| 21 | +console.log(`Square === Square1: ${Square === Square1}\nSquare === Square2: ${Square === Square2}`); // Square === Square1: true Square === Square2: true |
| 22 | + |
| 23 | +// 循环导入问题 |
| 24 | +console.log(`circular load a.js and b.js begin`); |
| 25 | +const a = require('./circular/a'); |
| 26 | +const b = require('./circular/b'); |
| 27 | +console.log(`index.js a.done = ${a.done}, b.done = ${b.done}`); |
| 28 | +console.log(`circular load a.js and b.js end`); |
| 29 | +/* |
| 30 | +circular load a.js and b.js begin |
| 31 | +a begin |
| 32 | +b.js begin |
| 33 | +b load a.js, a.done = false |
| 34 | +b end |
| 35 | +a load b.js, b.done = true |
| 36 | +b end |
| 37 | +index.js a.done = true, b.done = true |
| 38 | +circular load a.js and b.js end |
| 39 | +
|
| 40 | +index.js 加载 a.js 时, a 尝试加载 b.js |
| 41 | +但是 b.js 这时候尝试加载 a.js, 为防止死循环, 此时, b.js 只能拿到一个 a.js 的未完成的副本进行使用 |
| 42 | +b.js 完成加载后 a.js 拿到 b.js 的 exports, a.js 再完成剩余的加载 |
| 43 | +最终, 在 index.js 中 a.js 和 b.js 均完成加载 |
| 44 | +* */ |
| 45 | + |
| 46 | + |
| 47 | +// require 加载规则 -> http://nodejs.cn/api/modules.html#modules_all_together |
| 48 | +// 文件加载 LOAD_AS_FILE(X) |
| 49 | +const file1 = require('./fileModule/file1'); // If X is a file, load X as JavaScript text. STOP, |
| 50 | +console.log(`file1 is ${JSON.stringify(file1)}`); // file1 is {"name":"file1"}, 虽然 file1.js 存在, 但是查询到 file1 后停止 |
| 51 | + |
| 52 | +const file2 = require('./fileModule/file2'); // If X.js is a file, load X.js as JavaScript text. STOP |
| 53 | +console.log(`file2 is ${JSON.stringify(file2)}`); // file2 is {"name":"file2.js"} 虽然 file2.json 存在, 但是查询到 file2.js 停止 |
| 54 | + |
| 55 | +const file3 = require('./fileModule/file3'); // If X.json is a file, parse X.json to a JavaScript Object. STOP |
| 56 | +console.log(`file3 is ${JSON.stringify(file3)}`); // file3 is {"name":"file3.json"}, .node 文件未制作 |
| 57 | +// .node 插件待制作, 也会尝试加载 后缀为 .node的文件 |
| 58 | + |
| 59 | + |
| 60 | +// 目录加载, LOAD_AS_DIRECTORY(X) -> LOAD_INDEX(X) |
| 61 | +// LOAD_AS_DIRECTORY(X) |
| 62 | +// 1. If X/package.json is a file, |
| 63 | +// a. Parse X/package.json, and look for "main" field. |
| 64 | +// b. let M = X + (json main field) |
| 65 | +// c. LOAD_AS_FILE(M) |
| 66 | +// d. LOAD_INDEX(M) |
| 67 | +// 2. LOAD_INDEX(X) |
| 68 | +// |
| 69 | +// LOAD_INDEX(X) |
| 70 | +// 1. If X/index.js is a file, load X/index.js as JavaScript text. STOP |
| 71 | +// 2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP |
| 72 | +// 3. If X/index.node is a file, load X/index.node as binary addon. STOP |
| 73 | + |
| 74 | + |
| 75 | +const dirModule1 = require('./dirModule/dirModule1'); // package.json -> main -> load file |
| 76 | +console.log(`${JSON.stringify(dirModule1)}`); // {"name":"dirModule1/index.js"} |
| 77 | + |
| 78 | + |
| 79 | +const dirModule2 = require('./dirModule/dirModule2'); // package.json -> main -> LOAD_INDEX(main) |
| 80 | +console.log(`${JSON.stringify(dirModule2)}`); // {"name":"dirModule2/lib/index.js"} |
| 81 | + |
| 82 | +const dirModule3 = require('./dirModule/dirModule3'); // package.json -> main? -> LOAD_INDEX(dir) |
| 83 | +console.log(`${JSON.stringify(dirModule3)}`); // {"name":"dirModule3/index.js"} 虽然也存在 index.json 但是优先级低 |
| 84 | + |
| 85 | +const dirModule4 = require('./dirModule/dirModule4'); // package.json -> main? -> LOAD_INDEX(dir) |
| 86 | +console.log(`${JSON.stringify(dirModule4)}`); // {"name":"dirModule4/index.json"}, addon 未准备 |
| 87 | + |
| 88 | +// 从 node_modules 目录加载, 此处已 is 模块演示 |
| 89 | +const is = require('is'); |
| 90 | +console.log(`${is.string}`); // function (value) {return toStr.call(value) === '[object String]';} |
| 91 | + |
| 92 | + |
| 93 | +// 从全局目录加载, 如安装的全局模块 |
| 94 | +// NODE_PATH |
| 95 | +// $HOME/.node_modules |
| 96 | +// $HOME/.node_libraries |
| 97 | +// $PREFIX/lib/node |
| 98 | + |
| 99 | + |
| 100 | +// 模块封装器 |
| 101 | + |
| 102 | +// (function(exports, require, module, __filename, __dirname) { |
| 103 | +// // 模块的代码实际上在这里 |
| 104 | +// }); |
| 105 | +// 保持顶层变量,作用在模块范围内, 而不是全局对象 |
| 106 | +// 方便提供看似全局实际上是模块特有的变量 |
| 107 | + |
| 108 | +// 子模块可以泄露全局变量吗? |
| 109 | +const leakGlobalVar = require('./global/leakGlobalVar'); |
| 110 | +console.log(`module: ${JSON.stringify(leakGlobalVar)}, leak: ${leak}`); // module: {"name":"leakGlobalVar.js"}, leak: this is a leak global variable |
| 111 | + |
| 112 | +const vm1 = require('./global/vm'); |
| 113 | +console.log(vm1); // { name: 'global/vm.js' } |
| 114 | +console.log(leakInVm); // this is a leak object in vm |
| 115 | +// https://nodejs.org/docs/latest-v8.x/api/vm.html#vm_vm_runinthiscontext_code_options |
| 116 | +// |
0 commit comments