如何使用自己的webpack

前言

前端模块化编程思想是很重要的,优秀的模块化打包工具比如webpack、rollup、vite都可以用来进行模块编程。那么如何实现自己的打包工具呢?这里我们模仿webpack的底层打包思想来实现自己的打包工具。

准备

如何在全局下定义自己的打包命令以使用自己的打包工具?

我们需要准备一个文件夹(自定义名字),这里我以mypack命名,目录结构参考下图。

注意package.json里面的"bin"的属性值的’mypack’是命令(后面会使用npm link,然后就可以在全局下使用这个命令了)

在这里插入图片描述

mypack.js代码如下(第一行代码的意思是指定用node运行该js文件)

下面代码的template模板是从wepback打包出的bundle.js中提取出来的

#! /usr/bin/env node
//这个文件就要描述如何打包
let entry='./src/index.js';//入口文件
let output='./dist/main.js';//出口文件
let fs=require('fs');
let path=require('path');
let modules={}
let content=fs.readFileSync(entry,'utf8')
let styleLoader=function(source){//负责将结果进行更改 更改后继续走
    //source代表的就是样式文件中的内容
    return `
        let style=document.createElement('style');
        style.innerHTML=${JSON.stringify(source).replace(/\\r\\n/g,'')};
        document.head.appendChild(style);
    `
}
//JSON.stringfy(source)的结果是body{\r\n background:red \r\n}
//处理依赖关系
function replaceFn(name,content){
    content=content.replace(/require\(['"](.+?)['"]\)/g,function(){
        let name=path.join('./src',arguments[1]);//./src/a.js
        let content2=fs.readFileSync(name,'utf8');
        if(/\.css$/.test(name)){
            content2=styleLoader(content2)
        }
        replaceFn(name,content2)
        return `require('${name}')`
    })
    modules[name]=content
}

replaceFn(entry,content)
let ejs=require('ejs')
let template=`(function(modules) {
    function require(moduleId) {
        var module =  {
            exports: {}
        };
        modules[moduleId].call(module.exports, module, module.exports, require);
        return module.exports;
    }
    return require("<%-entry%>");
})
({
<%Object.keys(modules).forEach((key)=>{%>
    "<%-key%>":
(function(module, exports, require) {
eval(\`<%-modules[key]%>\`);
}),
<%})%>
 })
`
let result=ejs.render(template,{
    entry,
    modules
});
//result为替换后的结果,最终要写到output中
fs.writeFileSync(output,result)
console.log('成功')

生成全局打包命令

好了,目录结构和自定义打包代码已经准备好了,我们现在就要把这个mypack文件夹放在本地npm文件夹。

我们使用npm link命令以完成这个操作

在这里插入图片描述

使用全局打包命令

好了,经过以上的步骤,我们现在就可以使用我们的全局打包命令了!

我们要确保现在处于项目根目录,因为我们的打包工具里面的代码入口文件是’./src/index.js’

在这里插入图片描述

我们现在使用mypack命令打包一下!

打包的结果在项目根目录的dist/main.js

在这里插入图片描述

main.js的代码如下

(function(modules) {
    function require(moduleId) {
        var module =  {
            exports: {}
        };
        modules[moduleId].call(module.exports, module, module.exports, require);
        return module.exports;
    }
    return require("./src/index.js");
})
({

    "src\b.js":
(function(module, exports, require) {
eval(`module.exports='bbbbb'
`);
}),

    "src\a.js":
(function(module, exports, require) {
eval(`let result=require('src\b.js')
module.exports=result`);
}),

    "src\index.css":
(function(module, exports, require) {
eval(`
        let style=document.createElement('style');
        style.innerHTML="body{    background-color:blue;}";
        document.head.appendChild(style);
    `);
}),

    "./src/index.js":
(function(module, exports, require) {
eval(`let result=require('src\a.js')
let result2=require('src\b.js')
require('src\index.css')
console.log(result+result2)`);
}),

 })

验证效果

我们在项目的根目录的dist/index.html中引入main.js

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值