前端常见面试题-2025

vue4.0

Vue.js 4.0 是在 2021 年 9 月发布。Vue.js 4.0 是 Vue.js 的一个重要版本,引入了许多新特性和改进,旨在提升开发者的体验和性能。以下是一些关键的更新和新特性:

  1. Composition API 重构:Vue 3 引入了 Composition API 作为官方推荐的 API 风格,而 Vue 4.0 在此基础上进一步优化和扩展了 Composition API,使其更加灵活和强大。

  2. 更好的 TypeScript 支持:Vue 4.0 提供了更完善的 TypeScript 支持,帮助开发者更容易地利用 TypeScript 进行 Vue 开发。

  3. 性能改进:通过优化内部机制,Vue 4.0 在渲染性能和响应性系统上有了显著提升,尤其是在处理大型应用时。

  4. 新的编译器优化:引入了更先进的编译器优化技术,使得模板编译速度更快,生成的代码更加优化。

  5. 更好的跨框架集成:Vue 4.0 加强了与其他前端框架和库的集成能力,例如更好地与 React 和 Angular 等框架互操作。

  6. 新的 CLI 和 Vite 支持:Vue CLI 和 Vite 都得到了更新和改进,支持 Vue 4.0 的新特性和最佳实践。

  7. 生态系统更新:Vue Router、Vuex 等生态系统项目也相应地更新了以支持 Vue 4.0 的新特性和改进。

Vite的原理

Vite 是一个现代化的前端构建工具,由 Vue.js 的作者尤雨溪开发。它旨在提供更快的开发体验和更高效的构建流程。Vite 的核心原理基于 ES Modules (ESM) 和现代浏览器的原生支持,与传统的打包工具(如 Webpack)有显著的区别。

Vite 的核心原理

1. 基于 ES Modules 的开发服务器

Vite 的核心思想是利用现代浏览器对 ES Modules (ESM) 的原生支持,直接在浏览器中运行未打包的代码。

  • 传统工具的问题:

    • Webpack 等工具在开发模式下需要将所有模块打包成一个或多个 bundle 文件。

    • 随着项目规模增大,打包时间会显著增加,尤其是在启动开发服务器时。

  • Vite 的解决方案:

    • Vite 在开发模式下不打包代码,而是直接利用浏览器的 ESM 支持,按需加载模块。

    • 当浏览器请求一个模块时,Vite 会动态地将模块转换为浏览器可识别的 ESM 格式,并返回给浏览器。

    • 这种方式避免了打包的开销,极大地提升了开发服务器的启动速度。

示例:
假设有以下代码:

// main.js
import { greet } from './utils.js';greet('Vite');// utils.js
export function greet(name) {console.log(`Hello, ${name}!`);
}

在传统工具中,Webpack 会将 main.js 和 utils.js 打包成一个文件。

在 Vite 中,浏览器会直接加载 main.js,然后通过 ESM 动态加载 utils.js。

2. 按需编译

Vite 采用按需编译的方式,只有在浏览器请求某个模块时,才会对该模块进行编译。

  • 传统工具的问题:

    • Webpack 等工具在启动时需要对整个项目进行打包和编译,即使某些模块在初始加载时并不需要。
  • Vite 的解决方案:

    • Vite 启动时只编译项目的入口文件(如 index.html),其他模块按需编译。

    • 当浏览器请求某个模块时,Vite 会动态编译该模块并返回结果。

    • 这种方式减少了初始编译时间,特别适合大型项目。

热更新(HMR)机制

Vite 的热更新机制(Hot Module Replacement)非常高效,基于 ESM 的特性实现。

  • 传统工具的问题:

    • Webpack 的热更新需要重新构建整个模块依赖图,并将更新的模块推送到浏览器。

    • 随着项目规模增大,热更新的速度会变慢。

  • Vite 的解决方案:

    • Vite 利用 ESM 的特性,只更新修改的模块及其依赖。

    • 当某个模块发生变化时,Vite 会通过 WebSocket 通知浏览器,浏览器只需要重新加载更新的模块,而不需要刷新整个页面。

    • 这种方式使得热更新的速度非常快,几乎感觉不到延迟。

示例:
修改 utils.js 中的 greet 函数:

export function greet(name) {console.log(`Hi, ${name}!`);
}

Vite 会通知浏览器重新加载 utils.js,而不影响其他模块。

4. 生产环境的构建

