webpack面试题

常见loader

 在webpack5之后,我们可以直接使用资源模块类型(asset module type),来替代url-loader、file-loader;

常见plugin 

webpack的工作流程 

webpack的工作流程是一个串行的过程,从启动到结束会依次执行下面的步骤

1.初始化参数:从命令行或者配置文件中获取参数,得到最终的配置对象

        这一步由webpack-cli来操作它的本质就是将所有的配置参数进行合并

2.开始编译:从上一步得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法开始执行编译

执行compile方法的时候会实例化一个compilation对象 

3.确定入口:根据配置中的entry找到所有的入口文件,从入口文件出发,调用所有配置文件的loader对模块进行编译,

4.并找出模块依赖的模块,再递归本步骤直到所有的入口文件依赖的模块都执行了此步骤(是通过AST对模块的源代码进行解析找到require表达式分析出所依赖的文件路径)

5.输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk(每个入口对应一个chunk,一个chunk对应多个模块),再把每个chunk转换成一个单独的文件加入到输出列表中(assets中属性是文件名,值是文件内容)

6.输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件写入到文件系统中

在以上过程中,webpack会在特定的时间点执行对应的插件

2.AST:

webpack的核心通过JavaScript Parser把代码转化为一颗抽象语法树(AST),这颗树定义了代码的结构,然后对AST进行遍历修改之后,然后再将AST变成修改后的代码

AST:抽象语法树

loader的执行顺序

loader可能有两部分组成一个是pitch一个是normal

相同优先级的情况下pitchLoader的执行顺序是从前往后,normalLoader的执行顺序是从后往前

可以在规则里面设置enforce属性设置pre或者post来改变他们的执行的优先级顺序

优先级为pre>normal>inline>post

总结:loader的执行顺序是先从右向左 在从左向右执行

原理:具体实现在loader-runner的库里面的runLoader方法里面

先去执行IteratePitchingLoader 在执行迭代pitchLoader的时候有将loaderIndex进行++的操作,处理完所有的pitch就会去处理文件,然后在迭代normalLoader的在迭代normalLoader的时候是根据这个loaderIndex取出当前loader执行然后把loaderindex进行--的操作

 note如果有一个pitchloader有返回值则将loaderIndex--,去迭代执行normalLoader

 

 webpack的babel的原理

https://blog.csdn.net/qq_33207292/article/details/122507786

webpack如何优化

一:优化构建速度:

  1. 配置别名alias
  2. 配置扩展名extensions、
  3. 缩小范围使用exclude、
  4. 使用cdn(在生产环境中第三方库使用cdn引入 (webpack不会对cdn资源进行打包))
  5. 利用缓存

       babel-loader 开启缓存

       babel 在转译 js 过程中时间开销比价大,将 babel-loader 的执行结果缓存起来,重新打包的时候,直接读取缓存

    其他loader编译后的用cache-loader进行缓存 

二、优化运行时体验

运行时优化的核心就是提升首屏的加载速度,主要的方式就是降低首屏加载文件体积,首屏不需要的文件进行预加载或者按需加载

  1. 代码懒加载
  2. 可以通过魔法注释的方式用prefetch 与 preload

    prefetch是在浏览器闲置的情况下才会下载资源、preload是在父文件加载时,以并行方式开始加载该文件

三、 优化构建结果 

  1. 压缩csscss-minimizer-webpack-plugin
  2. 清除无用css:purgecss-webpack-plugin
  3. 压缩js、terser-webpack-plugin
  4. Tree-shaking

Compiler和Compilation的区别:

Compiler是在webpack构建之初就会创建的对象它都是一个独一无二,并且在webpack整个生命周期都会存在

它有以下主要属性:

compiler.options 可以访问本次启动 webpack 时候所有的配置文件,包括但不限于 loaders 、entry 、output 、plugin 等等完整配置信息

compiler.inputFileSystem 和 compiler.outputFileSystem 可以进行文件操作,相当于 Nodejs 中 fs

compiler.hooks 可以注册 tapable 的不同种类 Hook,从而可以在 compiler 生命周期中植入不同的逻辑

Compilation ,每次资源变化都会生成新的compilation对象

它会对构建依赖图中所有模块,进行编译。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)

Compilation是准备编译模块的时候才会创建的对象

它有以下主要属性:

compilation.modules :可以访问所有模块,打包的每一个文件都是一个模块。

compilation.chunks:chunk 即是多个 modules 组成而来的一个代码块。入口文件引入的资源组成一个 chunk,通过代码分割的模块又是另外的 chunk

compilation.assets:可以访问本次打包生成所有文件的结果。

compilation.hooks:可以注册 tapable 的不同种类 Hook,用于在 compilation 编译模块阶段进行逻辑添加以及修改

自定义loader

loader本质是一个函数然后loader runner库(是一个执行loader链条的模块)会调用这个函数,然后将上一个loader产生的结果或者资源文件传入进去,返回一个buffer格式的数据或者JavaScript语法的字符串如果返回多个值可以调用this.callback方法。

自定义plugin

    自定义插件我们需要知道Tapable这个模块,它是webpack的一个非常重要的核心模块,Tapable提供了许多钩子(hooks),这些钩子会被应用到插件中,这样开发者就可以通过注册插件来修改Webpack的行为,从而实现各种功能。webpack 在编译代码过程中,会触发一系列 Tapable 钩子事件,插件所做的,就是找到相应的钩子,往上面挂上自己的任务,也就是注册事件,这样当 webpack 构建的时候,会适时的触发相应的钩子,因此也就触发了插件的方法。

    插件可以是一个类也可以是一个函数,但是大部分情况下都是一个类

    如果插件是一个类需要在类的prototype 上定义一个 apply 方法,接受一个webpack compiler对象的引用。 compiler上有很多钩子比如afterEmit(等资源输出到output文件中后执行),在apply方法里面去监听(订阅)这些钩子,在webpack的工作流中通过call去发布这些钩子

实现CleanWebpackPlugin:

 

 实现AnalyzeWebpackPlugin

vite

 在开发环境下基于浏览器原生 ES module开发,将代码通过esbuild构建成es module。在生产环境下基于 Rollup 打包。

vite的优点是不需要自己配置loader

Vite 天然支持引入 .ts  .css文件。

快的原因:使用了ESBuild构建工具、进行预打包(对一些node_module里面的模块)

vite的原理

vite会建立一个本地服务器使用的是Connect搭建的服务器,浏览器去请求ts、less这些资源的时候,本地的服务器会进行拦截,然后对这些请求进行转发,返回给浏览器的资源是vite构建后的es module js代码,这些代码浏览器是可以识别的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值