分享Web前端开发Webpack面试题_惠州前端培训学校
作者:hz_admin01发布时间:2022-04-30分类:前端开发专业浏览:862
今天惠州北大青鸟老师给大家分享Web前端开发Webpack面试题,希望对大家有帮助。
Webpack
1.1 简介
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle.
1.2 核心概念
入口(entry)
指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src。
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块
在更高层面,在 webpack 的配置中 loader 有两个目标:
test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
use 属性,表示进行转换时,应该使用哪个 loader。
注意:Webpack选择了compose方式,即从右到左执行loader
插件(plugins)
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
plugins需要暴露出一个class, 在new WebpackPlugin()的时候通过构造函数传入这个插件需要的参数,在webpack启动的时候会先实例化plugin再调用plugin的apply方法,插件需要在apply函数里监听webpack生命周期里的事件,做相应的处理
模式(mode)
通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化
// 多个入口module.exports = {
mode: 'production', entry: {
index: ["./src/index.js"], main: ["./src/main.js"] },
output: { path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].[hash:8].js' },
module: {
rules: [{ test: /\.js$/, // 正则匹配文件名
exclude: '/node_modules/', // 排除
use: ['babel-loader']
} }, plugins: [ // 插件 new copyWebpackPlugin([{
from: path.resolve(__dirname, 'public/static'),
to: path.resolve(__dirname, 'dist'),
ignore: ['index.html']
}])}
1.3 基本流程
解析shell和config中的配置项,用于激活webpack的加载项和插件
webpack初始化工作,包括构建compiler对象,初始化compiler的上下文,loader和file的输入输出环境
解析入口js文件,通过对应的工厂方法创建模块,使用acron生成AST树并且遍历AST,处理require的module,如果依赖中包含依赖则遍历build module,在遍历过程中会根据文件类型和loader配置找出合适的loader用来对文件进行转换
调用seal方法,封装,逐次对每一个module,chunk进行整理,生成编辑后的代码
1.4 模块打包
通过fs将模块读取成字符串,然后用warp包裹一下,使之成为一个字符串形式的的函数然后调用 vm.runInNewContext 这样类型的方法,这个字符串会变成一个函数。
这些模块的函数会被存放在数组里,然后进行解析执行。module和export都是传入的对象,webpack会实现require函数,去加载其他模块。
如果是异步模块,则会通过jsonp的形式去加载该模块打包好生成的chunk。异步加载模块可以使用import和require.ensure函数,函数将会返回一个promise。
上面方法都是公共的,可以抽离成模板的js文件,webpack负责做依赖分析,并将模块读成函数填充入数组。(这里说的只是js的模块)
下面附上简易版的代码
<!-- 同步模块 -->var moduleDepList = [ {'./moduleA': 1}, // module[0] 的依赖 他依赖moduleA 且 moduleA的下标在moduleList 中 为 1 {}] function require(id, parentId) { var currentModlueId = parentId !== undefined ? moduleDepList[parentId][id] : id var module = {exports: {}} var moduleFunc = moduleList[currentModlueId] moduleFunc(id => require(id, currentModlueId), module, module.exports) return module.exports}
<!-- 异步模块 -->var cache = {}
window.__jsonp = function(chunkId, moduleFunc) { var chunk = cache[chunkId] var resolve = chunk[0] var module = {exports: {}} moduleFunc(require, module, module.exports) resolve(module.exports)}
require.ensure = function(chunkId, parentId) { var currentModlueId = parentId !== undefined ? moduleDepList[parentId][chunkId] : chunkId var currentChunk = cache[currentModlueId]
if (currentChunk === undefined) { var $script = document.createElement('script') $script.src = `chunk.${chunkId}.js` document.body.appendChild($script)
var promise = new Promise(function(resolve) { var chunkCache = [resolve] // 数组形式是为了保存promise chunkCache.status = true // 异步模块加载中 如果有别的包 在 异步加载在模块 那么下面的 cache[chunkId] = chunkCache }) cache[chunkId].push(promise) return promise }
if (currentChunk.status) { return currentChunk[1] // 这里的promise 这里的就直接返回promise 这样模块只会加载一次 } return currentChunk}
代码地址:https://github.com/zty1205/react-recruit/tree/master/src/_webpack
1.5 热更新
client 和 server 建立一个 websocket 通信
当有文件发生变动(如fs.watchFile)的时候,webpack编译文件,并通过 websocket 向client发送一条更新消息
client 根据收到的hash值,通过ajax获取一个 manifest 描述文件
client 根据manifest 获取新的JS模块的代码
当取到新的JS代码之后,会更新 modules tree,(installedModules)调用之前通过 module.hot.accept 注册好的回调,可能是loader提供的,也可能是你自己写的
manifest: 描述资源文件对应关系如下,打包后的文件拥有了hash值,所以需要进行映射。
{ "a.js": "a.41231243.js"}
1.6 plugin
1.6.1如何开发一个plugin
一个 JavaScript 命名函数。
在插件函数的 prototype 上定义一个 apply 方法。
指定一个绑定到 webpack 自身的事件钩子。
处理 webpack 内部实例的特定数据。
功能完成后调用 webpack 提供的回调。
tapable 工具,它提供了 webpack 插件接口的支柱
// 一个 JavaScript 命名函数。function plugin() {};
// 在插件函数的 prototype 上定义一个 `apply` 方法。plugin.prototype.apply = function(compiler) { // 指定一个挂载到 webpack 自身的事件钩子。 compiler.plugin('webpacksEventHook', function(compilation, callback) { callback(); }); // 使用taptable的写法 //基本写法 compiler.hooks.someHook.tap(...) //如果希望在entry配置完毕后执行某个功能 compiler.hooks.entryOption.tap(...) //如果希望在生成的资源输出到output指定目录之前执行某个功能 compiler.hooks.emit.tap(...)};
官网地址:https://www.webpackjs.com/api/plugins/
1.6.2 Compiler和Compliation 对象和钩子
对象
compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。
compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用
钩子:总体分成两大类:Compiler和Compliation
Compiler暴露了和webpack整个生命周期相关的钩子
Compilation暴露了与模块和依赖有关的粒度更小的事件钩子,官方文档中的说法是模块会经历加载(loaded),封存(sealed),优化(optimized),分块(chunked),哈希(hashed)和重新创建(restored)这几个典型步骤,从上面的示例可以看到,compilation是Compiler生命周期中的一个步骤,使用compilation相关钩子的通用写法为:
compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){ compilation.hooks.someOtherHook.tap('SomeOtherPlugin,function(){ .... })});
1.6.3 钩子的类型
同步钩子
syncHook: 不关心返回值
syncBailHook: 有一个返回值不为null就跳过剩下的逻辑
SyncWaterfallHook: 下一个任务要拿到上一个任务的返回值
SyncLoopHook: 监听函数返回true表示继续循环,返回undefine表示结束循环
异步钩子
AsyncParallelHook: 异步并发执行,仍是单线程
AsyncParallelBailHook: 异步并发执行,有一个失败了,其他的都不用走了
AsyncSeriesHook: 异步串行执行
AsyncSeriesBailHook: 异步串行执行,有一个返回值不为null就跳过剩下的逻辑
AsyncSeriesWaterfallHook: 异步串行执行,下一个任务要拿到上一个任务的返回值
1.7 常见plugin
clean-webpack-plugin: 在构建之前删除上一次build的文件夹
copy-webpack-plugin: 复制文件或文件夹到生成后的目录
extract-text-webpack | mini-css-extract-plugin: 将所有入口的chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件
html-webpack-plugin: 将build后生成的资源以标签的形式嵌入到HTML模板内
hot-module-replacement: 模块热更新
1.8 常见loader
babel-loader: 语法,源码转换以便能够运行在当前和旧版本的浏览器或其他环境中
css-loader: 配合style-loader可以解析在js中引入的css文件,并以<style>便签将css-loader内部样式注入到我们的HTML页面
file-loader: 可以解析js中require的文件,输出到输出目录并返回 public URL
html-loader: 可以对HTML模板中指定哪个标签属性组合(tag-attribute combination)元素应该被此 loader 处理
less-loader: 依赖less,可以将less编译成css
postcss-loader: 配合一些plugin如cssnano,autoprefixer可以对css进行压缩,优化,自动补足前缀等
scss-loader: 配合node-scss,可以将scss编译成css
style-loader: 配合css-loader可以解析在js中引入的css文件,并以<style>便签将css-loader内部样式注入到我们的HTML页面
url-loader: url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(base64)
1.9 常见打包优化
使用dll
移除prefetch, preload,关闭sourceMap
webpack-bundle-analyzer打包分析,将大的模块可能的移至CDN。打包时间分析使用speed-measure-webpack-plugin
开启gzip,服务器需要支持
使用多线程:thread-loader或HappyPack
webpack4内置的terser启动多线程压缩
对项目进行拆分
想了解更多关于前端的知识吗?可以来惠州北大青鸟新方舟校区了解一下。
标签:惠州前端培训学校惠州前端基础惠州前端培训北大青鸟IT计算机学校北大青鸟IT软件学校前端北大青鸟IT学校惠州北大青鸟北大青鸟
- 前端开发专业排行
- 标签列表
-
- Java (3694)
- 北大青鸟 (3713)
- 软件开发 (3613)
- JAVA (3413)
- UI设计入门 (2093)
- 惠州北大青鸟 (4375)
- 惠州IT培训 (2558)
- UI设计培训 (2090)
- 惠州UI设计培训 (2095)
- 惠州UI设计培训学校 (2090)
- 惠州计算机软件培训 (6260)
- 惠州计算件软件开发 (6260)
- 惠州计算机软件基础 (6261)
- 惠州计算机JAVA培训 (3574)
- 惠州计算机Java软件开发 (3620)
- 惠州计算机JAVA软件开发 (4645)
- 惠州计算机JAVA软件开发学校 (3338)
- 惠州计算机Java软件开发培训 (3338)
- 北大青鸟IT计算机学校 (5048)
- 北大青鸟IT软件学校 (5062)
- 北大青鸟IT学校 (5059)
- 惠州计算机UI设计软件开发 (2088)
- UI设计基础教程 (2088)
- UI设计是什么 (2088)
- UI设计教程 (2088)
- 网站分类
-
- 计算机教程
- 计算机入门
- 职业学校
- 新闻动态
- 专业课程
- 热门技术
- SEO
- 培训教程
- windows
- linux教程
- 系统集成
- 网站开发
- Html5
- 办公软件
- 师资力量
- 热点问答
- 联系我们
- 计算机学校
- 惠州计算机学校
- 河源计算机学校
- 广州计算机学校
- 深圳计算机学校
- 湛江计算机学校
- 佛山计算机学校
- IT计算机培训信息
- 设计专业
- UI
- 影视特效
- 游戏动漫设计
- Photoshop
- AI设计
- 软件教程
- Java技术
- C语言/C++语言培训
- C#
- Python技术
- PHP
- 数据库
- SQL Server
- 网络教程
- 网络安全
- 网络营销
- 软件专业
- 大数据专业
- 前端开发专业
- 软件测试专业
- Python专业
- 软件实施
- 珠海计算机学校
- 初中生学什么好
- 计算机认证
- 文章归档
-
- 2024年11月 (14)
- 2024年10月 (32)
- 2024年9月 (29)
- 2024年8月 (68)
- 2024年7月 (59)
- 2024年6月 (43)
- 2024年5月 (48)
- 2024年4月 (80)
- 2024年3月 (65)
- 2024年2月 (54)
- 2024年1月 (25)
- 2023年12月 (12)
- 2023年11月 (73)
- 2023年10月 (134)
- 2023年9月 (34)
- 2023年8月 (3)
- 2023年7月 (3)
- 2023年6月 (12)
- 2023年5月 (30)
- 2023年4月 (72)
- 2023年3月 (11)
- 2023年2月 (34)
- 2023年1月 (37)
- 2022年12月 (78)
- 2022年11月 (359)
- 2022年6月 (1193)
- 2022年5月 (570)
- 2022年4月 (1567)
- 2022年3月 (982)
- 2022年2月 (54)
- 2022年1月 (182)
- 2021年9月 (308)
- 2021年8月 (1704)
- 2021年7月 (2423)
- 2021年6月 (1806)
- 2021年5月 (1569)
- 2021年4月 (1380)
- 2021年3月 (1255)
- 2021年2月 (709)
- 2021年1月 (1521)
- 2020年12月 (3626)
- 2020年11月 (1646)
- 2020年10月 (1046)
- 2020年9月 (592)
- 最近发表
-
- 清远信息:2024年广清杯清远南粤家政技能大赛举行决赛|||计算机培训机构
- 汕尾信息:陈良川带队到汕尾技师学院调研|||计算机职业技能培训班
- 东莞信息:凤岗凤岗镇组织召开社保参保缴费及劳动用工政策宣讲会|||计算机软件培训学校
- 阳江信息:2024年度注册城乡规划师职业资格考试的合格标准是怎样的?|||计算机软件培训学校
- 阳江信息:职业技能提升补贴对象有哪些?|||大学生计算机培训学校
- 清远信息:清远市首家社保服务合作网点在清城区举办启动仪式|||计算机职业技能培训班
- 汕头信息:招聘658名中高端人才!2024年汕头市引进中高端人才专场招聘会举行|||北大青鸟计算机培训中心
- 东莞信息:广东省社保智能经办现场会在东莞召开|||大学生计算机培训学校
- 东莞信息:东坑镇举办2024年重点群体系列招聘活动|||计算机职业技能培训班
- 东莞信息:万江万江街道成功举办第四届粤菜师傅烹饪技能竞赛|||广州计算机编程培训