# 概覽
1. 找到入口文件
2. 解析入口文件, 提取它依賴的文件
3. 解析入口文件的依賴的依賴, 遞歸去創(chuàng)建一個文件間的依賴圖, 描述所有文件的依賴關(guān)系
4. 把所有文件打包成一個文件
## 開發(fā)
1. 新建幾個js文件
* name.js
* message.js
* entry.js
2. 三個文件依賴關(guān)系
entry 依賴-> message 依賴-> name
3. 創(chuàng)建一個my-webpack.js 我們在這個文件開發(fā)
4.了解幾個工具庫
* babylon 生成ast語法樹
* babel-traverse 遍歷ast語法樹
* babel-core 提取語法樹里面的代碼
5. 創(chuàng)建一個打包命令在package.json
"scripts": {
"build": "rm -rf dist.js && node my-webpack.js > dist.js"
}
const fs = require('fs')
const babylon = require('babylon')
const path = require('path')
const traverse = require('babel-traverse').default
const babel = require('babel-core')
let ID = 0
function createAsset (filename) {
const content = fs.readFileSync(filename, 'utf-8')
const ast = babylon.parse(content, {
sourceType: 'module'
})
const dependencies = []
traverse(ast, {
ImportDeclaration: ({ node }) => {
dependencies.push(node.source.value)
}
})
const id = ID++
const { code } = babel.transformFromAst(ast, null, {
presets: ['env']
})
return {
id, // 模塊唯一標(biāo)識
filename, // 模塊路徑
dependencies,// 模塊中使用的依賴
code // 模塊代碼
}
}
function createGraph (entry) {
const mainAsset = createAsset(entry)
const allAsset = [mainAsset]
for (let asset of allAsset) {
const dirname = path.dirname(asset.filename) // 獲取絕對路徑
asset.mapping = {} // 當(dāng)前文件的依賴對象, key:路徑, 值是id
asset.dependencies.forEach(relativePath => {
const absolutePath = path.join(dirname, relativePath) // 依賴文件的絕對路徑
// 獲取文件的依賴
const childAsset = createAsset(absolutePath)
asset.mapping[relativePath] = childAsset.id
allAsset.push(childAsset) // 遍歷整個依賴圖
})
}
return allAsset
}
function bundle (graph) {
let modules = ''
graph.forEach(module => {
modules += `${module.id}:[
function (require, module, exports) {
${module.code}
},
${JSON.stringify(module.mapping)}
],`
})
const result = `
(function(modules){
function require(id) {
const [fn, mapping] = modules[id]
function localRequire(relativePath) {
return require(mapping[relativePath])
}
const module = {exports:{}}
fn(localRequire, module, module.exports)
return module.exports
}
require(0)
})({${modules}})
`
return result
}
const graph = createGraph('source/entry.js')
console.log(bundle(graph))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。