webpack 面试题整理

Posted nuise_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack 面试题整理相关的知识,希望对你有一定的参考价值。

文章目录

webpack 面试题整理

谈谈你对Webpack的理解

1.Webpack是什么?

webpack 是一个静态模块打包器,当 webpack 处理应用程序时,会递归构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle。

webpack 就像一条生产线,要经过一系列处理流程(loader)后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能交给下一个流程去处理。
插件就像是一个插入到生产线中的一个功能,在特定的时机对生产线上的资源做处理。 webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。

2.可以说说打包过程/构建流程
3.可以说说对前端运行的优化

Webpack的打包过程/打包原理/构建流程?


webpack 的运行流程是一个串行的过程,它的工作流程就是将各个插件串联起来。

命令行执行npx webpack打包命令开始
1.初始化编译参数:从配置文件和shell命令中读取与合并参数
2.开始编译:根据上一步得到的参数初始化Compiler对象,加载所有配置的Plugin,执行对象的 run 方法开始执行编译。
3.确定入口:根据配置中的 entry 找出所有的入口文件
4.编译模块:从入口文件触发,调用所有配置的Loader对模块进行翻译,再找出该模块依赖的模块,然后递归本步骤直到所有入口依赖的文件都进行翻译。
5.完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系图。
6.输出资源:根据依赖关系图,组装成一个个包含多个模块的Chunk,再把每个Chunk转化成一个单独的文件加入到输出列表,根据配置确定输出的路径和文件名,输出。

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑。

总结

  • 初始化:从配置文件和shell命令中读取与合并参数,根据参数初始化Compiler实例,加载Plugin(注册所有配置的插件),调用Compiler实例的run方法开始执行编译。

Compiler编译对象掌控者webpack生命周期,不执行具体的任务,只是进行一些调度工作。比如执行模块创建、依赖收集、分块、打包等
调用run之后,创建Compiltation实例,每次构建都会新创建一个Compiltation实例,包含了这次构建的基本信息
Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑。

  • 编译:从entry 触发,对每个Module 串行调用对应的 Loader对模块进行翻译,再找出该模块依赖的模块,递归进行编译处理。

从配置文件( webpack.config.js )中指定的 entry 入口,开始解析文件构建 AST 语法树

  • 根据依赖关系图,组装成包含多个模块的Chunk,将个Chunk转换成文件输出。

不同entry生成不同chunk,动态导入也会生成自己的chunk

Webpack中loader的作用/ loader是什么?

Loader 是webpack中提供了一种处理多种文件格式的机制,因为webpack只认识JS和JSON,所以Loader相当于翻译官,将其他类型资源进行预处理。
用于对模块的"源代码"进行转换。
loader支持链式调用,**调用的顺序是从右往左。**链中的每个loader会处理之前已处理过的资源,最终变为js代码。
可以通过 loader 的预处理函数,为 javascript 生态系统提供更多能力。

常见的loader有哪些?

  • less-loader:将less文件编译成css文件

开发中,我们常常会使用less预处理器编写css样式,使开发效率提高

  • css-loader:将css文件变成commonjs模块加载到js中,模块内容是样式字符串
  • style-loader: 创建style标签,将js中的样式资源插入标签内,并将标签添加到head中生效
  • ts-loader: 打包编译Typescript文件

Plugin有什么作用?/Plugin是什么

Plugin功能更强大,主要目的就是解决loader 无法实现的事情,比如打包优化和代码压缩等。
Plugin加载后,在webpack构建的某个时间节点就会触发plugin定义的功能,帮助webpack做一些事情。实现对webpack的功能扩展。

常见的Plugin有哪些

  • html-webpack-plugin 处理html资源,默认会创建一个空的HTML,自动引入打包输出的所有资源(js/css)
  • mini-css-extract-plugin 打包过后的css在js文件里,该插件可以把css单独抽出来
  • clean-webpack-plugin 每次打包时候,CleanWebpackPlugin 插件就会自动把上一次打的包删除

Webpack 插件的执行顺序(加载机制)?

Webpack中Loader和Plugin的区别

总说
webpack 就像一条生产线,要经过一系列处理流程(loader)后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能交给下一个流程去处理。
插件就像是一个插入到生产线中的一个功能,在特定的时机对生产线上的资源做处理。 webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。

或者分别使用之前的总结说Loader和Plugin是什么

运行时机
1.loader运行在编译阶段
2.plugins 在整个周期都起作用

使用方式
Loader:1.下载 2.使用
Plugin:1.下载 2.引用 3.使用

