新建项目bundler,在目录下新建src目录,在目录新建文件, 目录结构如下:
word.js
export const word = 'hello'
message.js
import {word} from './word.js'
const message = `say ${word}`
export default message
index.js
import {message} from './message.js'
console.log(message)
bundler.js
const fs = require('fs') //获取文件信息
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
console.log(content)
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js
,打印出了index.js中的内容:
katedeMacBook-Air:bundler kate$ node bundler.js
import {message} from './message.js'
console.log(message)
katedeMacBook-Air:bundler kate$
让代码高亮显示
安装:
npm install cli-highlight -g
运行node bundler.js | highlight
babel: 帮助我们分析语法
安装:
npm install @babel/parser --save
参考文档: https://www.babeljs.cn/docs/babel-parser
bundler.js
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
console.log(parser.parse(content, {
sourceType: 'module'
}))
// console.log(content)
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight
,打印出抽象语法树
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
Node {
type: 'File',
start: 0,
end: 57,
loc:
SourceLocation {
start: Position { line: 1, column: 0 },
end: Position { line: 2, column: 20 } },
errors: [],
program:
Node {
type: 'Program',
start: 0,
end: 57,
loc: SourceLocation { start: [Position], end: [Position] },
sourceType: 'module',
interpreter: null,
body: [ [Node], [Node] ],
directives: [] },
comments: [] }
使用babel中parse分析抽象语法树
bundler.js
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
const ast = parser.parse(content, {
sourceType: 'module'
})
console.log(ast.program.body)
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
[ Node {
type: 'ImportDeclaration',
start: 0,
end: 36,
loc: SourceLocation { start: [Position], end: [Position] },
specifiers: [ [Node] ],
source:
Node {
type: 'StringLiteral',
start: 22,
end: 36,
loc: [SourceLocation],
extra: [Object],
value: './message.js' } },
Node {
type: 'ExpressionStatement',
start: 37,
end: 57,
loc: SourceLocation { start: [Position], end: [Position] },
expression:
Node {
type: 'CallExpression',
start: 37,
end: 57,
loc: [SourceLocation],
callee: [Node],
arguments: [Array] } } ]
两个node里是声明的语句, 声明的语句放置的是入口文件对应的依赖关系
使用babel中的traverse
安装:
npm install @babel/traverse --save
bundler.js
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
const ast = parser.parse(content, {
sourceType: 'module'
})
const dependencies = []
//对代码分析
//对ast遍历
traverse(ast, {
ImportDeclaration({node}) {
// console.log(node)
dependencies.push(node.source.value)
}
})
console.log(dependencies)
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight
:
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
[ './message.js' ]
路径是相对路径,需要打印出绝对路径(相对于bundler.js文件):
bundler.js
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const path = require('path')
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
const ast = parser.parse(content, {
sourceType: 'module'
})
const dependencies = []
//对代码分析
//对ast遍历
traverse(ast, {
ImportDeclaration({node}) {
const dirname = path.dirname(filename)
const newFile = './' + path.join(dirname, node.source.value)
console.log(newFile)
dependencies.push()
}
})
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight
:
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
./src/message.js
存两个路径
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const path = require('path')
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
const ast = parser.parse(content, {
sourceType: 'module'
})
const dependencies = {}
//对代码分析
//对ast遍历
traverse(ast, {
ImportDeclaration({node}) {
const dirname = path.dirname(filename)
const newFile = './' + path.join(dirname, node.source.value)
dependencies[node.source.value] = newFile
}
})
console.log(dependencies)
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight:
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
{ './message.js': './src/message.js' }
使用babel中的core
安装:
npm install @babel/core --save
参考文档: https://www.babeljs.cn/docs/babel-core
使用babel中的preset-env
安装: npm i @babel/preset-env --save
bundler.js
const fs = require('fs') //获取文件信息
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const path = require('path')
const babel = require('@babel/core')
// 分析入口文件
const moduleAnalyser = (filename) => {
//读取文件
const content = fs.readFileSync(filename, 'utf-8')
const ast = parser.parse(content, {
sourceType: 'module'
})
const dependencies = {}
//对代码分析
//对ast遍历
traverse(ast, {
ImportDeclaration({node}) {
const dirname = path.dirname(filename)
const newFile = './' + path.join(dirname, node.source.value)
dependencies[node.source.value] = newFile
}
})
//能在浏览器上运行的模块代码
const {code} = babel.transformFromAst(ast, null, {
presets: ["@babel/preset-env"] //es6 => es5
})
console.log(code)
//分析出入口文件和依赖和代码
return {
filename,
dependencies
code
}
}
//对index.js进行分析
moduleAnalyser('./src/index.js')
运行node bundler.js | highlight:
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
"use strict";
var _message = require("./message.js");
console.log(_message.message);
//...
//分析出入口文件和依赖和代码
return {
filename,
dependencies,
code
}
}
//对index.js进行分析
const moduleInfo = moduleAnalyser('./src/index.js')
console.log(moduleInfo)
运行node bundler.js | highlight:
katedeMacBook-Air:bundler kate$ node bundler.js | highlight
{ filename: './src/index.js',
dependencies: { './message.js': './src/message.js' },
code:
'"use strict";\n\nvar _message = require("./message.js");\n\nconsole.log(_message.message);' }