webpack离线缓存-【面试题】2023年后端最新笔试题-webpack

原文见:语雀()

● 脚手架和项目脚本

构建工具

○网络包

○咕噜、咕噜咕噜

脚手架

框架

如何设计突然大规模的并发架构?

框架

你知道各种 JS 框架(Angular、Backbone、Ember、React、Meteor、Knockout...)吗? 你能说说它们各自的优点和缺点吗?

重构工具

网络包

⭐️相关知识点参考:

如何设计代码依赖关系

webpack诞生是为了解决什么问题?

如果以前开发时一个html文件可能引用了十多个js文件,那么顺序一定不能乱,因为它们之间存在依赖关系。 同时,对于ES6+等新句型,less、sass等CSS预处理也不能很好。 为了解决...,你需要一个工具来解决这个问题。

为什么要打包构建后端?

●代码层面:更小的体积(Tree-shaking、压缩、合并)、更快的加载中间语言和句型的编译(TS、ES6、模块化、scss)、兼容性和错误检测(polyfill、postcss、eslint)

●研发流程层面:统一高效的开发环境、统一的建立流程、输出标准一体化公司建立规范(测试、上线)

期限

哪些是模块,哪些是块,哪些是捆绑包?

●module:是正在开发的单个模块

Chunk:指webpack进行模块依赖分析时从代码中划分出来的代码块

●bundle:webpack打包的文件

原则

webpack如何打包?/webpack如何工作? (字节)/webpack-原理(数字马力)

1、Webpack可以看成是一个模块加壳器:

●根据文件的依赖关系对文件进行静态分析,

●然后根据指定的规则生成本模块的静态资源,

当webpack处理一个程序时,它会递归地构建一个依赖图(dependencygraph),其中包含应用程序所需的每一个模块,然后将所有这些模块打包成一个或多个bundle。

webpack打包流程? /webpack的建立过程是怎样的?

●初始化参数:解析webpack配置参数,将shell传入的参数与webpack.config.js文件中配置的参数合并,生成最终的配置结果。

●开始编译:用上一步得到的参数初始化编译器对象,注册所有配置的插件,插件监听webpack建立生命周期的storm节点,做出相应反应,执行对象的run模式开始编译,并生成编译对象

●确定entry:从配置的entryentry开始解析文件构建AST句子树,找出依赖关系,向下递归。

●编译模块:在递归中,根据文件类型和加载器配置,调用所有配置的加载器进行文本转换,然后找出该模块所依赖的模块,然后递归这一步,直到所有入口依赖的文件都有经过这一步处理。

●完整的模块编译和输出:递归完成后,得到每个文件结果,包括每个模块以及它们之间的依赖关系,并根据条目或配置生成代码块chunk。

●输出完成:将所有chunk输出到文件系统。

webpack解析import()原理/webpack延迟加载原理/webpack异步加载原理(字节)

jsonp+承诺

1.简单地说

首先,当webpack遇到import方法时,会将其视为代码分割点webpack离线缓存,也就是说,当遇到import方法时,会解析该import方法。

●然后,webpack会将import引用的文件编译成jsonp,这是一个自执行函数。 然后,函数内部就是引用文件的内容,因为后面会通过jsonp加载。

其次,具体而言,

●导入参考文件时,会先调用require.ensure方法(根据打包结果调用require.e)。 该方法主要构造一个promise。 它将把resolve、reject和promise放入一个链表中,并将promise放入一个in队列中。

●然后,调用require.load(根据打包结果调用require.l)方法。 该方法主要创建一个jsonp,即创建一个script标签。 标签的url就是文件加载地址,然后塞到document.head中。 一旦插入,文件就会被加载。

●加载完成后,执行这个jsonp,主要是将moduleId和模块内容保存到modules链表中,然后使用webpack的外部require。

webpack对外的require主要是先判断缓存,moduleId是否已经缓存,如果已经缓存则直接返回。 如果没有缓存,则继续往下,即加载模块内容,然后最终的内容会挂在模块和导出上。 返回module.exports会返回引用文件的最终执行结果。

网页包配置

webpack的核心概念?

●Entry:入口,Webpack执行和建立的第一步都会从Entry开始,可以体现为输入。 告诉 webpack 使用该模块作为构建项目的起点,默认为 ./src/index.js

