简单webpack打包器
const fs = require('fs')
const path = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const babel = require('@babel/core')
const config = {
entry : './entry.js',
output : './dist.js'
}
function readFile(entry){
let fileUrl = './' + path.relative(__dirname,entry).replace('\\','/');
fileUrl += path.extname(fileUrl) ? "" : '.js'
const content = fs.readFileSync(fileUrl,'utf-8');
const deps = [];
const ast = parser.parse(content);
traverse(ast,{
CallExpression:({node})=>{
if(node.callee.name === 'require'){
node.callee.name = '__webpack__require__';
let url = node.arguments[0].value;
url += path.extname(node.arguments[0].value) ? '' : '.js';
url = './' + path.relative(__dirname,url).replace('\\','/');
deps.push(url)
}
}
})
const { code } = babel.transformFromAstSync(ast)
return {
fileUrl,
deps,
code
}
}
function start({
entry,
output
}){
const entryInfo = readFile(entry);
const list = [entryInfo]
for(let prop of list){
prop.deps.forEach(item=>{
list.push(readFile(item))
})
}
fs.writeFileSync(output,build(list,entry))
}
function build(list,entry){
return `(()=>{var webpackModule = {
${
list.map(item=>{
return `
'${item.fileUrl}' : (module, exports, __webpack__require__ )=>{ eval(\`${item.code}\`) }
`
}).join(',')
}
}
const cache = {}
function __webpack__require__(moduleId){
if(cache[moduleId]){
return cache[moduleId].exports
}
var module = cache[moduleId] ={
exports : {}
}
webpackModule[moduleId](module,module.exports,__webpack__require__)
return cache[moduleId].exports
}
__webpack__require__('${entry}');
})()`
}
start(config)
打包的结果
(()=>{var webpackModule = {
'./entry.js' : (module, exports, __webpack__require__ )=>{ eval(`const a = __webpack__require__('./a.js');
console.log('a', a);`) }
,
'./a.js' : (module, exports, __webpack__require__ )=>{ eval(`const b = __webpack__require__('./src/b.js');
const a = 6666;
console.log('b', b);
module.exports = a;`) }
,
'./src/b.js' : (module, exports, __webpack__require__ )=>{ eval(`module.exports = 555;`) }
}
const cache = {}
function __webpack__require__(moduleId){
if(cache[moduleId]){
return cache[moduleId].exports
}
var module = cache[moduleId] ={
exports : {}
}
webpackModule[moduleId](module,module.exports,__webpack__require__)
return cache[moduleId].exports
}
__webpack__require__('./entry.js');
})()
目录结构
