知识点
es模块、commonjs模块
- 它们的特点都是一样的 每个文件都是一个模块
commonjs只是一个规范
1)每个文件都是一个模块
2)如果要使用 就需要require
3)如果要给别人用 就需要module.exports
怎么实现模块化? 防止命名冲突
命名空间 无法彻底解决命名问题
自执行函数 node让js拥有了在服务端执行的能力,可以读写文件
模块
新建usea.js、 a.js
1 | // a.js |
1 | // usea.js |
这里require进来a文件相当于如下:
1 | let a = (function(){ |
怎么实现模块化的 传进来一个匿名函数,让函数执行,拿到它导出来的结果 就可以了
node之所以能实现CommonJS规范,靠的是文件读写,将a文件读出来,加上自执行这个函数 一执行就好了。
fs模块
1 | const fs = require('fs'); |
path模块
1 | const path = require('path'); // 专门处理路径的模块 |
resolve & join
join 就是单纯的拼路径
1 | console.log(path.resolve('a', 'b')); // /Users/jiafei/Desktop/node-test/a/b |
加 __dirname
1 | console.log(path.resolve(__dirname, 'a', 'b')); |
加 /
1 | // resolve出来的肯定是个绝对路径 join就是以/拼接 |
其他
1 | console.log(path.extname('main.js'));// .js |
vm模块
它提供了一个沙箱环境(一个安全的环境,不会影响其它)
1 | require('vm'); // 虚拟机模块 |
1 | /*这里 引入a |
让字符串执行 new Function \ eval \ vm
1 | let a = 1; |
这时a.js中的代码如下:
1 | // 供沙箱示例 |
usea.js
1 | // let b = XX; |
文件读写
手写require模块
a.js
1 | // (function(exports,module,require){ |
usea.js
1 | const path = require('path'); |
源码 require() 核心逻辑
- Module._resolveFilename 解析文件名字 获取文件绝对路径
- module.load(filename); 加载模块
- fs.readFileSync(filename, ‘utf8’); 同步的读取文件内容
- 加函数
- 让函数执行 module.exports 传入给用户 用户会给module.exports赋值
- 把module.exports返回