在开发模式下,Vite 利用 ESM 和按需编译实现了极快的启动速度。但在生产环境中,Vite 仍然会使用 Rollup 进行打包。

  • Rollup 的优势:

    • Rollup 是一个基于 ESM 的打包工具,生成的代码更小、更高效。

    • Vite 在生产环境中使用 Rollup 打包,确保代码的性能和兼容性。

  • 与传统工具的区别:

    • Webpack 在开发和生产环境中都使用相同的打包机制。

    • Vite 在开发和生产环境中采用不同的策略,开发模式下不打包,生产模式下使用 Rollup 打包。

在这里插入图片描述

Vite 的优势

  1. 极快的启动速度:

    由于不需要打包,Vite 的启动速度非常快,特别适合大型项目。

  2. 高效的热更新:

    基于 ESM 的热更新机制,更新速度极快。

  3. 开箱即用的现代前端支持:

    原生支持 TypeScript、JSX、CSS Modules 等现代前端特性。

  4. 灵活的插件系统:

    Vite 的插件系统基于 Rollup,兼容 Rollup 插件,同时提供了 Vite 特有的插件 API。

  5. 生产环境优化:

    使用 Rollup 进行打包,生成的代码更小、更高效。

Vite 的适用场景

现代前端项目:Vite 非常适合基于 Vue、React、Svelte 等现代框架的项目。大型项目:Vite 的按需编译和热更新机制特别适合大型项目。快速原型开发:Vite 的极快启动速度非常适合快速原型开发。

总结:
Vite 通过利用现代浏览器的 ESM 支持,实现了按需编译和极快的开发体验。与传统的打包工具相比,Vite 在开发模式下不打包代码,而是直接利用浏览器的模块加载机制,极大地提升了开发效率。在生产环境中,Vite 使用 Rollup 进行打包,确保代码的性能和兼容性。Vite 的出现标志着前端构建工具的一次重大革新,特别适合现代前端开发的需求。

webpack-现代前端开发中最主流的模块打包工具之一

1. Webpack 是什么?

Webpack 是一个静态模块打包工具,主要用于将前端项目中的各种资源(如 JavaScript、CSS、图片、字体等)打包成一个或多个 bundle 文件。它的核心功能包括:

模块化支持:支持 CommonJS、ES Modules、AMD 等多种模块化规范。资源打包:将各种类型的资源(如 JS、CSS、图片等)视为模块,并打包到最终的输出文件中。代码分割:支持按需加载和代码分割,优化加载性能。插件和加载器:通过插件和加载器扩展功能,支持 TypeScript、Sass、Less 等非原生资源。

2. Webpack 的核心概念

(1)Entry(入口)

  • 入口是 Webpack 构建的起点,Webpack 会从入口文件开始递归解析依赖。

  • 可以配置单个或多个入口。

  • 示例:

    module.exports = {entry: './src/index.js',
    };
    

(2)Output(输出)

  • 输出配置指定打包后的文件存放位置和文件名。

  • 示例:

    module.exports = {output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',},
    };
    

(3)Loader(加载器)

  • Loader 用于处理非 JavaScript 文件(如 CSS、图片、字体等),将其转换为 Webpack 可以处理的模块。

  • 常见的 Loader:

    • babel-loader:将 ES6+ 代码转换为 ES5。

    • css-loader:处理 CSS 文件。

    • style-loader:将 CSS 插入到 DOM 中。

    • file-loader:处理文件(如图片、字体)。

  • 示例:

    module.exports = {module: {rules: [{test: /\.css$/,use: ['style-loader', 'css-loader'],},],},
    };
    

(4)Plugin(插件)

  • 插件用于扩展 Webpack 的功能,例如打包优化、资源管理、环境变量注入等。

  • 常见的插件:

    • HtmlWebpackPlugin:自动生成 HTML 文件并注入打包后的资源。

    • CleanWebpackPlugin:清理构建目录。

    • MiniCssExtractPlugin:将 CSS 提取到单独的文件中。

  • 示例:

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
    };
    

(5)Mode(模式)

  • Webpack 支持三种模式:development、production 和 none。

  • 不同模式会启用不同的优化策略。

  • 示例:

    module.exports = {mode: 'production',
    };
    

(6)Module(模块)

  • Webpack 将所有文件视为模块,通过 Loader 处理不同类型的模块。

(7)Chunk(代码块)

  • Chunk 是 Webpack 打包过程中的中间产物,通常对应一个或多个模块。

  • 通过代码分割(Code Splitting)可以将代码拆分成多个 Chunk,实现按需加载。

3. Webpack 的工作原理

