[TOC]
手写 CommonJS 的简单实现
# 示例
`a.js`:
~~~javascript
const fn = function () {
console.log('Hello');
}
module.exports = fn;
~~~
# 第一种
~~~js
let fs = require('fs')
//common.js规范实现(node中)
let a = req('./a.js')
function req(moduleName){
let content = fs.readFileSync(moduleName, 'utf-8')
//下面是创建一个字符串函数
let fn = new Function('exports','module', 'require', '__dirname', '__filename',
content + '\n return module.exports'
);
//构造一个module对象,用于给module.exports赋值
let module = {
exports:''
}
//这里传入req是由于req的文件里面可能require其他文件
return fn(module.exports,module,req,__dirname,__filename)
}
/*
* fn函数注释
*/
// function fn(exports,module, require, __dirname, __filename){
// //let content = fs.readFileSync(moduleName, 'utf-8')执行结果是字符串
// module.exports = '我的第一个webpack'
// return module.exports
// }
console.log(a)
~~~
# 第二种
```js
const path = require('path');
const fs = require('fs');
const vm = require('vm');
// Module处理
function Module(id) {
this.id = id;
this.exports = {};
};
// 缓存
Module.cache = {};
// 不同后缀类型处理
Module.extensions = {};
Module.extensions['.js'] = function (module) {
let script = fs.readFileSync(module.id, 'utf8');
const wrapper = `(function (exports, require, module, __dirname, __filename) {${script}})`;
const fn = vm.runInThisContext(wrapper);
fn(module.exports, req, module, __dirname, __filename);
return module.exports;
};
Module.extensions['.json'] = function (module) {
let jsonContent = fs.readFileSync(module.id, 'utf8');
return JSON.parse(jsonContent);
};
Module.getPath = function (id) {
const absPath = path.resolve(id);
if (fs.existsSync(absPath)) {
return absPath;
}
const extensions = Object.keys(Module.extensions);
for (let i = 0; i < extensions.length; i++) {
const extPath = `${absPath}${extensions[i]}`;
if (fs.existsSync(extPath)) {
return extPath;
}
}
throw new Error('The file do not exist');
}
const req = (id) => {
const ext = Module.getPath(id);
if (Module.cache[ext]) {
return Module.cache[ext];
}
const myModule = new Module(ext);
// 对应后缀方法执行
const result = Module.extensions[path.extname(ext)](myModule);
Module.cache[ext] = myModule;
return result;
};
//以下是使用req的代码块
const func = req('./b');
func(); // Hello
```
> [手写 commonJs](https://www.javascriptcn.com/read-103959.html)
- 修仙之路
- 基础原理篇
- JS和Node.js事件环机制剖析
- 一图理解原型链
- 手写篇
- 基础手写
- 手写实现 Promise A+ 类库
- 手写 CommonJS
- 手写 Express 框架
- 手写 React Router 4.0
- 手写虚拟 DOM 和 DOM-Diff
- 手写 Webpack 实现
- 手写一个 MVVM 类库
- 手写一个 Vue-cli 脚手架
- 手写 JWT 类库
- 手写 Mobx 类库
- 手写前端性能和错误监控框架
- 手写 Vue 路由
- 手写 Vuex 实现
- 手写 redux 状态容器
- 手写 throttle 和 debounce
- Node 高级
- Mongodb
- 安全测试篇
- CSRF原理实现
- XSS原理实现
- 九种跨域方法全解析
- 编写单元测试
- 爬虫篇
- 使用puppeteer破解滑动验证码
- 工程篇
- 使用AST语法树手工转译ES6代码
- 编写自己的webpack插件
- 实战篇
- webpack4.0 实战
- Canvas+Websocket 实现弹幕
- canvas 动效
- SVG 动效
- CSS3 实现 Apple Watch 中的呼吸灯效果
- CSS3 实现动态气泡屏保效果
- 算法篇
- 基础知识
- 服务器端
- 分布式架构中的幂等性
- TCP/UDP
- Docker
- V8
- 动画篇
- 贝塞尔曲线
- requestAnimationFrame
- 框架篇
- 随记