今天学习一个简单的类似webpack
的bundler
。可以了解webpack的底层打包原理
创建文件夹
(1)bundler/src/indes.js
(2)bundler/src/message.js (引用3后返回以一个字符串)
(3)bundler/src/word.js (定义一个字符串)
(2)引入(3),使用import
浏览器不支持import 语法,我们需要支持这个功能
开始创建模拟一个webpack工具
1、首先要分析入口文件
const moduleAnalyser = (filename)=>{
}
// 传入文件
moduleAnalyser ('./src/index.js')
要想分析内容要拿到文件的内容
const fs = require(‘fs’)// 可以获取到文件的信息
const result = fs.readFileSync(filename,'utf-8')
console.log(result)
打印出来特别丑,全黑。使用cli-highlight -g
美化打包结果
运行 node xx.js | hightlight 管道运算符
打印的文件中有需要获取的引入的文件的依赖
(1)使用字符串切割,多个的时候会很麻烦
(2)引入个模块npm install @babel/parser
,可以帮助分析源代码(babel7的工具)
const parser = require('babel/parser')
const fs = require('fs')// 可以获取到文件的信息
const parser = require('@babel/parser')
// 这个函数帮助我们分析文件
const mouduleAnalyser = (filename) =>{
//借助fs 读取到filename的文件,读取的内容utf-8
const content = fs.readFileSync(filename,'utf-8')
const parseContent = parser.parse(content, { sourceType: 'module' })
console.log(parseContent)
}
mouduleAnalyser('./src/index.js')
打印出了一个js对象,叫做node 的抽象语法树。可以很好的表述当前代码。
body中内容
想要分析一下body
中的节点,可以采取遍历的方法,去找到 type=importDeclaration
的节点文件的依赖,但是比较麻烦。有更好的方法,
使用npm install @babel/traverse
// 默认导出的是esmodule。想用exportdefault,就要引入加个default
const traverse = require('@babel/traverse').default
traverse( parseContent, {
ImportDeclaration({node}) {
console.log(node) // 仅包含ImportDeclaration
}
})
通过traverse
可以获取到节点,使用数组收集引入文件的路径依赖,
以上获取的依赖是相对路径,我们期望的是绝对路径
或相对bundler的相对路径
解决办法是;
const newFileName = path.posix.join( dirName, node.source.value )
数组中存的是绝对路径,没有相对路径处理起来也会很麻烦。(我也不太清楚哪里麻烦,没有尝试)
最好的解决办法是相对路径和绝对路径都保存,这样在后面处理时最方便
如此,找到了入口文件依赖文件。接下来我们要拿到依赖文件的代码,打包成esmodule格式
引入@babel/core
, 安装@babel/preset-env
使用transformFromAst 可以转化抽象语法树,转换成浏览器可以运行的代码
const { code } = babel.transformFromAst(ast, null., {
presets : ['@babel/preset-env]'
})