Webpack 的打包过程可以分为以下几个步骤:

  1. 解析入口文件:从配置的入口文件开始,递归解析依赖。

  2. 构建依赖图:根据模块之间的依赖关系,构建一个依赖图。

  3. 加载模块:使用 Loader 处理非 JavaScript 模块。

  4. 应用插件:在打包过程中执行插件的逻辑。

  5. 生成 Chunk:根据依赖图生成一个或多个 Chunk。

  6. 输出文件:将 Chunk 写入到配置的输出目录中。

4. Webpack 的优化

(1)代码分割(Code Splitting)

  • 通过 SplitChunksPlugin 或动态导入(import())将代码拆分成多个 Chunk,实现按需加载。

  • 示例:

    import('./module').then((module) => {module.default();
    });
    

(2)Tree Shaking

  • 移除未使用的代码(Dead Code),减少打包体积。

  • 需要启用 ES Modules 并配置 mode: ‘production’。

(3)缓存

  • 使用 cache 配置或 HardSourceWebpackPlugin 缓存构建结果,提升构建速度。

(4)压缩代码

  • 使用 TerserWebpackPlugin 压缩 JavaScript 代码。

  • 使用 CssMinimizerWebpackPlugin 压缩 CSS 代码。

(5)懒加载

  • 通过动态导入实现懒加载,减少初始加载时间。

5. Webpack 与其他工具的区别

(1)Webpack vs Vite

  • Webpack:

    • 开发模式下需要打包所有模块,启动速度较慢。

    • 适合复杂项目和需要兼容旧浏览器的场景。

  • Vite:

    • 开发模式下基于 ESM 按需加载,启动速度极快。

    • 适合现代前端项目和快速开发。

(2)Webpack vs Rollup

  • Webpack:

    • 适合应用开发,支持代码分割、懒加载等功能。
  • Rollup:

    • 适合库开发,生成的代码更小、更高效。

(3)Webpack vs Parcel

  • Webpack:

    • 配置灵活,功能强大,但配置复杂。
  • Parcel:

    • 零配置,开箱即用,适合简单项目。

6. Webpack 的常见问题

(1)如何优化 Webpack 的构建速度?

  • 使用 cache 配置缓存构建结果。

  • 使用 DllPlugin 预编译不常变化的模块。

  • 减少 Loader 和插件的使用范围。

(2)如何解决 Webpack 打包体积过大的问题?

  • 使用 Tree Shaking 移除未使用的代码。

  • 使用代码分割和懒加载。

  • 压缩代码和资源。

(3)Webpack 如何处理 CSS 文件?

  • 使用 css-loader 解析 CSS 文件。

  • 使用 style-loader 将 CSS 插入到 DOM 中。

  • 使用 MiniCssExtractPlugin 将 CSS 提取到单独的文件中。

总结:
Webpack 是一个功能强大的模块打包工具,通过 Loader 和插件支持多种资源类型和优化策略。它的核心概念包括 Entry、Output、Loader、Plugin 和 Mode。Webpack 的优化手段包括代码分割、Tree Shaking、缓存和懒加载等。与 Vite、Rollup 和 Parcel 相比,Webpack 更适合复杂项目和需要兼容旧浏览器的场景。

Turbopack

Turbopack 是一个新兴的前端构建工具,由 Vercel 团队开发,旨在提供比现有工具(如 Webpack 和 Vite)更快的构建速度和开发体验。Turbopack 是基于 Rust 编写的,利用了现代编程语言的高性能和并发能力,专注于解决大规模前端项目的构建性能问题。

1. Turbopack 的核心特点

(1)基于 Rust 的高性能

  • Turbopack 使用 Rust 编写,Rust 是一种高性能、内存安全的系统编程语言。

  • 与 JavaScript 相比,Rust 的执行速度更快,尤其是在 CPU 密集型任务(如模块解析和打包)中表现优异。

(2)增量编译

  • Turbopack 采用增量编译机制,只重新编译发生变化的模块,而不是整个项目。

  • 这种机制显著减少了构建时间,特别适合大型项目。

(3)按需编译

  • 类似于 Vite,Turbopack 在开发模式下按需编译模块,只有在浏览器请求某个模块时才会进行编译。

  • 这种方式避免了不必要的编译工作,提升了开发服务器的启动速度。

(4)兼容 Webpack 生态

  • Turbopack 兼容 Webpack 的配置和插件生态,可以平滑迁移现有项目。

  • 这意味着开发者可以继续使用熟悉的 Webpack 插件和 Loader。

