前端Webpack面试题
1.说说你对webpack的理解
开发时,我们会使用框架 (React、Vue) ,ES6 模块化语法,Less/Sass 等 CSS 预处理器等语法进行开发,这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS语法才能运行。所以我们需要打包工具帮我们做完这些事。除此之外,打包还能压缩代码、做兼容性处理、提升代码性能等。
webpack 是一个静态模块的打包工具。它会在内部从一个或多个入口点构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个 bundles 进行输出,它们均为静态资源。输出的文件已经编译好了,可以在浏览器运行。 webpack 具有打包压缩、编译兼容、能力扩展等功能。其最初的目标是实现前端项目的模块化,也就是如何更高效地管理和维护项目中的每一个资源。
2.说说webpack的构建流程
初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
确定入口:根据配置中的 entry 找出所有的入口文件
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
在以上过程中,webpack会在特定的时间点广播出特定的事件,插件在监听到事件后会执行特定的逻辑,并且插件可以调用webpack提供的API改变webpack的运行结果
3.Loader是什么?
其作用是让 Webpack 能够去处理那些非 JavaScript 文件。由于 Webpack 自身只理解 JavaScript、JSON ,其他类型/后缀的文件都需要经过 loader 处理,并将它们转换为有效模块。loader 可以是同步的,也可以是异步的;而且支持链式调用,链中的每个 loader 会处理之前已处理过的资源。
loader的两个属性:
1.test,识别出哪些文件会被转换
2.use,在进行转换时,使用的loader
多loader的执行顺序,从右到左(从下到上)
4.常用的Loader
babel-loader 将ES6代码转换成ES5版本
ts-loader ts转js 如果没有babel,使用ts-loader,有babel用@babel/preset-typescript
sass-loader sass转换css
style-loader 创建
css-loader 将css转为js模块导出
url-loader url-loader可以在图片大小小于设定的limit的时候返回的是base编码的图片,大于limit时会调用file-loader对图片进行处理。
file-loader 其实就是将文件拷贝到输出目录下,使用file-loader中配置的新名字
postcss-loader (1)将css解析成js可以操作的AST,(2)调用插件来处理AST并得到结果。
经常配合autoprefixer自动为CSS添加浏览器前缀
html-loader 将html代码转换为js模块导出
eslint-loader 检查代码是否符合eslint规范,只检查错误,不修改代码
5.手写Loader
const loaderUtils = require('loader-utils');module.exports = function(source){// 知识点一 如果为每个构建执行重复的转换操作,这样webpack的构建可能会变得非常慢// 开启缓存this.cacheable && this.cacheable();// 知识点二 使用loaderUtils 获取loader的参数const options = loaderUtils.getOptions(this);console.log('options ->', options);// 知识点三 告诉 Webpack 本次转换是异步的,Loader 会在 callback 中回调结果 // 异步用this.axync() 同步用this.callback()var callback = this.async() // someAsyncOperation 代表一些异步的方法someAsyncOperation(source).then(res => {// 通过 callback 返回异步执行后的结果callback(err, result, sourceMaps, ast)})// 真正的手写代码const reg = /(console.log((.*)))/g;source = source.replace(reg, '');this.callback(null, source);// return undefined的作用是让webpack知道loader返回的结果应该在this.callback当中,而不是return中return;
}/**
this.callback( // 当无法转换原内容时,给 Webpack 返回一个 Error err: Error | null, // 原内容转换后的内容 content: string | Buffer, // 用于把转换后的内容得出原内容的 Source Map,方便调试sourceMap?: SourceMap, // 如果本次转换为原内容生成了 AST 语法树,可以把这个 AST 返回,以方便之后需要 AST 的 Loader 复用该 AST,以避免重复生成 AST,提升性能 abstractSyntaxTree?: AST
);
*/
6.Plugins是什么?
由于webpack基于发布订阅模式,在运行的生命周期中会广播出许多事件,插件通过监听这些事件,就可以在特定的时机执行自己的插件任务,webpack有两个核心对象:
compiler:包含了 webpack 环境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整个生命周期相关的钩子
compilation:作为 plugin 内置事件回调函数的参数,包含了当前的模块资源、编译生成资源、变化的文件以及被跟踪依赖的状态信息。当检测到一个文件变化,一次新的 Compilation 将被创建
1.插件必须是一个带有apply方法的对象
2.不建议修改compiler和compilation对象,因为传入的同一个对象的引用
class CopyrightWebpackPlugin {// 编写一个构造器// 参数初始化constructor(options) {console.log(options)}apply(compiler) {//遇到同步时刻 同步用tapcompiler.hooks.compile.tap('CopyrightWebpackPlugin',() => {console.log('compiler');});//遇到异步时刻 异步用tapAsync// emit 输出asset到output目录之前执行//Compilation存放打包的所有内容,Compilation.assets放置生成的内容compiler.hooks.emit.tapAsync('CopyrightWebpackPlugin', (Compilation, callback) => {debugger;// 往代码中增加一个文件,copyright.txtCompilation.assets['copyright.txt'] = {source: function() {return 'copyright by monday';},size: function() {return 19;}};callback();})}
}module.exports = CopyrightWebpackPlugin;
7.常用的Plugin
1.HtmlWebpackPlugin
2.CleanWebpackPlugin
3.CopyWebpackPlugin
4.Webpack.DefinePlugin 定义全局变量
5.MiniCssExtractPlugin 将css抽取成单独的文件
6.PurgeCSSPlugin 删除没用到的CSS样式,需要判断引用文件,起到css tree-shaking的效果
7.webpack.ProvidePlugin 配置全局模块,避免多次引入的麻烦
8.BundleAnalyzerPlugin 分析打包后资源的依赖以及大小
9.ImageminPlugin 压缩图片
10.CompressionPlugin 启用传输压缩,gzip压缩,需要服务端配合
11.webpack.NoEmitOnErrorsPlugin 遇到编译报错不输出
12.OptimizeCssAssetsPlugin 压缩css,去除重复的类名样式,去除无用的空格
13.UglifyJSPlugin 压缩JS
14.webpack.HotModuleReplacementPlugin 热更新插件
15.TerserPlugin 压缩es6,相比UglifyJsPlugin插件,能更好的处理ES6以上的语法
8.实现一个Plugin
由于webpack基于发布订阅模式,在运行的生命周期中会广播出许多事件,插件通过监听这些事件,就可以在特定的时机执行自己的插件任务,webpack有两个核心对象:
compiler:包含了 webpack 环境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整个生命周期相关的钩子
compilation:作为 plugin 内置事件回调函数的参数,包含了当前的模块资源、编译生成资源、变化的文件以及被跟踪依赖的状态信息。当检测到一个文件变化,一次新的 Compilation 将被创建
在这里插入代码片class CopyrightWebpackPlugin {// 编写一个构造器// 参数初始化constructor(options) {console.log(options)}apply(compiler) {//遇到同步时刻 同步用tapcompiler.hooks.compile.tap('CopyrightWebpackPlugin',() => {console.log('compiler');});//遇到异步时刻 异步用tapAsync// emit 输出asset到output目录之前执行//Compilation存放打包的所有内容,Compilation.assets放置生成的内容compiler.hooks.emit.tapAsync('CopyrightWebpackPlugin', (Compilation, callback) => {debugger;// 往代码中增加一个文件,copyright.txtCompilation.assets['copyright.txt'] = {source: function() {return 'copyright by monday';},size: function() {return 19;}};callback();})}
}module.exports = CopyrightWebpackPlugin;
9.Source map是什么?
source map是将编译、打包、压缩后的代码映射和回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试代码就需要source-map,提高开发效率
10.文件指纹是什么?
文件指纹是打包文件的唯一标识,文件指纹通常有两个用途:
-
版本管理: 在发布版本时,通过文件指纹来区分 修改的文件 和 未修改的文件。
-
使用缓存: 未修改的文件,文件指纹保持不变,浏览器继续使用缓存访问。
Hash 是和整个项目的构建相关,
compilation
实例的变化就会触发 Hash 的变化。Chunkhash 是和 webpack 打包的模块相关,每一个 entry 作为一个模块,会产生不同的 Chunkhash 值,所以他们之间的变化是互不影响的。
Contenthash 是和根据文件内容相关,比如一个页面内的 JS 内容、CSS 内容都会拥有自己的 Contenthash,可以保持各自的独立更新。
11.说说webpack热更新的原理
HMR全称Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换,添加,删除模块,而无需重新刷新整个应用。
例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失如果使用的是 HMR
,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用
webpack的原理:
-
启动阶段
1-2-A-B 在编写为经webpack打包的源代码后,webpacl compiler将源代码和HMR Runtime一起编译成bundle文件,放在webpack Dev Server,当浏览器请求bundle.js文件时,bundle.js就返回给浏览器,运行在浏览器上
(socket.js在服务器和浏览器建立了一个websocket长链接) -
更新阶段
1-2-3-4 当某一个文件或者模块发生变化时,webpack监听到文件变化对文件重新编译打包,编译生成唯一的hash值,本次生成的hash值会作为下一次热更新的标识,也就是本次热更新使用的hash值,是上一次热更新生成文件的hash(此次的hash值是上次热更新中manifest中h的值)由于
socket
服务器在HMR Runtime
和HMR Server
之间建立websocket
链接,当文件发生改动的时候,服务端会向浏览器推送一条消息,消息包含文件改动后生成的hash
值,如下图的h
属性,作为下一次热更细的标识
浏览器根据hash标识,去创建ajax去获取此次的mainfest(h:build生成的hash值,c:变化的模块 )文件,使用jsonp获取此次的修改内容,浏览器拿到这两个文件后,通过HMR runtime机制,加载这两个文件,触发render流程,实现局部刷新
12.说说webpack proxy工作原理
在开发阶段, webpack-dev-server
会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在 localhost
的一个端口上,而后端服务又是运行在另外一个地址上
所以在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题
通过设置webpack proxy
实现代理请求后,相当于浏览器与服务端中添加一个代理者
当本地发送请求的时候,代理服务器响应该请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地
在代理服务器传递数据给本地浏览器的过程中,两者同源,并不存在跨域行为,这时候浏览器就能正常接收数据
注意:服务器与服务器之间请求数据并不会存在跨域行为,跨域行为是浏览器安全策略限制
13.webpack打包体积优化
一、提取公共模块
假如现在有一个MPA(多页面应用)的react项目,每个页面的入口文件及其依赖的组件中都会引入一份react和react-dom等,那最终打包后的每个页面中同样也会有一份以上的公共包的代码,可以将这个包单独抽离出来,最终在每个打包后的页面入口文件引入,从而减少打包后的总体积
module.exports = {optimization: {splitChunks: {minSize: 20000,cacheGroups: {react: {test: /(react|react-dom)/,name: 'vendors',chunks: 'all',},},},}
};
二、配置CDN服务器
1.可以修改output:{publicPath: ‘’} 的值,打包时添加上自己的CDN地址
2.在CDN上部署自己依赖的第三方资源,
3.在externals中加入不进行打包的资源,在html模版中加入CDN服务器地址
4.如果没有自己配置CDN服务器,可以使用其他人放置在cdn服务器上的资源
三、代码压缩(此处的代码压缩并非真正的压缩,而是删掉代码中无意义的部分,例如空格)
1.压缩js,使用插件TerserPlugin
2.压缩css,使用CSSMinimizerPlugin
css压缩通常是去除无用的空格等,因为很难去修改选择器,属性和名称、值等
3.压缩html,使用HtmlWebpackPlugin的minify配置
new HtmlWebpackPlugin({template: path.join(__dirname, './public/index.html'),filename: 'index.html',minify: { // minify配置可以压缩html文件,设置了minify,实际上会使用另一个插件html-minifier-terserminifyCSS: false, //是否压缩csscollapseWhitespace: true, // 是否折叠空格removeComments: true, // 是否移除注释}
}),
4.压缩图片,使用image-webpack-loader
这个不太理解,压缩后图片会不会失真或者像素变低?打包的时候压缩,使用的时候进行解压缩?
四、使用TreeShaking
tree shaking是一个术语,在计算机中标识消除死代码,尽量使用纯函数编程,用于消除未调用的代码
1.JS实现Tree Shaking
(1)usedExports,配置方法很简单,只需将usedExports设置为true
module.exports = {...optimization:{usedExports}
}
使用后,没被用上的代码在webpack打包中会添加 unused harmony export … 注释,用来告知Terser在优化时,可以删掉这段代码
(2)sideEffects实现
sideEffects用于指定哪些模块是有副作用的,副作用指的是这里面的代码有执行一些特殊的任务,不能仅仅依靠export来判断这段代码的意义
sideEffect设置为false,就是告知webpack可以安全的删除未用到的exports
sideEffect设置为数组,则将代码中的数据进行保留
总结:
- 在optimization中配置usedExports为true,来帮助Terser进行优化;
- 在package.json中配置sideEffects,直接对模块进行优化;
2.CSS实现Tree Shaking
css主要使用的purgecss-webpack-plugin
五、文件大小压缩(真正意义的压缩,gzip算法)
compression-webpack-plugin 插件
对文件的大小进行压缩,将前端打包好的资源文件进一步压缩,生成指定的、体积更小的压缩文件,减小http传输过程中带宽的损耗
new ComepressionPlugin({test:/\.(css|js)$/, // 哪些文件需要压缩threshold:500, // 设置文件多大开始压缩minRatio:0.7, // 至少压缩的比例algorithm:"gzip", // 采用的压缩算法
})
使用npm run build,会生成许多以.gz格式的文件
生成压缩后的文件,不能直接使用,需要服务端配置才可以使用,而且发现打包生成的“dist/index.html”首页内,也没有直接引用这些“.gz”格式的文件。
而实现的关键,其实就是让服务端向浏览器发送“Content-Encoding=gzip”这个响应头,并把对应的“.gz”格式文件发送给浏览器,让浏览器通过“gzip”编码格式来解析资源。
const path = require('path');
const fs = require('fs');
const express = require('express');
const app = express();app.use((request, response, next) => {const fullPath = path.join(__dirname, `${request.originalUrl}.gz`); // 检测是否存在同名.gz压缩文件if (fs.existsSync(fullPath)) {// 存在就告诉浏览器用gzip编码格式来解析,并把对应的“.gz”格式文件发送给浏览器。response.setHeader('Content-Encoding', 'gzip') response.sendFile(fullPath);} else {next()}
})
app.use(express.static('./'));app.listen(1055, _ => {console.log('1055服务器已经启动');
});
六、antd按需导入
import {Col,Row} from 'antd'
14.优化构建速度
这个问题个人认为比较宽泛,顺着聊几点就好了,答不上来也没关系,重点是上面的压缩打包后的体积
可以使用speed-measure-webpack-plugin统计总打包耗时以及每个plugin和loader的打包耗时
一、缩小构建范围、优化Loader配置
在使用loader时,可通过配置include、exclude、test属性来匹配文件
module.exports = {module: {rules: [{// 如果项目源码中只有 js 文件就不要写成 /\.jsx?$/,提升正则表达式性能test: /\.js$/,// babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启use: ['babel-loader?cacheDirectory'],// 只对项目根目录下的 src 目录中的文件采用 babel-loaderinclude: path.resolve(__dirname, 'src'),},]},
};
二、优化resolve.alias
alias
给一些常用的路径起一个别名,特别当我们的项目目录结构比较深的时候,一个文件的路径可能是./../../
的形式
通过配置alias
以减少查找过程
module.exports = {...resolve:{alias:{"@":path.resolve(__dirname,'./src')}}
}
三、多进程构建
对于耗时较长的模块,同时开启多个 nodejs 进程进行构建,可以有效地提升打包的速度。terser启动多线程
module.exports = {optimization: {minimizer: [new TerserPlugin({parallel: true,}),],},
};
四、合理使用source-map
打包生成sourceMap的时候,信息越详细,打包速度就越慢
五、cache-loader
在一些性能开销较大的 loader
之前添加 cache-loader
,以将结果缓存到磁盘里,显著提升二次构建速度
保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader
使用此loader
module.exports = {module: {rules: [{test: /\.ext$/,use: ['cache-loader', ...loaders],include: path.resolve('src'),},],},
};
相关文章:

前端Webpack面试题
1.说说你对webpack的理解 开发时,我们会使用框架 (React、Vue) ,ES6 模块化语法,Less/Sass 等 CSS 预处理器等语法进行开发,这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS语法才能运行。所以我们需要打包工…...

LabVIEW使用边缘检测技术实现彩色图像隐写术
LabVIEW使用边缘检测技术实现彩色图像隐写术 隐写术是隐藏信息的做法,以隐瞒通信的存在而闻名。该技术涉及在适当的载体(如图像,音频或视频)中插入秘密消息。在这些载体中,数字图像因其在互联网上的广泛使用而受到青睐…...
第一次参加计算机会议报告注意事项以及心得
计算机会议参会报告 注意事项参会前参会中参会后 参会心得 注意事项 接下来的会议注意事项分为:(1)参会前,(2)参会中,(3)参会后 参会前 参会前,一般被邀请…...
TypeScript教程(二)基础语法与基础类型
一、基础语法 TypeScript由以下几个部分组成 1.模块 2.函数 3.变量 4.语句和表达式 5.注释 示例: Runoob.ts 文件代码: const hello : string "Hello World!" console.log(hello) 以上代码首先通过 tsc 命令编译: tsc …...

问道管理:网上如何打新股?
随着资本市场的不断敞开,越来越多的人开始重视股票市场,并想经过网上打新股来取得更大的出资收益。但是,网上打新股的办法并不简略,怎样才能成功地打新股呢?本文将从多个角度剖析,协助广阔出资者处理这一问…...

重磅更新,HertzBeat 集群版发布,易用友好的开源实时监控系统!
什么是 HertzBeat? HertzBeat 赫兹跳动 是一个拥有强大自定义监控能力,高性能集群,无需 Agent 的开源实时监控告警系统。 特点 集 监控告警通知 为一体,支持对应用服务,数据库,操作系统,中间件…...
.NET6使用微信小程序授权登录,获取手机号
1.在appsettings配置你的小程序配置信息 //微信小程序信息配置"WechatConfig": {"appid": "", //小程序ID"secret": "" //小程序秘钥},2.请求接口时先获取Access_token #region 获取小程序的Access_tokenpublic object GetA…...

游戏类APP如何提升用户的活跃度?
移动游戏行业,追求使用率的营销能发挥强大的功效,可帮助减少玩家流失、追回流失的玩家、提高活跃玩家所带来的价值以及增加付费玩家贡献的收入。 一、了解玩家需求 想要提升玩家的活跃,首先要知道,玩家喜欢玩哪些平台的游戏&…...
【Sklearn】基于支持向量机算法的数据分类预测(Excel可直接替换数据)
【Sklearn】基于支持向量机算法的数据分类预测(Excel可直接替换数据) 1.模型原理1.1 数学模型1.2 模型原理2.模型参数3.文件结构4.Excel数据5.下载地址6.完整代码7.运行结果1.模型原理 支持向量机(Support Vector Machine,SVM)是一种用于分类和回归的监督学习算法,其基本…...
抽象类与接口
一,类 定义类 部分与ES6用法基本一致。通过class定义类名,并通过constructor定义构造函数,通过super关键字来调用父类的方法。 class Person {name: string; // 属性constructor(name: string) { // 构造函数this.name name;}eat()…...
第三章,矩阵,09-线性方程组解的判断与求法、矩阵方程
第三章,矩阵,09-线性方程组解的判断与求法、矩阵方程 定理推论1推论2推论3推论4 矩阵方程AXB解法解的存在性推论 玩转线性代数(21)线性方程组解的判断与求法的笔记,相关证明以及例子见原文 定理 对n元线性方程组 A x b Axb Axb,…...

Vue-4.编译器VsCode
准备 Vue-1.零基础学习Vue Vue-2.nodejs的介绍和安装 Vue-3.vue简介 为什么用VsCode VsCode 是Vue官网首推的编译器它是完全免费的 下载安装VsCode 下载地址 安装的时候不停地下一步直到完成即可 安装插件 安装汉化插件 要将 Visual Studio Code(VSCode&am…...
Neo4j之Aggregation基础
在 Neo4j 中,聚合(Aggregation)是对数据进行计算、汇总和统计的过程。以下是一些使用聚合函数的常见例子,以及它们的解释: 计算节点数量: MATCH (p:Person) RETURN count(p) AS totalPersons;这个查询会计…...

Python 函数
Built-in Functions — Python 3.11.4 documentation...

Spring(三):Spring中Bean的生命周期和作用域
前言 在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。而 b…...

【AutoLayout案例03-设置底部按钮之间相同间距 Objective-C语言】
一、好,咱们继续啊 1.咱们继续把autoLayout介绍一下 咱们的自动布局 给大家介绍一下 那么,自动布局呢 继续咱们给大家做的案例 做几个例子 把这几个例子做完以后 我们再给它 我们再给大家说一下,如何通过代码,来实现自动布局 虽然说,通过代码来实现自动布局,并不推荐 但…...
代码随想录算法训练营20期|第七天|哈希表part02|454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和 ● 总结
454.四数相加II 比较巧思的解法,先把nums1 和nums2的数两两相加,并存储sum和次数 再在nums3和nums4里找对应和sum和为0的数值i,j Time: N^2 Space:N^2, 最坏情况下A和B的值各不相同,相加产生的数字个数为 n^2 class Solution {public int fo…...

NavMeshPlus 2D寻路插件
插件地址:h8man/NavMeshPlus: Unity NavMesh 2D Pathfinding (github.com) 我对Unity官方是深恶痛觉,一个2D寻路至今都没想解决,这破引擎早点倒闭算了. 这插件是githun的开源项目,我本身是有写jps寻路的,但是无法解决多个单位互相阻挡的问题(可以解决但是有性能问…...
【03】基础知识:typescript中的函数
一、typescript 中定义函数的方法 函数声明法 function test1(): string {return 返回类型为string }function test2(): void {console.log(没有返回值的方法) }函数表达式/匿名函数 const test3 function(): number {return 1 }二、typescript 中 函数参数写法 1、typesc…...

ssm社区文化宣传网站源码和论文
ssm社区文化宣传网站源码和论文019 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 研究或设计的目的和意义: (一)研究目的: 通过本次课题能够将所学的Java编程知识以及Mysql数据库知…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...