android手写简单mvp,[webpack]手写一个mvp版本的webpack
let fs = require(‘fs‘);
let path = require(‘path‘);
let babylon = require(‘babylon‘); // Babylon 把源碼轉換為AST
let t = require(‘@babel/types‘); // @babel-types 替換節(jié)點
let traverse = require(‘@babel/traverse‘).default; // @babel-traverse 遍歷節(jié)點
let generator = require(‘@babel/generator‘).default; // @babel/generator 生成
let ejs = require(‘ejs‘); // js模版
class Compiler {
// 構造函數(shù)
constructor(config) {
// entry out
this.config = config;
// 1、保存入口文件的路徑
this.entryId;
// 2、博阿村所有的模塊依賴
this.modules = {};
// 入口路徑
this.entry = config.entry;
// 工作路徑
this.root = process.cwd();
}
// 獲取文件源碼
getSource(modulePath){
let content = fs.readFileSync(modulePath,‘utf8‘);
return content;
}
// 解析源碼
parse(source,parentPath){
// AST解析語法樹
let ast = babylon.parse(source);
let dependencies = [];
traverse(ast,{
CallExpression(p){
let node = p.node; // 對應的節(jié)點
if(node.callee.name === ‘require‘){
node.callee.name = ‘__webpack_require__‘;
let moduleName = node.arguments[0].value; // 取到的就是模塊的引用名字
moduleName = moduleName + (path.extname(moduleName)?‘‘:‘.js‘);
moduleName = ‘./‘+path.join(parentPath,moduleName);
dependencies.push(moduleName);
node.arguments = [t.stringLiteral(moduleName)];
}
}
});
let sourceCode = generator(ast).code;
return { sourceCode, dependencies }
}
// 建立模塊
buildModule(modulePath,isEntry){
// 拿到模塊的內容
let source = this.getSource(modulePath);
// 模塊id modulePath modulePath-this.root = src/index.js
let moduleName = ‘./‘+path.relative(this.root,modulePath);
if(isEntry){
// 保存入口的名字
this.entryId = moduleName;
}
// 解析需要把source源碼進行改造,返回一個依賴列表
let {sourceCode,dependencies} = this.parse(source,path.dirname(moduleName));
this.modules[moduleName] = sourceCode;
dependencies.forEach(
// 父模塊的加載,遞歸加載
(dep)=>{
this.buildModule(path.join(this.root,dep),false)
}
);
}
emitFile(){
// 發(fā)射文件
// 用數(shù)據(jù)渲染
// 輸出路徑
let main = path.join(this.config.output.path,this.config.output.filename);
// 模板的路徑
let tempateStr = this.getSource(path.join(__dirname,‘main.ejs‘));
let code = ejs.render(tempateStr,{
entryId:this.entryId,
modules: this.modules
});
// this.assets = {};
// // 路徑對應的代碼
// this.assets[main] = code;
// fs.writeFileSync(main,this.assets[main]);
fs.writeFileSync(main,code);
}
run() {
// 執(zhí)行并創(chuàng)建模塊依賴關系
this.buildModule(path.resolve(this.root, this.entry),true);
// 發(fā)射一個打包后的文件
this.emitFile();
}
}
module.exports = Compiler;
總結
以上是生活随笔為你收集整理的android手写简单mvp,[webpack]手写一个mvp版本的webpack的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html5变动标签新写法,Html5新标
- 下一篇: html css移动位置,html –