** 1. webpack的作用主要就是将通过import方式引入替换为浏览器可识别的__webpack__require__, **
** 2. webpack构建的过程为,读取配置项入口,通过入口路径读取文件资源后解析为ast(抽象语法数),通过解析ast后递归处理依赖 **
1. 在配置文件添加配置项
javascript const path = require("path"); module.exports = { mode: "development", devtool: 'source-map', entry: "./src/index.js", output: { filename: "main.js", path: path.resolve(__dirname, "dist"), }, };
2. 创建文件
- 分别创建hello.js 、helloWord.js、 index.js
hello.js
javascript const hello = 'hello'; export default hello;
helloWord.js
``javascript
import hello from ‘./hello’;
const world = ‘world’;
const helloWorld = () => ${hello} ${world}
;
export default helloWorld;
index.js
javascript
import helloWorld from “./helloWorld”;
const helloWorldStr = helloWorld();
function component() {
const element = document.createElement(“div”);
element.innerHTML = helloWorldStr;
return element;
}
document.body.appendChild(component());
** 以上在index.js入口文件里引入了hello.js,helloWord.js;在下面再创建一个测试的test.js,通过执行该文件实现webpack的打包输出,ast解析等**
javascript
// node模块里的路径解析api
const path = require(‘path’);
// node模块里文件模块
const fs = require(“fs”);
// 对文件字符解析为ast依赖
const parser = require(“@babel/parser”);
// 可通过ast转换为指定的节点模式
const traverse = require(‘@babel/traverse’).default;
const t = require(“@babel/types”)
// 将ast解析生成为代码依赖
const generate = require(‘@babel/generator’).default;
const config = require(“…/webpack.config”); // 引入配置文件
// var result = parseFile(config.entry);
// console.log(“result”, result)
function parseFile(file) {
// 读取入口文件
const fileContent = fs.readFileSync(file, “utf-8”);
// 使用babel parser解析AST
const ast = parser.parse(fileContent, { sourceType: “module” });
let globimportFilePath = “”;
// 使用babel traverse来遍历ast上的节点
traverse(ast, {
ImportDeclaration§ {
// 获取被import的文件
const importFile = p.node.source.value;
// 获取文件路径
let importFilePath = path.join(path.dirname(config.entry), importFile);
importFilePath = `./${importFilePath}.js`;
globimportFilePath = importFilePath
// 构建一个变量定义的AST节点
const variableDeclaration = t.variableDeclaration("var", [
t.variableDeclarator(
t.identifier(
`__${path.basename(importFile)}__WEBPACK_IMPORTED_MODULE_0__`
),
t.callExpression(t.identifier("__webpack_require__"), [
t.stringLiteral(importFilePath),
])
),
]);
// 将当前节点替换为变量定义节点
p.replaceWith(variableDeclaration);
},
// CallExpression(p) {
// // 如果调用的是import进来的函数
// if (p.node.callee.name === importVarName) {
// // 就将它替换为转换后的函数名字
// p.node.callee.name = `${importCovertVarName}.default`;
// }
// }
});
const newCode = generate(ast).code;
// 返回一个包含必要信息的新对象
return {
file,
dependencies: [globimportFilePath],
code: newCode,
};
}
const allAst = parseFiles(config.entry);
console.log(allAst);
function parseFiles(entryFile) {
const entryRes = parseFile(entryFile); // 解析入口文件
const results = [entryRes]; // 将解析结果放入一个数组
// 循环结果数组,将它的依赖全部拿出来解析
for (const res of results) {
const dependencies = res.dependencies;
dependencies.map((dependency) => {
if (dependency) {
const ast = parseFile(dependency);
results.push(ast);
}
});
}
return results;
}
``