(5)支持多种框架

  • Turbopack 支持 React、Next.js、Vue、Svelte 等主流前端框架。

  • 它与 Next.js 深度集成,是 Next.js 13 的默认构建工具。

2. Turbopack 的工作原理

(1)模块图(Module Graph)

  • Turbopack 通过构建模块图来管理项目中的模块依赖关系。

  • 模块图是增量更新的,只有发生变化的模块及其依赖会被重新编译。

(2)缓存机制

  • Turbopack 使用高效的缓存机制来存储编译结果。

  • 在重新构建时,Turbopack 会优先使用缓存,避免重复编译。

(3)并发处理

  • Turbopack 利用 Rust 的并发能力,并行处理多个模块的编译任务。

  • 这种并发机制进一步提升了构建速度。

(4)开发模式与生产模式

  • 开发模式:按需编译,启动速度快,支持热更新(HMR)。

  • 生产模式:全量打包,生成优化的静态资源。

3. Turbopack 的优势

(1)极快的构建速度

  • Turbopack 的构建速度比 Webpack 快得多,尤其是在大型项目中。

  • 根据 Vercel 的基准测试,Turbopack 的启动速度比 Webpack 快 10 倍以上。

(2)更好的开发体验

  • 按需编译和增量编译机制使得开发服务器的启动和热更新速度更快。

  • 开发者可以更快地看到代码更改的效果。

(3)兼容现有生态

  • Turbopack 兼容 Webpack 的配置和插件,降低了迁移成本。

  • 开发者可以逐步迁移现有项目,而不需要重写所有配置。

(4)专注于大规模项目

  • Turbopack 的设计目标是为大规模前端项目提供高效的构建解决方案。

  • 它特别适合需要处理大量模块和复杂依赖关系的项目。

**加粗样式
**

5. Turbopack 的使用场景

(1)大型前端项目

  • Turbopack 的增量编译和高效缓存机制特别适合处理大规模项目。

(2)Next.js 项目

  • Turbopack 是 Next.js 13 的默认构建工具,与 Next.js 深度集成。

(3)需要快速开发体验的项目

  • 对于需要快速启动和热更新的项目,Turbopack 提供了极佳的开发体验。

6. Turbopack 的局限性

(1)生态尚不成熟

  • 虽然 Turbopack 兼容 Webpack 生态,但其自身的插件和工具生态还在发展中。

(2)学习成本

  • 对于熟悉 Webpack 的开发者来说,Turbopack 的学习成本较低,但仍需要了解其独特的配置和优化方式。

(3)生产环境优化

  • Turbopack 在生产环境中的优化策略仍在不断完善,可能不如 Webpack 成熟。

7. 如何开始使用 Turbopack

(1)在 Next.js 中使用

  • Next.js 13 默认集成了 Turbopack,只需升级到最新版本即可使用。

(2)独立使用

  • Turbopack 也可以独立使用,但目前文档和工具链还在完善中。

总结:
Turbopack 是一个基于 Rust 的高性能前端构建工具,专注于提升大规模项目的构建速度和开发体验。它通过增量编译、按需编译和高效的缓存机制,显著减少了构建时间。Turbopack 兼容 Webpack 生态,特别适合大型项目和 Next.js 应用。尽管其生态尚不成熟,但 Turbopack 代表了前端构建工具的未来发展方向,值得开发者关注和尝试。

TypeScript

1. TypeScript 是什么?

TypeScript 是 JavaScript 的一个超集,由微软开发。它在 JavaScript 的基础上添加了静态类型检查和面向对象编程的特性,主要特点包括:

  • 静态类型检查:在编译时检查类型错误,提升代码的健壮性。

  • 类型推断:自动推断变量类型,减少手动类型注解的工作量。

  • 面向对象编程:支持类、接口、泛型等高级特性。

  • 兼容 JavaScript:TypeScript 是 JavaScript 的超集,任何合法的 JavaScript 代码都是合法的 TypeScript 代码。

2. TypeScript 的优势

(1)类型安全

  • 静态类型检查可以在编译时发现潜在的错误,减少运行时错误。

  • 示例:

    function add(a: number, b: number): number {return a + b;
    }
    add(1, '2'); // 编译时报错:Argument of type 'string' is not assignable to parameter of type 'number'.
    

(2)更好的代码可维护性

  • 类型注解和接口定义使代码更易读、易懂。

  • 示例:

    interface User {name: string;age: number;
    }function greet(user: User): string {return `Hello, ${user.name}!`;
    }
    

(3)增强的开发体验

  • 现代编辑器(如 VSCode)对 TypeScript 提供了强大的支持,包括代码补全、类型提示、重构等功能。

