当前位置: 首页 > news >正文

(四)什么是Vite——冷启动时vite做了什么(源码、middlewares)

 vite分享ppt,感兴趣的可以下载:

​​​​​​​Vite分享、原理介绍ppt

什么是vite系列目录:

(一)什么是Vite——vite介绍与使用-CSDN博客

(二)什么是Vite——Vite 和 Webpack 区别(冷启动)-CSDN博客

(三)什么是Vite——Vite 主体流程(运行npm run dev后发生了什么?)-CSDN博客

(四)什么是Vite——冷启动时vite做了什么(源码、middlewares)-CSDN博客

(五)什么是Vite——冷启动时vite做了什么(依赖、预构建)-CSDN博客

(六)什么是Vite——热更新时vite、webpack做了什么-CSDN博客

(七)什么是Vite——vite优劣势、命令-CSDN博客

冷启动时vite做了什么:

vite主要遵循的是使用 ESM ( Es modules 模块)的规范来执行代码,由于现代浏览器基本上都支持了 ESM 规范,所以在开发阶段并不需要将代码打包编译成 es5 模块即可在浏览器上运行。我们只需要从入口文件出发, 在遇到对应的 import 语句时,将对应的模块加载到浏览器中就可以了(按需加载)。同时 ts/jsx 等文件的转译工作也会借助了 esbuild 来提升速度。Vite在内部实现上,会启动一个 dev server , 并接受独立模块的HTTP请求,并让浏览器自身去解析和处理模块加载

模块解析

对于引用的模块,vite将其分为了 依赖 和 源码 两类,对其进行不同的处理。

先来看一下对于 源码 的处理。我们打开请求的App.vue文件,可以看到里面的内容已经不是源码了,而是经过处理后的代码。

middlewares 中内容转换

Vite 中源文件的转换是在 dev server 启动以后通过 middlewares 实现的。

当浏览器发起请求以后,dev sever 会通过相应的 middlewares (transformMiddleware 、indexHtmlMiddleware)对请求做处理,然后将处理以后的内容返回给浏览器。

middlewares 对源文件的处理,分为 resolve、load、transform、parser 四个过程:

  1. resolve - 解析 url,找到源文件的绝对路径;
  2. load - 加载源文件。如果是第三方依赖,直接将预构建内容返回给浏览器;如果是业务代码,继续 transform、parser。
  3. transfrom - 对源文件内容做转换,即 ts -> js, less -> css 等。转换完成的内容可以直接返回给浏览器了。
  4. parser - 对转换以后的内容做分析,找到依赖模块,对依赖模块做预转换 - pre transform 操作,即重复 1 - 4。
    1. pre transform 是 Vite 做的一个优化点。预转换的内容会先做缓存,等浏览器发起请求以后,如果已经完成转换,直接将缓存的内容返回给浏览器。

Vite 在处理步骤 3 时,是通过 esbuild.transform 实现的,对比 Webpack 使用各个 loader 处理源文件,那是非常简单、快捷的。

模块请求加载过程:一个请求的 Vite 之旅

当浏览器一个请求到vite服务时,发生了什么?

主要由以下两个中间件来统一处理请求的内容,并在中间件处理的流程中调用 vite 插件容器的相关钩子函数

  • transformMiddleware:核心中间件处理代码
  • indexHtmlMiddleware:html 相关请求处理中间件

GET localhost :实际 GET / => /index.html

当访问页面的时候,实际是有一个 GET / => /index.html 的重定向进入 indexHtmlMiddleware 这个过程,主要做了一件事情,注入 dev 环境需要的一些依赖,@vite/client 主要用来和服务器进行 ws 通信并处理一些 hmr 相关的工作。

GET client :实际 GET /@vite/client

这个请求会直接进入 transformMiddleware 中间件中,进入中间件的处理过程:中间件会调用 transformRequest(url, server, options = {}) 函数

  1. @vite/client 是如何映射到对应的内容呢,在调用 pluginContainer.resolveId 的过程中会遇到 aliasPlugin 插件的钩子,执行名称替换,最终替换成 vite/dist/client/client.mjs
  1. 继续将改写过的路径传给下一个插件,最终进入 resolvePlugin 插件的 tryNodeResolve 函数,最终解析获得该文件的 id 为/lib/node_modules/vite/dist/client/client.mjs
  2. 最终通过 pluginContainer.load 获取加载本地文件,然后通过 pluginContainer.transform 进行代码转换,将转换后的代码通过 send 方法发送给浏览器。

