[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
- 框架篇
- 隨記