(4)渐进式采用

  • 可以在现有 JavaScript 项目中逐步引入 TypeScript,无需重写整个项目。

3. TypeScript 的核心概念

(1)基础类型

  • TypeScript 支持 JavaScript 的所有基础类型(如 number、string、boolean 等),并扩展了一些类型(如 any、unknown、void、never 等)。

  • 示例:

    let num: number = 42;
    let str: string = 'Hello';
    let isDone: boolean = false;
    

(2)联合类型和交叉类型

  • 联合类型:表示一个值可以是多种类型之一。

    let value: string | number;
    value = 'Hello'; // OK
    value = 42; // OK
    
  • 交叉类型:表示一个值必须同时满足多种类型。

    interface A {a: string;
    }
    interface B {b: number;
    }
    type C = A & B;
    let obj: C = { a: 'Hello', b: 42 };
    

(3)接口和类型别名

  • 接口(Interface):用于定义对象的形状。

    interface User {name: string;age: number;
    }
    
  • 类型别名(Type Alias):可以为类型定义一个别名。

    type Point = {x: number;y: number;
    };
    

(4)泛型

  • 泛型用于创建可重用的组件,支持多种类型。

  • 示例:

    function identity<T>(arg: T): T {return arg;
    }
    let output = identity<string>('Hello');
    

(5)类

  • TypeScript 支持面向对象编程,包括类、继承、修饰符等。

  • 示例:

    class Animal {name: string;constructor(name: string) {this.name = name;}move(distance: number = 0) {console.log(`${this.name} moved ${distance}m.`);}
    }
    

(6)装饰器

  • 装饰器是一种特殊类型的声明,用于附加到类、方法、属性或参数上。

  • 示例:

    function log(target: any, key: string) {console.log(`Method ${key} called.`);
    }class MyClass {@logmyMethod() {console.log('Hello');}
    }
    

4. TypeScript 的常见问题

(1)TypeScript 和 JavaScript 的区别

  • TypeScript 是 JavaScript 的超集,添加了静态类型检查和面向对象特性。

  • TypeScript 需要编译为 JavaScript 才能运行。

(2)any 和 unknown 的区别

  • any:禁用类型检查,可以赋值给任何类型。

  • unknown:类型安全的 any,不能直接赋值给其他类型,需要先进行类型检查。

(3)interface 和 type 的区别

  • interface:主要用于定义对象的形状,支持扩展和合并。

  • type:更通用,可以定义任何类型,不支持合并。

(4)如何实现类型守卫

  • 类型守卫用于在运行时检查类型,常见的方式包括 typeof、instanceof 和自定义类型谓词。

  • 示例:

    function isString(value: any): value is string {return typeof value === 'string';
    }
    

5. TypeScript 的面试高频问题

(1)什么是泛型?如何使用泛型?

  • 泛型用于创建可重用的组件,支持多种类型。

  • 示例:

    function identity<T>(arg: T): T {return arg;
    }
    

(2)如何定义一个可选属性?

  • 使用 ? 定义可选属性。

  • 示例:

    interface User {name: string;age?: number;
    }
    

(3)如何实现函数重载?

  • 通过定义多个函数签名实现函数重载。

  • 示例:

    function add(a: number, b: number): number;
    function add(a: string, b: string): string;
    function add(a: any, b: any): any {return a + b;
    }
    

(4)如何定义一个只读属性?

  • 使用 readonly 修饰符定义只读属性。

  • 示例:

    interface Point {readonly x: number;readonly y: number;
    }
    

(5)如何处理第三方库的类型定义?

  • 使用 DefinitelyTyped 提供的类型定义文件(@types 包)。

  • 示例:

    npm install --save-dev @types/lodash
    

总结:
TypeScript 是前端开发中的重要工具,通过静态类型检查和面向对象特性提升了代码的健壮性和可维护性。掌握 TypeScript 的核心概念(如类型、接口、泛型、类等)以及常见问题的解决方法,是面试中的关键。在实际项目中,TypeScript 可以帮助开发者更高效地编写和维护代码,特别适合中大型项目。

AST的应用

AST(Abstract Syntax Tree,抽象语法树) 是编程语言中源代码的树状表示形式。它将代码解析为树结构,每个节点代表代码中的一个语法结构(如表达式、语句、变量等)。AST 在前端开发中有广泛的应用,尤其是在代码分析、转换和优化方面。

1. AST 的基本概念