●output:export,告诉webpack将其打包后的代码输出到哪里以及如何命名,默认是./dist

●Module:模块,Webpack中的一切都是一个模块,一个模块对应一个文件。 Webpack 会从配置的 Entry 中递归查找所有依赖模块。

●Chunk:代码块,一个Chunk由多个模块组成,用于代码合并和拆分。

●Loader:模块转换器,用于将模块原有的内容按照要求转换成新的内容。

●Plugin:扩展插件,在Webpack创建过程中会在特定时间广播相应的风暴。 该插件可以监听此类风暴的发生,并在特定时间做相应的事情。

输出

散列

webpack打包时hash码是如何生成的?

1. webpack生态中有多种形式的哈希估计

● 哈希值

○hash 表示每次 webpack 编译时生成的哈希值,使用这些方法的所有文件都具有相同的哈希值。 每次构建都会导致 webpack 估计一个新的哈希值。

●chunkhash

○Chunkhash是根据入口文件及其关联的chunk生成的。 对某个文件的更改只会影响与其关联的 chunk 的哈希值,不会影响其他文件。

●内容哈希

○contenthash是根据文件内容创建的。当文件内容改变时contenthash也会改变

2.防止随机值相同

● webpack 在估计hash 后分割chunk。 相同随机值的形成可能是由于此类文件属于同一个chunk,并且一个文件可以在独立的chunk中被提及(例如加载条目)

模块模块

装载机

webpack有哪些常见的Loader?

CSS

○css-loader:加载CSS,支持模块化、压缩、文件导入等功能

○style-loader:将CSS代码注入JavaScript中,通过DOM操作加载CSS。

●图片、字体等。

○v5曾经

■file-loader:将文件输出到文件夹,并在代码中通过相对URL引用输出文件

■url-loader:与file-loader类似,当文件很小时,可以将文件内容以base64的形式注入到代码中。

■image-loader:加载并压缩图像文件

●js

○babel-loader:将ES6转换为ES5

●source-map-loader:加载额外的SourceMap文件,方便断点调试

●eslint-loader:通过ESLint检测JavaScript代码

装载机输入和输出什么? (字节)

本质上,webpackloader 将所有类型的文件转换为可以被应用程序的依赖图和最终包直接引用的模块。

Loader机制有哪些作用?

默认情况下,webpack只能打包js文件。 配置中的 module.rules 链表配置了一组规则,告诉 Webpack 遇到文件时使用什么 Loader 来加载并转换为 js。

如何解析html文本? (字节)

仍在测试 ast

默认CSS处理

1、Webpack无法直接识别CSS资源。 必须使用Loader资源来帮助webpack解析样式资源。

2.相关加载器:

●样式加载器

●CSS加载器

● postcss-loader

●少装载机

通天塔

babels是什么?有什么作用

●Babel是一个JS编译器,自带一套ES6/ES7句型转换器,用于转换JS代码

○这些转换器可以让开发者尽早使用最新的JS语法(ES6/ES7),而无需等待所有浏览器兼容

●Babel默认只转换新的JS复杂句(语法),不转换新的API

babel原理(字节)

1、Babel工作原理:三个主要处理步骤是:解析、转换、生成。

1.解析:babel使用@babel/parse将原始代码转换为具体的句子树

●词法解析:将字符串代码转换为token流

○ tokens 是句子片段的平面链表

●语法分析:如何将token流转换为AST

2、变换:第二步,babel通过@babel/traverse遍历并改变具体句子树,得到新的具体句子树

3.生成:使用@babel/generator将具体的句子树转换为代码

如何实现babel插件? / 如何编写 babel 插件? (字节)

1. 编写自己的插件,需要默认为插件提供一个方法,该方法返回一个包含visitor属性的对象。 访客也是一个对象。 对象属性支持不同节点类型对应的钩子函数。 在该函数中,对该类型的节点进行操作。

1. 从接收当前 babel 对象作为参数的函数开始。

