前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

babel 能够做静态分析,分析代码然后得出一些信息。我们经常用的打包工具就需要通过静态分析的方式得出模块间的依赖关系,然后构造成依赖图,之后对这个依赖图做各种处理,最后输出成文件。

比如 webpack 的打包过程:从入口模块分析依赖,构造模块依赖图,然后把一些模块合并到同个分组(chunk)里,生成 chunk 依赖图,最后把 chunk 通过模版打印为 assets,输出为文件。

img

从入口模块开始,对每个模块的依赖关系的分析就是基于 AST,这种就可以用 babel parser (或者直接用 acorn)来处理。

这一节我们就来实现下依赖分析的功能,也就是遍历所有的模块。

写这个的好处一个是能够加深我们对打包工具的认识,二是当做一些独立的工具的时候,可能也需要分析模块依赖关系。

# 思路分析

模块依赖分析也就是要分析 import 和 export,从入口模块开始,读取文件内容,通过 babel parser 把内容 parse 成 ast,之后通过 babel traverse 来对 AST 进行遍历。分别对 ImportDeclaration、ExportDeclaration 做处理:

ImportDeclaration:收集 import 信息,确定依赖的模块和引入的变量,之后再递归处理该模块 ExportDeclaration:收集 export 信息,确定导出的变量

我们可以设计这样一个结构来表示每个模块的信息:

class DependencyNode {
    constructor(path = '', imports = {}, exports = []) {
        this.path = path;
        this.imports = imports;
        this.exports = exports;
        this.subModules = {};
    }
}
@前端进阶之旅: 代码已经复制到剪贴板

path 表示当前模块路径, imports 表示从什么模块引入了什么变量,exports 表示导出了什么变量。

接下来我们要完成 traverseModule 这个方法,也就是对每个模块的处理

const dependencyGraph = traverseModule(入口模块路径);
@前端进阶之旅: 代码已经复制到剪贴板

具体处理的过程就是:

  • 读取文件内容
  • 通过 babel parser 把文件内容 parse 成 ast
  • 遍历 AST,对 ImportDeclaration、ExportDeclaration 分别做处理
  • 对分析出的依赖路径进行处理,变成绝对路径,并尝试补全
  • 递归处理分析出来的依赖路径

如果没有后缀名的依赖路径,要分别尝试 .js、.jsx、.ts、.tsx 的路径,如果存在就补全成该路径,并且目录还要补全 index 文件名。

通过递归处理依赖模块,就可以完成依赖图的构建,我们可以保存根节点和所有模块的信息:

const dependencyGraph = {
    root: new DependencyNode(),
    allModules: {}
};
@前端进阶之旅: 代码已经复制到剪贴板

当处理完所有模块后,就得到了完整的 dependencyGraph。

接下来我们来写下代码。

# 代码实现

首先我们定义要返回的 dependencyGraph,

class DependencyNode {
    constructor(path = '', imports = {}, exports = []) {
        this.path 
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