(1)什么是 AST?

  • AST 是源代码的抽象语法结构的树状表示。

  • 它将代码解析为树结构,每个节点代表代码中的一个语法单元。

  • 示例:

    const a = 1 + 2;
    

对应的 AST 可能如下json文件:

```
{"type": "VariableDeclaration","declarations": [{"type": "VariableDeclarator","id": { "type": "Identifier", "name": "a" },"init": {"type": "BinaryExpression","operator": "+","left": { "type": "Literal", "value": 1 },"right": { "type": "Literal", "value": 2 }}}],"kind": "const"
}
```

(2)AST 的生成过程

    1. 词法分析(Lexical Analysis):将源代码分解为一个个 Token(如关键字、标识符、运算符等)。
    1. 语法分析(Syntax Analysis):根据语法规则将 Token 组合成 AST。

2. AST 的应用场景

(1)代码编译和转译

  • Babel:将 ES6+ 代码转换为 ES5 代码。

  • Babel 使用 AST 解析代码,然后通过插件对 AST 进行转换,最后生成目标代码。

  • 示例:将箭头函数转换为普通函数。

    // 转换前
    const add = (a, b) => a + b;// 转换后
    const add = function(a, b) {return a + b;
    };
    
  • TypeScript 编译器:将 TypeScript 代码转换为 JavaScript 代码。

(2)代码格式化

  • Prettier:通过解析代码生成 AST,然后根据规则重新生成格式化的代码。

  • 示例:统一代码缩进、换行等。

(3)代码静态分析

  • ESLint:通过 AST 分析代码,检查潜在的错误或不符合规范的代码。

  • 示例:检查未使用的变量、不推荐的语法等。

    // ESLint 规则:禁止使用 var
    var a = 1; // 报错:Use 'let' or 'const' instead of 'var'.
    

(4)代码优化

  • Webpack:通过 AST 分析代码依赖关系,进行 Tree Shaking(移除未使用的代码)。

  • 示例:移除未使用的模块。

    // 未使用的模块
    import { unusedFunction } from './utils';// Tree Shaking 后
    // unusedFunction 被移除
    

(5)代码生成

  • 代码生成工具:根据 AST 生成目标代码。

  • 示例:根据模板生成代码。

    // 模板
    function {{name}}({{params}}) {return {{body}};
    }// 生成代码
    function add(a, b) {return a + b;
    }
    

(6)代码高亮和语法检查

  • 编辑器插件:通过 AST 实现代码高亮、语法检查和自动补全。

    • 示例:VSCode 的 TypeScript 插件。

3. AST 的操作工具

(1)JavaScript 的 AST 工具

  • Babel:

    • @babel/parser:将代码解析为 AST。

    • @babel/traverse:遍历和修改 AST。

    • @babel/generator:将 AST 转换为代码。

  • ESLint:

    • 提供 API 用于自定义规则和代码分析。
  • Acorn:

    • 一个轻量级的 JavaScript 解析器,用于生成 AST。

(2)TypeScript 的 AST 工具

  • TypeScript 编译器 API:

    • 提供完整的 AST 解析和操作功能。
  • ts-morph:

    • 一个基于 TypeScript 编译器 API 的高级工具库,简化了 AST 的操作。

4. AST 的实际应用示例

(1)使用 Babel 转换箭头函数

```
const babel = require('@babel/core');const code = 'const add = (a, b) => a + b;';// 解析代码生成 AST
const ast = babel.parseSync(code, {presets: ['@babel/preset-env'],
});// 遍历和修改 AST
babel.traverse(ast, {ArrowFunctionExpression(path) {path.replaceWith(babel.types.functionExpression(null,path.node.params,babel.types.blockStatement([babel.types.returnStatement(path.node.body),])));},
});// 生成目标代码
const output = babel.transformFromAstSync(ast);
console.log(output.code);
// 输出:const add = function(a, b) { return a + b; };
```

(2)使用 ESLint 自定义规则

```
module.exports = {meta: {type: 'suggestion',docs: {description: '禁止使用 console.log',},},create(context) {return {CallExpression(node) {if (node.callee.object &&node.callee.object.name === 'console' &&node.callee.property.name === 'log') {context.report({node,message: '禁止使用 console.log',});}},};},
};
```

5. AST 的面试高频问题

(1)什么是 AST?

  • AST 是源代码的抽象语法结构的树状表示,用于代码分析、转换和优化。

(2)AST 的生成过程是什么?

  • 词法分析:将代码分解为 Token。

  • 语法分析:将 Token 组合成 AST。

