webpack-Bundler源码编写(Dependencies Grapg)依赖图谱
之前我们分析出了分析文件(filename)的依赖和源代码,我们是对入口文件进行了分析,接下来我们要对整个工程进行分析:
bundler.js:
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 moduleAnalyser=(filename)=>{
const content=fs.readFileSync(filename,'utf-8');
const ast=parser.parse(content,{
sourceType:'module'
});
let dependencies={};
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,{ // code--浏览器可以运行的代码
presets:['@babel/preset-env']
});
return {
filename,dependencies,code
}
}
const makeDependenciesGraph=entry=>{ // entry--入口文件
const entryModule=moduleAnalyser(entry); // 入口
let graphArray=[entryModule];
// 递归分析依赖
for(let i=0;i<graphArray.length;i++){
const item=graphArray[i];
const {dependencies}=item;
if(dependencies){
for(let j in dependencies){
graphArray.push(moduleAnalyser(dependencies[j]));
}
}
}
console.log(graphArray);
}
输出:
[ { filename: './src/index.js',
dependencies: { './message.js': 'src/message.js' },
code:
'"use strict";\n\nvar _message = _interopRequireDefault(require("./message.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(_message["default"]);' },
{ filename: 'src/message.js',
dependencies: { './word.js': 'src/word.js' },
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports["default"] = void 0;\n\nvar _word = require("./word.js");\n\nvar message = "say ".concat(_word.word);\nvar _default = message;\nexports["default"] = _default;' },
{ filename: 'src/word.js',
dependencies: {},
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports.word = void 0;\nvar word = \'hello\';\nexports.word = word;' } ]
const makeDependenciesGraph=entry=>{ // entry--入口文件
const entryModule=moduleAnalyser(entry); // 入口
let graphArray=[entryModule];
// 递归分析依赖
for(let i=0;i<graphArray.length;i++){
const item=graphArray[i];
const {dependencies}=item;
if(dependencies){
for(let j in dependencies){
graphArray.push(moduleAnalyser(dependencies[j]));
}
}
}
let graph={};
graphArray.forEach(item=>{
graph[item.filename]={
dependencies:item.dependencies,
code:item.code
}
});
console.log(graph);
}
输出:
{ './src/index.js':
{ dependencies: { './message.js': 'src/message.js' },
code:
'"use strict";\n\nvar _message = _interopRequireDefault(require("./message.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(_message["default"]);' },
'src/message.js':
{ dependencies: { './word.js': 'src/word.js' },
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports["default"] = void 0;\n\nvar _word = require("./word.js");\n\nvar message = "say ".concat(_word.word);\nvar _default = message;\nexports["default"] = _default;' },
'src/word.js':
{ dependencies: {},
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports.word = void 0;\nvar word = \'hello\';\nexports.word = word;' } }
这样我们就得到了对象形式的依赖图谱

浙公网安备 33010602011771号