webpack3构建原理分析,ast解析

** 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. 创建文件

  1. 分别创建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.jsjavascript
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;
}
``

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值