(3)AST 在前端开发中的应用场景有哪些?

  • 代码编译和转译(如 Babel)。

  • 代码格式化(如 Prettier)。

  • 代码静态分析(如 ESLint)。

  • 代码优化(如 Webpack 的 Tree Shaking)。

  • 代码生成(如模板生成代码)。

(4)如何使用 Babel 操作 AST?

  • 使用 @babel/parser 解析代码生成 AST。

  • 使用 @babel/traverse 遍历和修改 AST。

  • 使用 @babel/generator 将 AST 转换为代码。

总结:
AST 是前端开发中非常重要的工具,广泛应用于代码编译、格式化、静态分析、优化和生成等场景。通过操作 AST,开发者可以实现代码的自动化处理和分析,提升开发效率和代码质量。掌握 AST 的基本概念和操作工具,是前端开发者进阶的必备技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19991.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python学opencv|读取图像(六十八)使用cv2.Canny()函数实现图像边缘检测

【1】引言 前序学习进程中&#xff0c;在对图像进行边缘识别的基础上&#xff0c;先后进行了边缘轮廓绘制&#xff0c;矩形标注、圆形标注和凸包标注。相关文章包括且不限于&#xff1a; python学opencv|读取图像&#xff08;六十四&#xff09;使用cv2.findContours()函数cv…

C语言基础16:二维数组、字符数组

二维数组 定义 二维数组本质上是一个行列式的组合&#xff0c;也就是说二维数组由行和列两部分组成。属于多维数组&#xff0c;二维数组数据是通过行列进行解读。 二维数组可被视为一个特殊的一维数组&#xff0c;相当于二维数组又是一个一维数组&#xff0c;只不过它的元素…

小爱音箱连接电脑外放之后,浏览器网页视频暂停播放后,音箱整体没声音问题解决

背景 22年买的小爱音箱增强版play&#xff0c;小爱音箱连接电脑外放之后&#xff0c;浏览器网页视频暂停播放后&#xff0c;音箱整体没声音&#xff08;一边打着游戏&#xff0c;一边听歌&#xff0c;一边放视频&#xff0c;视频一暂停&#xff0c;什么声音都没了&#xff0c;…

【做一个微信小程序】校园地图页面实现

前言 上一个教程我们实现了小程序的一些的功能&#xff0c;有背景渐变色&#xff0c;发布功能有的呢&#xff0c;已支持图片上传功能&#xff0c;表情和投票功能开发中&#xff08;请期待&#xff09;。下面是一个更高级的微信小程序实现&#xff0c;包含以下功能&#xff1a;…

使用Navicat for MySQL工具连接本地虚拟机上的MySQL

昨天在虚拟机上装了MySQL数据库&#xff0c;今天打算用Navicat for MySQL工具连下&#xff0c;结果连接不上。 使用本地Navicat for MySQL工具连接虚拟机上的MySQL数据库&#xff1a; 1.Navicat连接mysql 解决方案 1、首先使用xshell工具连上虚拟机服务器&#xff0c;输入命令&…

算法笔记 02 —— 入门模拟

本系列为胡凡编著的算法笔记当中代码部分的精简版整理&#xff0c;笔者也在同时准备Leetcode刷题和实习面试&#xff0c;希望为有一定编码和数据结构基础的同学提供一份系统型的参考&#xff0c;以方便遗忘时的算法查阅、期末复习总览以及C学习参照。 目录 01 简单模拟 Ⅰ害…

unity学习38:导入角色和动画,实测用脚本控制trigger和动作状态的转换

目录 1 资源准备&#xff1a;先从unity的 Asset store下载一些free的资源 2 在project/Asset里找到角色模型和动画 2.1 在prefab里找到角色资源 2.2 找到动画资源&#xff0c;一般在Animation下的模型文件fbx下层 2.3 准备工作 2.4 拖拽模型文件里的动作到Animator 2.5 …

Weboffice在线Word权限控制:限制编辑,只读、修订、禁止复制等

在现代企业办公中&#xff0c;文档编辑是一项常见且重要的任务。尤其是在线办公环境中&#xff0c;员工需要在网页中打开和编辑文档&#xff0c;但如何确保这些文档只能进行预览而无法被编辑或复制&#xff0c;成为许多企业面临的一个痛点。尤其是在处理涉密文档时&#xff0c;…

Endnote使用笔记——持续更新

&#xff08;1&#xff09;如果样式库里没有想要的期刊格式&#xff0c;可以到这个网址进行下载&#xff0c;并放在本地安装Endnote的文件下边的styles文件里&#xff1a; https://endnote.com/downloads/styles/ &#xff08;2&#xff09;EndNote导入参考文献时&#xff0c;关…

