# 三.递归解析
# lin/Complier.js
let fs = require("fs")
let path = require("path")
let babylon = require("babylon")
let traverse = require("@babel/traverse").default
let t = require("@babel/types")
let generator = require("@babel/generator").default
//babylon 主要把源码转换成ast
//@babel/traverse
//@babel/types
//@babel/generator
class Complier {
constructor(config) {
//entry output
this.config = config
//需要保存入口文件的路径
this.entryId
//需要保存所有的模块依赖
this.modules = {}
this.entry = config.entry
this.root = process.cwd()
}
getSource(modulePath) {
let content = fs.readFileSync(modulePath, "utf8")
return content
}
//解析源码 AST解析语法树
parse(source, parentPath) {
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)
;("src/a.js")
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
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() {}
run() {
//执行
this.buildModule(path.resolve(this.root, this.entry), true)
console.log(this.modules, this.entryId)
this.emitFile()
}
}
module.exports = Complier
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# 运行
npx mypack
1