var fs = require('fs')
var parser = require('@babel/parser')
var traverse = require('@babel/traverse').default
const path = require('path');
var babel = require('@babel/core')
function ModelInfo(fileUrl){
var content = fs.readFileSync(fileUrl,'utf-8');
var ast = parser.parse(content,{
sourceType:'module'
})
var deps = {}
traverse(ast,{
ImportDeclaration({node}){
var dirname = path.dirname(fileUrl)
var darPath = './'+path.join(dirname,node.source.value)
deps[node.source.value] = darPath.replace('\\','/')
}
})
const {code} = babel.transformFromAst(ast,null,{
presets:["@babel/preset-env"]
})
const moduleInfo = {fileUrl,deps,code}
return moduleInfo
}
function parseModules (fileUrl){
var entry = ModelInfo(fileUrl)
var temp = [entry]
for(let i = 0;i<temp.length;i++){
const deps = temp[i].deps
if (deps){
for (const key in deps){
if (deps.hasOwnProperty(key)){
temp.push(ModelInfo(deps[key]))
}
}
}
}
var depsMap = {}
temp.forEach(moduleInfo =>{
depsMap[moduleInfo.fileUrl] = {
deps:moduleInfo.deps,
code:moduleInfo.code
}
})
return depsMap
}
function bundle(fileUrl){
var depsMap = parseModules(fileUrl)
return `(function (graph){
console.log(graph)
function require(file) {
function absRequire(relPath) {
//我们再子模块中的代码中会这是require(path) 的文件加载相对路径我们需要根据相对路径获取其对应的map中的绝对路径 然后调用自定义的require方法通过自执行函数进行执行code
return require(graph[file].deps[relPath])
}
var exports = {};
(function (require,exports,code) { //将上下文传入 用于嵌套文件中的上下文使用
eval(code)
})(absRequire,exports,graph[file].code)
return exports //将exports对象返回
}
require('${fileUrl}')
})(${JSON.stringify(depsMap)})`
}
const content = bundle('./src/index.js')
fs.mkdirSync('./dist');
fs.writeFileSync('./dist/bundle.js',content)`