try learning-git-branching

文章目录 mergerebase分离 HEAD相对引用利用父节点branch -f 撤销变更cherry-pick交互式 rebase只取一个提交记录提交的技巧rebase 在上一次提交上amendcherry-pick 在上一次提交上 amend tag多分支 rebase两个parent节点纠缠不清的分支偏离的提交历史锁定的Main推送主分支合并…

Unity使用反射进行Protobuf(CS/SC)协议,json格式

protobuf生成的协议,有挺多协议的.利用反射生成dto进行伪协议的响应 和 发送请求 应用场景: 请求(CS)_后端先写完了(有proto接口了),前端还没搞完时(暂还没接入proto),后端可使用此请求,可自测 响应(SC)_可自行构建一个响应(有些特殊数据后端下发不了的),对数据进行测试 // 请…

Linux探秘坊-------8.进程详解

1.概念详解 1.运行&&阻塞&&挂起 内容基础&#xff1a;方框中的就是调度队列&#xff0c;是一个 双向队列&#xff0c;每一个元素是PCB其对应的代码数据 1.运行 只要进程 在调度队列中&#xff0c;进程的状态就是运行&#xff08;running&#xff09;. 2.阻塞…

VUE 集成高德地图部署到nginx后打开不了,控制台报错

VUE 集成高德地图部署到nginx后打开不了&#xff0c;控制台报错:xxxxxxx,because it violates the following Content Security Policy directive: “script-src ‘self’ https://webapi.amap.com ‘unsafe-inline’ ‘unsafe-eval’ blob: data:”. Note that ‘script-src-e…

解决vue-awesome-swiper 4.x + swiper 5.x 分页pagination配置不生效问题

这次给的需求需要实现几个轮播图&#xff0c;我打算用swiper来做。刚开始我参照同事之前实现的swiper&#xff0c;复制到我的新页面中&#xff0c;是可用的。但是这次的需求需要有底下的分页pagination&#xff0c;而且因为版本比较老&#xff0c;比较难找到配置项。这里说一下…

Linux中线程创建,线程退出,线程接合

线程的简单了解 之前我们了解过 task_struct 是用于描述进程的核心数据结构。它包含了一个进程的所有重要信息&#xff0c;并且在进程的生命周期内保持更新。我们想要获取进程相关信息往往从这里得到。 在Linux中&#xff0c;线程的实现方式与进程类似&#xff0c;每个线程都…

Unity Muse AIGC工具

这篇介绍unity3D的AIGC工具&#xff0c;Unity Muse&#xff0c;实现文本生成材质、动画、聊天等功能。 一、关于Unity Muse Unity Muse Unity Muse&#xff1a;利用 AI 释放您的创造潜力 | Unity 利用编辑器内置的 AI 更快地将你的想法变成现实 使用Unity Muse&#xff0c…

UART(一)——UART基础

一、定义 UART(Universal Asynchronous Receiver/Transmitter)是一种广泛使用的串行通信协议,用于在设备间通过异步方式传输数据。它无需共享时钟信号,而是依赖双方预先约定的参数(如波特率)完成通信。 功能和特点 基本的 UART 系统只需三个信号即可提供稳健的中速全双工…

【MyBatis】预编译SQL与即时SQL

目录 1. 以基本类型参数为例测试#{ }与${ }传递参数的区别 1.1 参数为Integer类型 1.2 参数为String类型 2. 使用#{ }传参存在的问题 2.1 参数为排序方式 2.2 模糊查询 3. 使用${ }传参存在的问题 3.1 SQL注入 3.2 对比#{ } 与 ${ }在SQL注入方面存在的问题 3.3 预编译…

Redis 03章——10大数据类型概述

一、which10 &#xff08;1&#xff09;一图 &#xff08;2&#xff09;提前声明 这里说的数据类型是value的数据类型&#xff0c;key的类型都是字符串 官网&#xff1a;Understand Redis data types | Docs &#xff08;3&#xff09;分别是 1.3.1redis字符串&#xff0…

Linux:线程概念、理解、控制

目录 一、认识线程 1.认识线程V1 2.认识线程V2 3.认识线程V3 4.认识线程V4 5.认识线程V5 二、线程控制 1.前言 2.创建线程 3.线程等待 4.线程终止 5.线程分离 三、线程理解 一、认识线程 1.认识线程V1 借用大多数计算机教材的话&#xff0c;线程是进程的一个执行…