有无 middlewares 的影响:例子—— vue-dev-server-analysis

(尤雨溪开发vue dev server理解vite原理 - 编程宝库)

# 克隆官方仓库
git clone https://github.com/vuejs/vue-dev-server.git
cd vue-dev-server
# npm i -g yarn
# 安装依赖
yarn

 一般来说,我们看源码先从package.json文件开始:

// vue-dev-server/package.json
{"name": "@vue/dev-server","version": "0.1.1","description": "Instant dev server for Vue single file components","main": "middleware.js",// 指定可执行的命令"bin": {"vue-dev-server": "./bin/vue-dev-server.js"},"scripts": {// 先跳转到 test 文件夹,再用 Node 执行 vue-dev-server 文件"test": "cd test && node ../bin/vue-dev-server.js"}
}

根据 scripts test 命令。我们来看 test 文件夹。

 test 文件夹:

vue-dev-server/test 文件夹下有三个文件,代码不长。

  • index.html
  • main.js
  • text.vue

如图下图所示。

接着我们找到 vue-dev-server/bin/vue-dev-server.js 文件,代码也不长。

主要是启动了端口 3000 的服务,重点在 vueMiddleware 中间件。接着我们来调试这个中间件。

vue-dev-server/bin/vue-dev-server.js 文件中这行 app.use(vueMiddleware()) 打上断点。

找到 vue-dev-server/package.json 的 scripts,把鼠标移动到 test 命令上,会出现运行脚本和调试脚本命令。如下图所示,选择调试脚本。

点击 进入函数(F11)按钮可以进入 vueMiddleware 函数。如果发现断点走到不是本项目的文件中,不想看,看不懂的情况,可以退出或者重新来过。可以用浏览器无痕(隐私)模式(快捷键Ctrl + Shift + N,防止插件干扰)打开 http://localhost:3000,可以继续调试 vueMiddleware 函数返回的函数。

有无 vueMiddleware 中间件对比:

先看结果,在具体分析:

不在调试情况状态下,我们可以在 vue-dev-server/bin/vue-dev-server.js 文件中注释 app.use(vueMiddleware()),执行 npm run test 打开  http://localhost:3000 .

再启用中间件后,如下图。

看图我们大概知道了有哪些区别。浏览器支持原生 type=module 模块请求加载。vue-dev-server 对其拦截处理,返回浏览器支持内容,因为无需打包构建,所以速度很快。

具体分析

接下来,我们来具体分析:

我们可以找到vue-dev-server/middleware.js,查看这个中间件函数的概览。

// vue-dev-server/middleware.jsconst vueMiddleware = (options = defaultOptions) => {// 省略return async (req, res, next) => {// 省略// 对 .vue 结尾的文件进行处理if (req.path.endsWith('.vue')) {// 对 .js 结尾的文件进行处理} else if (req.path.endsWith('.js')) {// 对 /__modules/ 开头的文件进行处理} else if (req.path.startsWith('/__modules/')) {} else {next()}}
}
exports.vueMiddleware = vueMiddleware

vueMiddleware 最终返回一个函数。这个函数里主要做了四件事:

  • 对 .vue  结尾的文件进行处理
  • 对 .js 结尾的文件进行处理
  • 对 /__modules/  开头的文件进行处理
  • 如果不是以上三种情况,执行 next 方法,把控制权交给下一个中间件

对 .vue 结尾的文件进行处理

if (req.path.endsWith('.vue')) {
const key = parseUrl(req).pathname
let out = await tryCache(key)
if (!out) {// Bundle Single-File Componentconst result = await bundleSFC(req) // 具体见下文,bundleSFC 编译单文件组件out = resultcacheData(key, out, result.updateTime)
}
send(res, out.code, 'application/javascript')
}

bundleSFC 编译单文件组件

这个函数,根据 @vue/component-compiler 转换单文件组件,最终返回浏览器能够识别的文件。

const vueCompiler = require('@vue/component-compiler')
async function bundleSFC (req) {
const { filepath, source, updateTime } = await readSource(req) // 看下文,readSource 读取文件资源
const descriptorResult = compiler.compileToDescriptor(filepath, source)
const assembledResult = vueCompiler.assemble(compiler, filepath, {...descriptorResult,script: injectSourceMapToScript(descriptorResult.script),styles: injectSourceMapsToStyles(descriptorResult.styles)
})
return { ...assembledResult, updateTime }
}