Webpack 做过哪些优化手段?有哪些优化手段?

如何利用webpack来优化前端性能? 问的是生产环境优化
如何提高webpack的构建速度? 问的是构建速度的优化

tree-shaking 删除没有使用的代码 优化前端性能/提高构建速度

tree-shaking是一种基于 ES Module 规范的 Dead Code Elimination 技术打包,在打包过程中检测工程中没有引用过的模块并进行标记,删除没有引用过的模块,提高构建速度,较少程序运行时间。

使用tree-shaking需要注意什么?

1.默认mode = production ,生产环境默认开启tree-shaking功能。
2.需要是使用 ES6 规范编写模块代码,ES6的模块依赖关系是确定的,和运行时状态无关
3.尽量不写带有副作用的代码。如编写了立即执行函数,在函数里使用了外部变量等。

关于副作用

如何利用webpack来优化前端性能?

  • 代码压缩

按需加载

  • 代码分割 splitChunks - 在optimization配置项中配置

1.可以将node__mudules中代码单独打包成一个chunk输出(比如使用了jqury?)
2.会自动分析多入口chunk中,有没有公共的文件,如果有会打包成单独的一个chunk不会重复打包

  • 使用Dll进行分包

正常情况下node_module会被打包成一个文件
使用dll技术,对可以将那些不常更新的框架和库进行单独打包,生成一个chunk

  • 使用路由懒加载

在代码中所有被 import()函数引用的模块,都将打成一个单独的包,放在 chunk 存储的目录下。在浏览器运行到这一行代码时,就会自动请求这个资源,实现异步加载。

Webpack如何配置压缩代码?压缩了什么?

1.在optimization配置项中来配置该插件作为压缩器进行压缩。
2.在plugins里使用该插件进行压缩

js压缩:利用terser-webpack-plugin
css压缩:利用了optimize-css-assets-webpack-plugin 插件

删除了console、注释、空格、换行、没有使用的css代码等

如何提高webpack的构建速度?

思路1:减少需要构建的文件或代码

  • HMR(Hot Module Replacement) 模块热替换只重新构建发生变化的模块 – 开发环境中
  • 缩小处理范围:合理利用这两个属性exclude:不需要处理的文件 和 include:需要处理的文件
  • babel缓存 第二次构建时,会读取之前的缓存,只重新构建变化的文件
  • 使用Dll进行分包 --> 分包方便按需加载

正常情况下node_module会被打包成一个文件
使用dll技术,对可以将那些不常更新的框架和库进行单独打包,生成一个chunk
项目源代码也需要拆分,可以根据路由来划分打包文件 --> 怎么实现路由懒加载?webpack中如何实现组件异步加载?

思路2:多进行进行构建

  • 多进程打包 thread-loader,将其放在费时的loader之前

进程启动和进程通信都有开销,工作时间比较长,才需要多进程打包

一名深漂程序员:我所整理和收集的前端面试题 webpack有关面试题

写在前面的话

虽然作为绝大多数,打包发布这些事接触的很少甚至接触不到,尤其是如果在外包公司。那基本上除了写业务逻辑,打包上线这些事跟咱没任何关系,但是。webpack,或者vite这些打包的工具是面试题经常问的,掌握并了解是非常好的加分项

一.如何做webpack构建优化,有哪些策略?

1.devtool:‘source-map’

选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
一些值适用于开发环境,一些适用于生产环境。对于开发者来说,通常希望更快速的源图,需要添加到捆绑中以增加身高为长,但适合生产环境,则希望创建更快速的源图,需要从中分离并独立存在。

2.mode选用production

文档中明确讲过,在生产模式中,代码执行效率提高

3.vendor的提取

公共代码的提取,也叫公共第三方包的提取。通过chunk但对于js的依赖拆分优化策略

4.配置loaders时,使用exclude或include来指定目录

通过使用 include 字段,仅将 loader 应用在实际需要将其转换的模块

5.resolve路径解析优化

(alias、extensions、modules)
alia是的使用优化…延展
减少 resolve.modules, resolve.extensions, resolve.mainFiles, resolve.descriptionFiles 中条目数量,因为他们会增加文件系统调用的次数。
说白了就是常用的后缀写前面,不常用的写后面

6.dll性能优化

对于更新很少的目录结构在开发环境中做优化(比如不敢动的祖传代码) 让这些代码缓存下来。减少构建时间,进行分离打包。使用dllPlugins

7. 减少编译结果的整体大小,提高构建性能

