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 替换节点

let traverse = require(‘@babel/traverse‘).default; // @babel-traverse 遍历节点

let generator = require(‘@babel/generator‘).default; // @babel/generator 生成

let ejs = require(‘ejs‘); // js模版

class Compiler {

// 构造函数

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; // 对应的节点

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(){

// 发射文件

// 用数据渲染

// 输出路径

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() {

// 执行并创建模块依赖关系

this.buildModule(path.resolve(this.root, this.entry),true);

// 发射一个打包后的文件

this.emitFile();

}

}

module.exports = Compiler;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手写一个webpack插件,你可以按照以下步骤进行操作: 1. 首先,了解webpack自身插件的调用流程。你可以参考webpack内部插件的实现方式来理解。其中一个例子是NodeEnvironmentPlugin插件。 2. 创建一个新的插件文件,比如TestPlugin.js,并在文件中定义一个插件类,比如TestPlugin。 3. 在插件类中使用tapable实例的方法,在webpack的emit钩子函数执行时触发我们定义的函数。你可以使用compiler.hooks.emit.tap方法来绑定钩子函数。 4. 在钩子函数内部,使用compiler.outputFileSystem.writeFile方法创建一个自定义的文件,并在文件中写入你想要的内容。比如你可以写入一句话,如"//我们的第一个webpack插件!"。 5. 在webpack配置文件中引入你的插件,并将它作为一个实例加入到plugins数组中。 以下是一个示例的webpack配置文件,展示了如何引入TestPlugin插件: ``` const path = require('path'); const TestPlugin = require('./TestPlugin'); module.exports = function() { return { mode: 'development', entry: ['./src/app.js'], output: { path: path.join(__dirname, 'out'), filename: 'out.[name].js' }, plugins: [ new TestPlugin() ] }; }; ``` 通过以上步骤,你就可以手写一个简单webpack插件了。这个插件会在webpack输出的文件夹中创建一个自定义的文件,并在文件中写入一句话。你可以根据自己的需求,进一步扩展和定制插件的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值