接着来看 readSource 函数实现。

readSource 读取文件资源

这个函数主要作用:根据请求获取文件资源。返回文件路径 filepath、资源 source、和更新时间 updateTime。

const path = require('path')
const fs = require('fs')
const readFile = require('util').promisify(fs.readFile)
const stat = require('util').promisify(fs.stat)
const parseUrl = require('parseurl')
const root = process.cwd()
async function readSource(req) {
const { pathname } = parseUrl(req)
const filepath = path.resolve(root, pathname.replace(/^\//, ''))
// 根据请求获取文件资源。返回文件路径 filepath、资源 source、和更新时间 updateTime。
return {filepath,source: await readFile(filepath, 'utf-8'),updateTime: (await stat(filepath)).mtime.getTime()
}
}
exports.readSource = readSource

接着我们来看对 .js 文件的处理

对 .js 结尾的文件进行处理

if (req.path.endsWith('.js')) {
const key = parseUrl(req).pathname
let out = await tryCache(key)
if (!out) {// transform import statements// 转换 import 语句 // import Vue from 'vue'// => import Vue from "/__modules/vue"const result = await readSource(req)out = transformModuleImports(result.source) // 转换 import 引入cacheData(key, out, result.updateTime)
}
send(res, out, 'application/javascript')
}

 针对 vue-dev-server/test/main.js 转换

import Vue from 'vue'
import App from './test.vue'
new Vue({render: h => h(App)
}).$mount('#app')

 转换:

import Vue from "/__modules/vue"
import App from './test.vue'
new Vue({render: h => h(App)
}).$mount('#app')

main.js 中的 import 语句import Vue from 'vue'通过 recast 生成 ast 转换成 import Vue from "/__modules/vue" 而最终返回给浏览器的是 vue-dev-server/node_modules/vue/dist/vue.esm.browser.js

main.js 中的引入 .vue 的文件,import App from './test.vue' 则用 @vue/component-compiler 转换成浏览器支持的文件,具体见下文。

对 /__modules/ 开头的文件进行处理

import Vue from "/__modules/vue"

 这段代码最终返回的是读取路径 vue-dev-server/node_modules/vue/dist/vue.esm.browser.js 下的文件。

if (req.path.startsWith('/__modules/')) {
// 
const key = parseUrl(req).pathname
const pkg = req.path.replace(/^\/__modules\//, '')
let out = await tryCache(key, false) // Do not outdate modules
if (!out) {out = (await loadPkg(pkg)).toString() // loadPkg 加载包(这里只支持Vue文件)cacheData(key, out, false) // Do not outdate modules
}
send(res, out, 'application/javascript')
}

loadPkg 加载包(这里只支持Vue文件)

目前只支持 Vue 文件,也就是读取路径 vue-dev-server/node_modules/vue/dist/vue.esm.browser.js 下的文件返回。

// vue-dev-server/loadPkg.js
const fs = require('fs')
const path = require('path')
const readFile = require('util').promisify(fs.readFile)
async function loadPkg(pkg) {
if (pkg === 'vue') {// 路径// vue-dev-server/node_modules/vue/distconst dir = path.dirname(require.resolve('vue'))const filepath = path.join(dir, 'vue.esm.browser.js')return readFile(filepath)
}
else {// TODO// check if the package has a browser es module that can be used// otherwise bundle it with rollup on the fly?throw new Error('npm imports support are not ready yet.')
}
}
exports.loadPkg = loadPkg

 至此,我们就基本分析完毕了主文件和一些引入的文件。对主流程有个了解。

Vite 提供了哪些常用的构建插件和中间件?如何使用它们?

上文讲到了对于不同的资源会有不同的插件去处理。Vite 提供了一些常用的构建插件和中间件,以帮助你在项目中进行开发和构建。

vite的内置插件:

vite在返回源码时,已经对源码做了一层处理,编译为浏览器可以运行的代码。实际上,对于不同的文件后缀,比如.ts、.vue、.tsx、.jsx,vite都会对其做不同的处理:

.vue文件

vite 默认支持 Vue 项目,并提供了一些 Vue 相关的插件,如 @vitejs/plugin-vue,用于解析和编译 Vue 单文件组件。

  • Vue 3 单文件组件支持:@vitejs/plugin-vue
  • Vue 3 JSX 支持:@vitejs/plugin-vue-jsx
  • Vue 2 支持:underfin/vite-plugin-vue2

npm install @vitejs/plugin-vue

 在 vite.config.js 中使用 Vue 插件:

import { createVuePlugin } from 'vite-plugin-vue'export default {plugins: [createVuePlugin(/* options */)]
}

.ts文件

(packages/vite/src/node/plugins/esbuild.ts)

Vite 内置支持 TypeScript,无需额外的插件,其内部使用esbuild将TypeScript 转译到 JavaScript。可以直接在项目中使用 TypeScript。

.jsx文件、.tsx文件

(packages/vite/src/node/plugins/esbuild.ts)

JSX 的转译同样是通过 esbuild,默认为 React 16 风格。

.css文件

(packages/vite/src/node/plugins/css.ts)

Vite 支持处理 CSS 相关的插件,比如 vite-plugin-css,用于处理 CSS 文件和样式。导入 .css 文件将会把内容插入到标签中。

npm install vite-plugin-css

 在 vite.config.js 中使用 CSS 插件:

import { createCssPlugin } from 'vite-plugin-css'export default {plugins: [createCssPlugin(/* options */)]
}

裸模块重写

(packages/vite/src/node/plugins/resolve.ts)(packages/vite/src/node/plugins/importAnalysis.ts)

从下面这张图中,我们可以看到, vuex.js、vue-router.js 这种依赖模块文件名后面是有后缀的,而 main.js 等这种源代码文件是没有的。为什么会有这样的不同呢?这是因为 vuex.js、vue-router.js 是裸模块,而浏览器在加载文件时,只能加载相对地址,类似于 import Vuex from 'vuex'; 这种裸模块的加载,浏览器是不支持的,所以 vite 会对其做一层裸模块重写的处理,例如将引入 vuex 的url改写为 /node_modules/.vite/deps/vuex.js?v=bc6c6eed

由于 import vue 这种模块引入方式,使用的是 Nodejs 特有的模块查找算法(到 node_modules 中取查找),浏览器无法使用,因此 Vite 会将 vue 替换成一个另一个路径,当浏览器解析到这行 import 语句时,会发送一个 /node_modules/.vite/deps/vuex.js?v=bc6c6eed, Vite Server 会到该目录下,拿到 vue 预构建之后的产物代码。

你会发现,引入的 vuex 是在.vite文件夹里头,而不是在 node_modules 的 vuex 文件夹中,这是因为 vite 做了一个优化 —— 依赖预构建

依赖预构建做了什么:

  • 扫描入口文件
  • 扫描所有用到的依赖
  • 将多个依赖进行打包
  • 修改这些模块的引入路径

简单来说,vite会对 package.json 中的 dependencies 部分先进行构建,然后把构建后的文件换存在 node_modules/.vite 文件夹中,当启动项目时,直接请求该缓存内容。

相关文章:

(四)什么是Vite——冷启动时vite做了什么(源码、middlewares)

vite分享ppt,感兴趣的可以下载: ​​​​​​​Vite分享、原理介绍ppt 什么是vite系列目录: (一)什么是Vite——vite介绍与使用-CSDN博客 (二)什么是Vite——Vite 和 Webpack 区别&#xff0…...

Docker部署MinIO对象存储服务器结合Cpolar实现远程访问

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远…...

C#入门(1):程序结构、数据类型

一、C#程序结构 第一个C#程序 using System;namespace base_01 {class Program{#region 代码折叠块static void Main(string[] args){//控制台输出Console.WriteLine("Hello World!");Console.Write("C#是微软的编程语言"); //不换行输出//Console.Rea…...

Scala---元组

1、元组定义 与列表一样,与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。 2、创建元组与取值 val tuple new Tuple(1) 可以使用newval tuple2 Tuple(1,2) 可以不使…...

【Linux】冯诺依曼体系结构、操作系统、进程概念、进程状态、环境变量、进程地址空间

目录 一、冯诺依曼体系结构二、操作系统(OS)1. 操作系统是什么2. 操作系统如何做管理3. 系统调用和库函数概念 三、进程1. 进程是什么?2. 描述进程-PCB3. 查看进程的方法 四、进程状态1 运行、阻塞和挂起状态2 Linux中的进程状态 五、进程优先级1. 什么是优先级2.查…...

【hive-解决】HiveAccessControlException Permission denied: CREATEFUNCTION

文章目录 一.任务描述二. 解决 一.任务描述 Error while compiling statement: FAILED: HiveAccessControlException Permission denied: Principal [nameroot, typeUSER] does not have following privileges for operation CREATEFUNCTION [ADMIN PRIVILEGE on INPUT, ADMIN…...

内网穿透的应用-通过内网穿透快速搭建公网可访问的Spring Boot接口调试环境

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…...

解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题

参考博文:uniapp微信小程序无法使用本地静态资源图片(背景图在真机不显示)的解决方法_javascript技巧_脚本之家 问题:uniapp 开发微信小程序,当使用本地图片作为 background-image 时,真机无法显示 解决: 方法一&am…...

常用中间件封装思路粗记

MQ 自定义注解 ,编写配置类在bean属性初始化SmartInitializingSingleton#afterSingletonsInstantiated后至处理器 去扫描有自定义注解的bean,去创建对应消费者的容器 并启动消费者容器类主要组件DefaultMQPushConsumer SmartInitializingSingleton#afte…...

探索SPI:深入理解原理、源码与应用场景

文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test…...

Web3名词解释

Web3名词解释 以太坊 ERC20 Defi去中心化金融 Defi是Decentralized Finance的英文缩写。 简单理解点就是与传统的高度中心化金融体系相比,去中心化金融是通过区块链技术,比如基于区块链技术开发的手机钱包软件,通过智能合约代码以实现去除…...

Vatee万腾外汇市场新力量:vatee科技决策力

在当今数字化时代,Vatee万腾崭露头角,以其强大的科技决策力进军外汇市场,成为该领域的新力量。这一新动向将不仅塑造外汇市场的未来,也展现Vatee科技决策力在金融领域的引领作用。 Vatee万腾带着先进的科技决策力进入外汇市场&…...

【HarmonyOS开发】配置开发工具DevEco Studio

1、下载 注意: 1、安装过程中,一定要自定义安装位置,包比较大,包比较大,包比较大!!! 2、可以将该工具添加到右键中,否则,如果你的项目不是HarmonyOS&#xff…...

探索亚马逊大语言模型:开启人工智能时代的语言创作新篇章

文章目录 前言一、大语言模型是什么?应用范围 二、Amazon Bedrock总结 前言 想必大家在ChatGPT的突然兴起,大家多多少少都会有各种各样的问题,比如:大语言模型和生成式AI有什么关系呢?大语言模型为什么这么火&#xf…...

zabbix-proxy分布式监控

Zabbix是一款开源的企业级网络监控软件,可以监测服务器、网络设备、应用程序等各种资源的状态和性能指标。在大型环境中,如果只有一个Zabbix Server来监控所有的节点,可能会遇到性能瓶颈和数据处理难题。 为了解决这个问题,Zabbi…...

springboot生成PDF,并且添加水印

/*** 导出调查问卷*/ApiLog("导出调查问卷")PostMapping("/print/{id}")ApiOperationSupport(order 23)ApiOperation(value "导出报告", notes "导出报告")public void print(PathVariable Long id, HttpServletResponse response…...

Tensorflow2.0:CNN、ResNet实现MNIST分类识别

以下仅是个人的学习笔记 ,内容可能是错误 CNN: import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers# 导入数据 (x_train, y_train), (x_test, y_test) keras.datasets.mnist.load_data()# 数据预处理 x_tra…...

本地jar导入maven

一、通过dependency引入 1.1. jar包放置&#xff0c;建造lib目录 1.2. pom.xml文件 <dependency><groupId>zip4j</groupId><artifactId>zip4j</artifactId><version>1.3.2</version><!--system&#xff0c;类似provided&#x…...

数据结构与算法【堆】的Java实现

前言 之前已经说过堆的特点了&#xff0c;具体文章在数据结构与算法【队列】的Java实现-CSDN博客。因此直接实现堆的其他功能。 建堆 所谓建堆&#xff0c;就是将一个初始的堆变为大顶堆或是小顶堆。这里以大顶堆为例。展示如何建堆。 找到最后一个非叶子节点从后向前&…...

同创永益联合红帽打造一站式数字韧性解决方案

随着AI技术的快速兴起&#xff0c;IT技术已成为推动业务持续增长的重要驱动力&#xff0c;这要求企业不断尝试新事物&#xff0c;改变固有流程&#xff0c;加强IT技术与业务的合作&#xff0c;同时提升数字韧性能力&#xff0c;以实现业务目标。10月26日&#xff0c;红帽2023中…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...