导出默认函数(babel){

//插件内容

2.然后返回一个对象,该对象的visitor属性是这个插件的主要访问者。

(1)Visitor中的每个函数接收2个参数:路径和状态

导出默认函数({类型:t}){

返回 {

游客:{

标识符(路径,状态){},

ASTNodeTypeHere(路径、状态){}

};

};

开发工具/源图

源图

1.是映射关系,将打包的文件映射到源码,用于定位错误位置

2、配置方法:

例如: devtool: 'source-map' 具有不同的前缀含义:

●inline:不生成映射关系文件,打包到main.js中

●便宜: 1.只精确到行,不精确到列,打包速度快 2.只有业务代码,不考虑第三方模块

●模块:除了管理业务代码外,还管理第三方代码

eval:执行效率最快、性能最好

3. 最佳实践:

●开发环境:cheap-module-eval-source-map

●线带环境:cheap-mudole-source-map

插件插件

插件有哪些功能?

1、Plugin用于扩展Webpack的功能。 它是通过在创建过程中注入hook来实现的,这给Webpack带来了很大的灵活性。

2、Webpack通过plugins属性配置要使用的插件列表。 plugins 属性是一个链表,上面的每一项都是一个插件的实例。 实例化组件时,可以通过构造函数传入组件支持的配置属性。

如何实现webpack插件?

1、webpack的本质是暴流机制,核心模块:tapable(Sync+Async)Hooks构建===Compiler(编译器)+Compilation(创建bundle)

●编译器对象代表完整的webpack环境配置。 该对象在 webpack 启动时构建一次,并配置所有可操作的设置,包括选项、加载器和插件。 当插件应用在webpack环境中时,插件会收到这个编译器对象的引用,可以用来访问webpack的主环境

●编译对象代表资源版本的创建。 运行webpack开发环境中间件时,每次测量到文件变化,都会创建一个新的编译,从而生成新的编译资源。 编译对象表示有关当前模块资源、已编译资源、更改的文件以及跟踪依赖项的状态的信息。 编译对象还提供了许多关键的时序反弹,供插件在进行自定义处理时选择和使用。

2、实施:

●创建插件函数,在其原型上定义apply方法,并指定webpack自己的storm hook

●该函数内部处理webpack内部实例的具体数据

●处理完成后,调用webpack提供的反弹函数

函数MyWebpackPlugin(){

};

//在原型上定义apply方法

MyWebpackPlugin.prototype.apply=function(){

//指定一个storm函数挂载到webpack

compiler.pluginCwebpacksEventHook"funcion(compiler)(console.log("这是一个插件");

//函数调用后webpack提供的反弹函数

打回来()

})

webpack插件的基本构成

●命名的JavaScript函数;

●在其原型上定义apply方法;

●指定一个触及Webpack本身的storm hook;

●在Webpack内操作特定于实例的数据;

● 实现该功能后,调用Webpack 提供的回调。

//一个基本的插件

类HelloWorldPlugin{

应用(编译器){

compiler.hooks.done.tap('HelloWorldPlugin',(

stats/* 会在钩子被触动时传入 stats 作为参数。 */

)=>{

console.log('HelloWorld!');

});

module.exports=HelloWorldPlugin;

加载器和插件有什么区别?

1、从功能角度区分:

1.Loader字面意思是“装载”。 它只专注于转换文件领域,完成压缩、打包、语言翻译,只是为了打包。

2.插件除了限于打包和资源加载之外,还应该具备越来越多的功能。 从打包优化和压缩到重新定义环境变量,它的功能足够强大,足以处理各种任务。

2、从运行时机角度区分

1.Loader在打包文件之前运行(loader是加载模块时的预处理文件)

2.插件在整个编译周期中工作。

常用插件

webpack常用的插件有哪些?

●ProvidePlugin:手动加载模块,替换require和import

●资源加工

○html

■html-webpack-plugin可以根据模板手动生成html代码,并手动引用css和js文件

○ CSS

■extract-text-webpack-plugin 将js文件中引用的样式分离到css文件中

optimize-css-assets-webpack-plugin不同组件中重复的css可以快速去重

●开发环境

○HotModuleReplacementPlugin热更新

● 编译

○DefinePlugin在编译时配置全局变量,这对于建立开发模式和发布模式以允许不同的行为非常有用。

○clean-webpack-plugin 清除各个包下未使用的文件

●性能优化

○webpack-bundle-analyzer:可视化Webpack输出文件量(业务组件,依赖第三方模块)

○speed-measure-webpack-plugin:可以查看每个Loader和Plugin的执行时长(整个打包时长、每个Plugin和Loader时长)

○compression-webpack-plugin生产环境可以使用gzip压缩JS和CSS

○happypack:通过多进程模型加速代码重构

ExtractTextPlugin插件的功能

ExtractTextPlugin插件的功能是将JavaScript代码中的CSS提取到一个单独的文件中。

为此,您可以使用插件的 filename 属性告诉插件 CSS 文件名输出是通过 [name]_[contenthash:8].css 字符串模板生成的。 上面的[name]代表文件名,[contenthash:8]代表根据文件内容计算出的8位哈希值,还有很多配置选项,可以在ExtractTextPlugin的主页上找到。

手动的

构建性能

如何实现webpack对静态资源的离线缓存?

●配置webpack时,我们可以使用html-webpack-plugin向html中注入脚本,用于静态存储第三方或者共享资源。在html中注入一个标记,例如可以通过在html中配置html属性来注入脚本-webpack-插件

●使用webpack-manifest-plugin并配置webpack-manifest-plugin生成manifest.json文件,用于比较js资源的差异,决定是否替换。 其实还需要写一个缓存脚本。

●我们在做Cl、CD的时候,还可以通过编辑文件流的方式注入静态脚本,以减轻服务器的压力,提高性能。

您可以通过自定义插件或周期性函数(例如html-webpack-plugin)动态注入后端静态存储脚本

基础脚手架功能:webpack相关

Webpack的基本功能有哪些?

●管理资源

● 管理输出

○模块合并:一个模块化项目中有很多模块和文件,需要创建一个功能将模块分类并合并到一个文件中

○代码校准:代码提交仓库前,需要检查代码是否符合规范,单元测试是否通过

○自动发布:更新代码后,手动创建在线发布代码并传输到发布系统。

●开发环境

○自动刷新:窃听本地源代码更改,手动构建,刷新浏览器

●环境配置

●性能优化

○代码转换:TypeScript编译为JavaScript、SCSS编译为CSS等。文件优化:JavaScript、CSS、html代码压缩、图片压缩合并等。

○代码拆分:提取多个页面的公共代码,提取首屏不需要执行的代码并异步加载

管理输出

手动创建的html

如何配置单页面应用程序? 如何配置多页面应用程序?

1、单页应用可以理解为webpack的标准模式。 可以直接在入口中指定单页应用的入口。 我这里就不详细说了。

2、对于多页面应用,可以使用webpack的AutoWebPlugin完成简单的手动创建,前提是项目的目录结构必须遵循其预设规范。

1、多页面应用中需要注意的是,每个页面都有共同的代码,可以将其提取出来,防止重复加载。例如,每个页面都引用同一套CSS样式表。 随着业务的不断扩展,页面可能会不断增加,因此门户的配置必须足够灵活,避免每次增加新页面时都需要更改创建配置。

开发环境

开发服务器

webpack-dev-server 和 http 服务器有什么区别?

webpack-dev-server 使用显存存储 webpack 开发环境中的包文件,并且可以使用模块热更新,比传统的 http 服务对开发更有效。

热更新

什么是模具热更新? 有什么优点?

1.模块热更新是webpack的一个功能,可以在代码更改后提示代码更新,无需刷新浏览器。

您可以在申请过程中替换、添加或删除模块,而无需重新加载整个页面。 它是手动刷新浏览器的中间版本。

2、优点:

1.只更新变化的内容,节省宝贵的开发时间。调整样式提高推送速度,几乎相当于在浏览器中修改样式。

Webpack的热更新原理? (字节)

1.其实我自己打开了express应用,添加了对webpack编译的监听,并添加了与浏览器的websocket长连接。 当文件变化触发webpack编译完成时,它会通过sokcet消息告诉浏览器它打算刷新。为了减少刷新成本,不一定要刷新网页,而是刷新某个模块。 webpack-dev-server可以支持热更新。 生成的文件的哈希值用于比较需要更新的模块webpack离线缓存,然后浏览器进行热替换。

二、服务器

●启动webpack-dev-server服务器

● 创建webpack实例

● 创建服务器服务器

●添加webpack完成的风暴反弹

●编译完成后发送消息给客户端

●创建快递应用程序

●设置文件系统为显存文件系统

●添加webpack-dev-middleware中间件

●中间件负责返回生成的文件

●开始webpack编译