8.使用HappyPack开启多线程构建

多线程在大型项目中会一定程度上加速构建

exports.plugins = [
  new HappyPack({
    id: 'jsx',
    threads: 4,
    loaders: [ 'babel-loader' ]
  }),
  ]

9.node上require使用相对路径

require使用相对路径效率更快

10.chunk css

11.减少编译编译路径

12.增量缓存

有关讲解增量缓存不错的帖子

这个很多很多,面试想到多少说多少,大胆说

二、如何提升webpack的运行速度(开发环境),有哪些策略

1.ScopeHoisting作用域提升

2.使用热更新

3. Plugin尽可能少并确保可靠

选择性能比较好的、官方推荐的或者社区认可的插件来使用。
Plugin尽可能少的使用,减少冗余的代码分析。比如:(css代码压缩插件只在生产环境中配置,开发环境中没有必要使用)
开发环境无用插件的剔除。

4. 构建缓存

在开发环境中使用cache-loader.优先使用webpack的缓存资源
加在loader前。
或者对象语法lader:{name:‘cache-loader’}
在生产模式 cache:true
cach:{type:memory}

三、如何自定义loaders、plugins


class myPlugin {
    constructor(options){       // 执行信息
        console.log(options);
    }
    apply(compiler){
        compiler.hooks.emit.tapAsync("myPlugin",(compilation,callback)=>{
            compilation.assets['content']={
                source:function(){
                    return "content"
                },
                size:function(){
                    return content.length
                }
            };
            cb(
	console.log('this is a content')
);
        })
    }
}
 
module.exports = myPlugin    //自定义一个配置并且引出
 
在webpack默认配置中 的 plugins放入
const myPlugin=require('./plugins/my-webpack-plugin');
 
    plugins:[
        new myPlugin()
    ],


四、说说HMR原理

HMR = Hot Module Replacement
原理:加上这个配置之后,当我们再启动本地服务时,就会在node服务器上开启一个websocket长连接。每当代码有变化时,通过WS长连接通信把变化的代码推送到客户端(浏览器)进行自动更新。

五、有哪些babel预设

Babel预设:用于编译JS语法版本(ES6、TS、JSX)
@babel/core 是Babel编译的核心代码(它不是预设)
@babel/preset-env 用于编译ES6代码
@babel/preset-typescript 用于编译TS代码
@babel/preset-react 用于编译JSX代码

六、webpack 的loader是怎么处理sass的

 当有多个loader配合工作时,使用use:[]数组语法
       注意:当使用多个loader时,有严格的顺序要求,数组中越往后的loader越先工作。
      { test: /\\.css$/i, use: ['style-loader', 'css-loader']},

      sass-loader,只是用于加载.scss文件,交给sass编译器进行编译,得到css代码
       css-loader,用于加载上一步中编译得到的css文件。
       style-loader,用于把css代码注入到DOM树中去。

七、请简述一下babel的运行原理

当webpack运行遇到.js文件时,使用babel-loader加载这个.js文件,然后交给一系列的@babel/*编译器进行编译,进而得到能够兼容浏览器的ES5代码。
当这条规则起作用时,环境会读取根目录中的babal.config.js文件、加载配置好的Babel预设和插件。

八、 解决ESLint报错常用的五种方案

1、找到eslint的配置文件,修改eslint规则
2、使用eslint注释的方式,临时关闭对代码的检测
3、在webpack中找到eslint的插件或eslint-loader进行exclude
4、使用.eslintignore临时忽略对代码的检测
5、老老实实地把eslint错误的改好(建议的做法)

九、脚手架环境中@直接指定src目录是怎么实现的

在webpack中plugin插件对象中。resolve中的

alias{ ‘@’ : path.resolve(__dirname,’…/…/src’)}

最后

我想说的是,面试中 往往这些回答的出彩反而能成为加分项,webpack可以研究的很深。虽然打包工具越来越简洁,越来越好用,但是还是会频繁出现在面试中。尤其是配置方法。所以大家在准备面试时 除了传统面试题的时候,不要忘了打包这一块

以上是关于webpack 面试题整理的主要内容,如果未能解决你的问题,请参考以下文章

「吐血整理」再来一打Webpack面试题

前端面试经历(字节滴滴虎牙),讲真的还挺难,前端大厂面试题总汇得看看

前端面试经历(字节滴滴虎牙),讲真的还挺难,前端大厂面试题总汇得看看

webpack 面试题整理

「吐血整理」Webpack面试题

面试题打卡第九天(前端 webpack基础及高级配置)