微前端——无界wujie

B站课程视频
课程视频

课程课件笔记:
1.微前端

2.无界

现有的微前端框架:iframe、qiankun、Micro-app(京东)、EMP(百度)、无届

前置

初始化

新建一个文件夹
1.通过npm i typescript -g安装ts
2.然后可以使用tsc --init初始化项目,这样项目目录下会有tsconfig.json配置文件
3.再新建index.ts
4.使用tsc -w命令可以实时的编译index.ts出一个index.js文件
5.通过index.html引入index.js即可

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./index.js"></script>
</head>
<body>
</body>
</html>

webComponents初使用

主要是为了样式隔离

wu-jie初体验

index.ts文件中书写

// webComponents 的写法
window.onload = () => {// 初始化class Wujie extends HTMLElement {// 类的基本用法constructor() {super()// this.attachShadow创建shadowdom并打开就具有样式隔离的性质,不会影响外层的样式let dom = this.attachShadow({mode: 'open'})// 获取templatelet template = document.querySelector('#wujie') as HTMLTemplateElement// 并绑定,这里是把template的内容深度克隆一份给dom,而不是直接给,true表示深度克隆dom.appendChild(template.content.cloneNode(true))// 这样就把template的内容渲染到了<wu-jie></wu-jie>的组件里面console.log(this.getAttr('url'), this.getAttr('age'))}// 获取传参this.getAttribute 传入属性名即可private getAttr(attr: string) {return this.getAttribute(attr)}}// webComponents挂载,注意名字不能启成驼峰的但是-横线连接可以,第二个参数是上面类的名字// 类似vue组件  原生js写的一个组件 可以在html中使用了<wu-jie></wu-jie>window.customElements.define('wu-jie', Wujie)
}

在上述建立的index.html中书写

<body><!-- 相当于组件,也可以传参 --><wu-jie url='xxxxx' age='18'></wu-jie><div>我是外层的div</div><template id="wujie"><div>我是 template 里面的div</div><style>div{background: red;}</style></template>
</body>

无届的三个生命周期

//生命周期自动触发有东西插入
connectedCallback () {console.log('类似于vue 的mounted');
}
//生命周期卸载
disconnectedCallback () {console.log('类似于vue 的destory');
}
//跟watch类似
attributeChangedCallback (name:any, oldVal:any, newVal:any) {console.log('跟vue 的watch类似,有属性发生变化自动触发');
}

pnpm介绍

1.全局安装npm i pnpm -g
2.使用 pnpm -v可以查看版本号
3.pnpmnpm的优势,在pnpm中文网的动机这样写pnpm官网
在这里插入图片描述
简单来说就是,但有100个vue项目,每个项目都会去安装相应的依赖包,这样导致磁盘的缩小和安装速度慢(每次都会重新下载依赖包),很麻烦。
但是pnpm使用软链接硬链接仓库解决

硬链接

1.使用cmd查看提示,表示 /H就是硬链接
在这里插入图片描述

2.创建命令含义 mklink /H 硬链接的名字 通过谁创建
例如:在pnpm文件目录下建立index.js文件,并通过mklink /H ying.js index.js创建了硬链接
在这里插入图片描述
3.并且目录下多出了一个ying.js
在这里插入图片描述

4.然后打开文件发现ying.js中内容和index.js中一样
在这里插入图片描述
5.而且当修改index.js中的内容时,ying.js中的内容会跟着修改,因为他们共享的同一个磁盘地址

软链接(符号链接)

1.创建软链接需要管理员权限,所以管理员打开cmd后进入目录可以使用cd ../../等回退到根目录下,然后直接 D: 进入相应盘,再cd命令
2.默认就是软链接 mklink ruan.js index.js 即可,不用加任何修饰符
在这里插入图片描述
3.成功创建后VScode中会有一个标志
在这里插入图片描述
4.且文件管理器中查看也是一个0字节的,因为他只记录一个路径(快捷方式,并不会占用资源),点击会跳转,指向的还是index.js
在这里插入图片描述

pnpm如何利用硬链接、软链接解决上述问题

1.使用pnpm init命令创建package.json
2.以安装vue包为例,使用pnpm i vue 安装vue依赖,可以看到node_modules下面有vue的软链接(快捷方式,地址指向)
在这里插入图片描述
3.实际上上述软链接指向在.pnpm包下找到真正的vue@3.3.13的包下面的vue文件夹,这个vue硬链接指向.pnpm store
在这里插入图片描述
4.实际上就对应了pnpm官网的这张图,非扁平化的方式(可能嵌入,因为这个库可能还依赖其他库,这样依次来)
在这里插入图片描述

绿色黄色实线为软链接、红色虚线为硬链接
在这里插入图片描述

pnpm的CLI命令管理

假设你之前使用的npm 安装包,会生成一个package-lock.json,或者使用yarn安装过,会生成一个yarn.lock

但是你再通过pnpm import命令 他会把你的上述的软件包管理器的 lockfile 生成 pnpm-lock.yaml文件

monorepo项目

创建monorepo项目目录

1.使用命令npm init vue创建vue项目,并创建项目名为main
2.创建web文件目录存放子应用
3.创建vue子应用,使用npm init vite选择vue+typescript
4.创建react子应用,使用npm init vite选择react+typescript
5.在web文件夹下有多个子应用,分别安装有点繁琐,所以在monorepo文件夹下使用命令pnpm init生成文件,并手动创建pnpm-workspace.yaml文件和配置。配置

官网是:
packages:# all packages in direct subdirs of packages/- 'packages/*'# all packages in subdirs of components/- 'components/**'# exclude packages that are inside test directories- '!**/test/**'替换为自己的目录
packages:# all packages in direct subdirs of packages/- 'main/*'# all packages in subdirs of components/- 'web/**'

此时目录如下:
在这里插入图片描述
6.替换好pnpm-workspace.yaml之后可以在根目录直接pnpm i即可自动为所有的项目安装包
最外层根目录下的node_modules是所有项目公共的包,而vue项目或者react项目里面的node_modules是他们单独所需要的,这样结构更加清晰。
在这里插入图片描述

子项目启动:

假设这时候我们要跨级执行命令,想要执行react-demo项目中package.jsondev命令,可以使用pnpm -F react-demo dev,其中F是过滤filter

子模块复用:

1.新建目录common下,并进入,想要common目录下的东西其余子项目(vue、react等都可以使用)
2.使用pnpm init初始化生成package.json文件。在pnpm-workspace.yaml中写

packages:# all packages in direct subdirs of packages/- 'main/*'# all packages in subdirs of components/- 'web/**'- 'common'

3.安装axios包了pnpm i axios
在这里插入图片描述
3.新建index.ts,编写一些公共代码

import axios from 'axios'// 公共的提取出来
export const a = axios.get('xxx')

4.进入main目录使用命令pnpm -F main add common则把common添加进main项目的依赖中,查看main/package.json文件里面有
在这里插入图片描述
5.然后就可以在main/src/main.ts中引入

import { a } from 'common'

6.同理,也可以去给react-demo项目添加或者vue-demo添加:pnpm -F vue-demo add common,一样查看那个package.json有common包,然后可以导入进行使用

无届

安装

1.使用pnpm i wujie,在main.ts中引入wujie并配置启动的参数

import { startApp } from 'node_modules/wujie/esm/index'
// 启动的参数
startApp({name, url, el})

2.如果是vue项目,可以直接安装npm i wujie-vue3进行安装

import Wujie from 'wujie-vue3'
app.use(router).use(Wujie)

3.然后分别启动好子应用,记录端口就可以在App.vue中使用了

<template><div><h1>这是主应用</h1><!-- 分别是子应用,子应用启动之后各自的端口 --><WujieVue url="http://127.0.0.1:5174" name="vue3"></WujieVue><WujieVue url="http://127.0.0.1:5175" name="react"></WujieVue></div>
</template>

在main.ts中,全部代码如下:

import './assets/main.css'import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import Wujie from 'wujie-vue3' // 引入一下对应的框架
import { preloadApp } from 'wujie'const app = createApp(App)app.use(router).use(Wujie) // 注册无界
app.mount('#app')// exac预加载为true即可,那么components/react.vue和vue3.vue就会有url
preloadApp({ name: "vue3", url: "http://127.0.0.1:5173", exec: true})
preloadApp({ name: "react", url: "http://127.0.0.1:5174", exec: true})

封装无届

1.创建的目录

封装无届

1.创建的目录文件如下:
其中使用pnpm init创建package.json
使用tsc --init创建 tsconfig.json
在这里插入图片描述
2.使用pnpm i wujie安装无届
3.使用pnpm i vue -D把vue装在开发环境中
4.安装webpack,使用pnpm i webpack webpack-cli -D
5.安装typescript,使用 pnpm i typescript -D
6.安装typescript解析器,使用pnpm i ts-loader -D

书写相关配置代码

配置代码部分可以看源码参照下面的代码

写完后使用 npm run lib 打包

1.在env.d.ts中书写

import { defineComponent, h, getCurrentInstance, onMounted, watch, onBeforeUnmount } from 'vue'
import type { App, PropType } from 'vue'
import { Props } from './type'
import { startApp, bus } from 'wujie'// 函数式定义组件
const wujie = defineComponent({props: {width: { type: String, default: "" },height: { type: String, default: "" },name: { type: String, default: "", required: true },loading: { type: HTMLElement, default: undefined },url: { type: String, default: "", required: true },sync: { type: Boolean, default: undefined },prefix: { type: Object, default: undefined },alive: { type: Boolean, default: undefined },props: { type: Object, default: undefined },attrs: { type: Object, default: undefined },replace: { type: Function as PropType<Props['replace']>, default: undefined },fetch: { type: Function as PropType<Props['fetch']>, default: undefined },fiber: { type: Boolean, default: undefined },degrade: { type: Boolean, default: undefined },plugins: { type: Array as PropType<Props['plugins']>, default: null },beforeLoad: { type: Function as PropType<Props['beforeLoad']>, default: null },beforeMount: { type: Function as PropType<Props['beforeMount']>, default: null },afterMount: { type: Function as PropType<Props['afterMount']>, default: null },beforeUnmount: { type: Function as PropType<Props['beforeUnmount']>, default: null },afterUnmount: { type: Function as PropType<Props['afterUnmount']>, default: null },activated: { type: Function as PropType<Props['activated']>, default: null },deactivated: { type: Function as PropType<Props['deactivated']>, default: null },},setup(props, { emit }) {// 读取当前组件实例// this.$refs.wujie // 在vue2中可以通过this获取当前组件实例const instance = getCurrentInstance() // vue3中通过getCurrentInstance获取组件实例// 封装启动函数const init = () => {// startApp({name, url, el})//初始化无界startApp({name: props.name,url: props.url,el: instance?.refs.wujie as HTMLElement,loading: props.loading,alive: props.alive,fetch: props.fetch,props: props.props,attrs: props.attrs,replace: props.replace,sync: props.sync,prefix: props.prefix,fiber: props.fiber,degrade: props.degrade,plugins: props.plugins,beforeLoad: props.beforeLoad,beforeMount: props.beforeMount,afterMount: props.afterMount,beforeUnmount: props.beforeUnmount,afterUnmount: props.afterUnmount,activated: props.activated,deactivated: props.deactivated,})}watch([props.name, props.url], () => {init() // 如果发生变化就重新执行startApp})const handlerEmit = (event:string, ...args:any[]) => {emit(event, ...args)}onMounted(() => {// 发布订阅模式bus.$onAll(handlerEmit) init()})onBeforeUnmount(() => {bus.$offAll(handlerEmit)})// 定义渲染函数return ()=> h('div', {style: {width: props.width,height: props.height},ref: "wujie" // 方便之后读取})}
})
// install 方法给vue使用的,app.use(router).use(wujie)会调用install
wujie.install = function(app: App) {app.component('WujieVue', wujie)
}export default wujie

2.type.ts中写

import type { plugin } from 'wujie'
type lifecycle = (appWindow: Window) => any;
interface Props {/** 唯一性用户必须保证 */name: string;/** 需要渲染的url */url: string;/** 需要渲染的html, 如果用户已有则无需从url请求 */html?: string;/** 渲染的容器 */loading?: HTMLElement;/** 路由同步开关, false刷新无效,但是前进后退依然有效 */sync?: boolean;/** 子应用短路径替换,路由同步时生效 */prefix?: { [key: string]: string };/** 子应用保活模式,state不会丢失 */alive?: boolean;/** 注入给子应用的数据 */props?: { [key: string]: any };/** js采用fiber模式执行 */fiber?: boolean;/** 子应用采用降级iframe方案 */degrade?: boolean;/** 自定义运行iframe的属性 */attrs?: { [key: string]: any };/** 自定义降级渲染iframe的属性 */degradeAttrs?: { [key: string]: any };/** 代码替换钩子 */replace?: (codeText: string) => string;/** 自定义fetch,资源和接口 */fetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>;/** 子应插件 */plugins: Array<plugin>;/** 子应用生命周期 */beforeLoad?: lifecycle;/** 没有做生命周期改造的子应用不会调用 */beforeMount?: lifecycle;afterMount?: lifecycle;beforeUnmount?: lifecycle;afterUnmount?: lifecycle;/** 非保活应用不会调用 */activated?: lifecycle;deactivated?: lifecycle;
};export { Props } 

3.webpack.config.js中写

const { Configuration } = require('webpack')
const path = require('path')/*** @type {Configuration} //配置智能提示*/const config = {entry: "./src/index.ts", // 入口文件mode: "none",output: {filename: "index.js",path: path.resolve(__dirname, 'lib')},externals: { // 防止打包后的代码包含wujie和vue代码显得过多vue: "vue",wujie: "wujie"},module: {rules: [{test: /\.ts$/,use: "ts-loader"}]}}module.exports = config

SWC和babel

SWC官网
1.swc比babel快20倍,如果是4核情况下,快70倍
使用pnpm add -D @swc/score swc-loader安装命令

2.然后替换webpack.config.js中的use

module: {rules: [{test: /\.ts$/,use: "ts-loader" // babel的ts-loader,换成swc-loader}]}

3.因为swc底层是rust写的,rust性能是js的好几倍所很快

4.然后再打包npm run lib打包后还不能直接使用,
因为前端有很多代码规范,AMD, CMD,CommonJS,ESModule,所以统一配置一个UMD,
5.安装pnpm i -D @swc/cli @swc/core以便使用swc-cli
6.新建配置文件.swcrc

{"$schema": "https://json.schemastore.org/swcrc","jsc": {"parser": {"syntax": "typescript", // js是ecmascript// "jsx": false,// "dynamicImport": false,// "privateMethod": false,// "functionBind": false,// "exportDefaultFrom": false,// "exportNamespaceFrom": false,// "decorators": false,// "decoratorsBeforeExport": false,// "topLevelAwait": false,// "importMeta": false},// "transform": null,"target": "es5","loose": false,"externalHelpers": false,// Requires v1.2.50 or upper and requires target to be es2016 or upper."keepClassNames": false},"minify": false}

7.在根目录的package.json的 scripts中编写打包命令写"esm": "swc src/index.ts -d esm",
8.控制台执行 npm run swc即可打包在esm文件中
9.修改增添package.json中
设定一些版本号和启动的入口

"name": "vuejie-setup",
"version": "0.0.1","main": "lib/index.js", 
"module": "esm/index.js",

添加files

"files": ["lib","esm","index.d.ts"],

10.在根目录下的index.d.ts声明文件中写

// import { bus, preloadApp, destroyApp, setupApp } from "wujie";
import type { App } from 'vue';declare const WujieVue: {// bus: typeof bus;// setupApp: typeof setupApp;// preloadApp: typeof preloadApp;// destroyApp: typeof destroyApp;install: (app: App) => void
};export default WujieVue;

发布包

1.切换镜像 mmp use,输入 npm
2.使用 npm adduser命令,然后输入npm的用户名
在这里插入图片描述
3.使用npm login
4.使用 npm publish发布

使用

1.在MONOREPO项目中切换进主应用cd main
2.命令安装pnpm i vuejie-setup
3.在main.ts中引入import Wujie from 'vuejie-setup'
4.使用npm run dev启动各种主应用或者子应用查看效果

无届的预加载和FPS

1.requestldleCallback函数
MDN的解释
在这里插入图片描述

2.FPS扩展
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

无届的传参

总共三种方法

第一种方法

无届的架构是把JS单独存放在了iframe中,那么iframe可以通过window和父级进行通讯,所以第一种传参就是通过
window.parent.变量名 进行读取。

1.在vue-demo/App.vue中添加按钮,绑定函数获取a

<script setup lang="ts">
const send = () => {alert(window.parent.a) //
}
</script>
<button @click="send">点击</button>

2.在控制台输入变量 var a = '控制台的输入'
3.点击按钮,发现可以弹出
在这里插入图片描述

在这里插入图片描述

第二种方法

通过props 传参,子应用不需要绑定无界,主应用接进来之后会自动捕获vue实例,所以子应用可以访问到无界实例对象获取参数

1.例如在主应用的components/App.vue组件中挂载数据,通过props传参

<template><WujieVue :props="{name: '张三', age: '18'}" url="http://127.0.0.1:5173" name="vue3"></WujieVue>
</template>

2.然后在vue-demo子项目中的App.vue中写JS代码

const send = () => {// alert(window.parent.a) // 第一种方法console.log(window.$wujie) // 第二种方式
}

3.为了防止上述$wujie报错,可以在main.ts中添加

declare global {interface Window {$wujie: {props:  Record<string, any>bus: {$emit: any}}}
}

4.打印的结果如下(可以看到还有bus,第三种方法获取)
在这里插入图片描述
4.上述可以访问props console.log(window.$wujie)进行打印

d第三种方案eventBus发布订阅

可以双向数据传递,直接使用wujie的bus.$on
1.在 主应用的App.vue中通过bus.$on绑定数据

<script lang="ts">
import { bus } from 'wujie'
bus.$on('vue3', (data: any) => {console.log(data, '我是主应用的bus.$on')
})
</script>

2.在子应用vue-demo的App.vue中通过实例直接使用

const send = () => {// alert(window.parent.a)// console.log(window.$wujie.props) // 获取到App.vue下的propswindow.$wujie.bus.$emit('vue3', '我是子应用vuedemo')
}

模块联邦

1.创建文件如下,目录
在这里插入图片描述

2.安装下面四个依赖包
npm i webpack webpack-cli webpack-server html-webpack-plugin -D
在这里插入图片描述
3.书写代码,略,结果如下,总之host里面没有的List数据却通过引入到了remote的数据进行展示
在这里插入图片描述
在这里插入图片描述
4.pnpm run build进行打包host项目下
点开dist/bundle.js,可以看到使用CDN的方式进行引入的
在这里插入图片描述
之前:10个项目引用同一个模块,通过把这个项目发布到npm上面,然后这是个项目可以install这个模块,但是当这个模块发生改变的时候,例如从1.0.0 -> 1.0.1,那么这十个项目得重新下载install一遍
现在的CDN,当你的模块修改了,直接就是最新的版本,通过这个链接,远程调用联邦的技术正是用的这种

报错

1.在tsconfig.app.json中报错:没有 “node” 模块解析策略的情况下,无法指定选项 “-resolveJsonModule”。

修改tsconfig.app.json 文件中 compilerOptions 选项配置 “moduleResolution”: “node”

{"extends": "@vue/tsconfig/tsconfig.dom.json","include": ["env.d.ts", "src/**/*", "src/**/*.vue"],"exclude": ["src/**/__tests__/*"],"compilerOptions": {"composite": true,/** 模块解析策略,ts默认用node的解析策略,即相对的方式导入, 可选值:node、classic* 如果未指定,则 --module commonjs 默认为 node,否则默认为 classic(包括 --module 设置为 amd、system、umd、es2015、esnext 等)* Node 模块解析是 TypeScript 社区中最常用的,推荐用于大多数项目。 * 如果您在 TypeScript 中遇到导入和导出的解析问题,请尝试设置 moduleResolution: “node” 以查看它是否解决了问题。*/"moduleResolution": "node",    "baseUrl": ".","paths": {"@/*": ["./src/*"]}}
}

参考自

一些文件爆红

1.找不到模块“./App.vue”或其相应的类型声明
2.ts.config.app.json找不到文件vue tsconfig tsconfig dom json

如果报错vite找不到之类的,以及奇怪的错误请删除两个子应用重新建立和安装和初始化最外层的包pnpm init

ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL vue-demo@0.0.0 dev: `vite` Exit status 1

一些常用的命令

pnpm i 和 pnpm init

pnpm i是 pnpm install的简写,表示安装包,会根据package.json的包版本进行安装,
pnpm init是初始化一个项目,一般只会在空项目文件下创建package.json一些必要的包

pnpm run dev 和 pnpm run start

前者是开发环境,后者是打包之后的生产环境运行项目

使用脚手架建立项目

因为涉及诸多配置,建议按照vite、webpack官网来看

使用vite脚手架建立vue、react项目

使用webpack脚手架建立vue、react项目

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/223896.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA控制台乱码

报错情况&#xff1a; 报错原因&#xff1a;Idea的vm用的编码格式不一致&#xff1a;需要修改为UTF-8 你看Tomcat我之前下在后修改果&#xff0c;就没有报错&#xff0c;新人刚下载也有乱码问题 问题解决&#xff1a; 按我步骤来一定对 下面这俩文件打开输入&#xff1a; -D…

CSS-SVG-环形进度条

线上代码地址 <div class"circular-progress-bar"><svg><circle class"circle-bg" /><circle class"circle-progress" style"stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" …

esp32使用lvgl,给图片取模显示图片

使用LVGL官方工具。 https://lvgl.io/tools/imageconverter 上传图片&#xff0c;如果想要透明效果&#xff0c;那么选择 输出格式C array&#xff0c;点击Convert进行转换。 下载.c文件放置到工程下使用即可。

Java开发框架和中间件面试题(1)

1.什么是Spring框架&#xff1f; Spring是一种轻量级框架&#xff0c;旨在提高开发人员的开发效率以及系统的可维护性。 我们一般说的Spring框架就是Spring Framework,它是很多模块的集合&#xff0c;使用这些模块可以很方便的协助我们进行开发。这些模块是核心容器、数据访…

3.[BUUCTF HCTF 2018]WarmUp1

1.看题目提示分析题目内容 盲猜一波~ &#xff1a; 是关于PHP代码审计的 2.打开链接&#xff0c;分析题目 给你提示了我们访问source.php来看一下 大boss出现&#xff0c;开始详细手撕~ 3.手撕PHP代码&#xff08;代码审计&#xff09; 本人是小白&#xff0c;所以第一步&…

解读SPP / SPPF / SimSPPF / ASPP / RFB / SPPCSPC

SPP与SPPF 一、SPP的应用的背景 在卷积神经网络中我们经常看到固定输入的设计&#xff0c;但是如果我们输入的不能是固定尺寸的该怎么办呢&#xff1f; 通常来说&#xff0c;我们有以下几种方法&#xff1a; &#xff08;1&#xff09;对输入进行resize操作&#xff0c;让他们…

案例144:基于微信小程序的自修室预约系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

Unity手机移动设备重力感应

Unity手机移动设备重力感应 一、引入二、介绍三、测试成果X Y轴Z轴横屏的手机&#xff0c;如下图竖屏的手机&#xff0c;如下图 一、引入 大家对重力感应应该都不陌生&#xff0c;之前玩过的王者荣耀的资源更新界面就是使用了重力感应的概念&#xff0c;根据手机的晃动来给实体…

Latex生成的PDF中加入书签/Navigation/导航

本文参考&#xff1a;【Latex学习】在生成pdf中加入书签/目录/提纲_latex 书签-CSDN博客 &#xff08;这篇文章写的真的太棒了&#xff01;非常推荐&#xff09; 题外话&#xff0c;我的碎碎念&#xff0c;这也是我如何提高搜索能力的办法&#xff1a;想在Latex生成的PDF中加入…

2023美团机器人研究院学术年会成功举办

2023年12月19日&#xff0c;深圳市美团机器人研究院学术年会在清华大学深圳国际研究生院成功落下帷幕。会议回顾了研究院成立一年来的进展和成果&#xff0c;并邀请了各界专家共同讨论机器人技术的未来发展趋势。此外&#xff0c;年会期间还举办了首届低空经济智能飞行管理挑战…

【网络安全/CTF】unseping 江苏工匠杯

该题考察序列化反序列化及Linux命令执行相关知识。 题目 <?php highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method $method;$this->args $args;}function __destruct(){if (in_array($thi…

安洵杯 re + 其他部分题解

第11&#xff0c;比较小丑&#xff0c;差了一步队伍wp应该会发吧&#xff0c;不知道&#xff0c;我先放点跟我有关系的 Re mobilego so的check看了一会比较南崩&#xff0c;但是看flag的密文形式很像简单位置替换所以直接输编码表&#xff0c;jeb动调然后得到替换表解密就行…

CnosDB:深入了解时序数据处理函数

CnosDB 是一个专注于时序数据处理的数据库&#xff0c;旨在解决时序数据存储与分析问题&#xff0c;为用户提供高效的时序数据管理与查询便利。为了实现这一目标&#xff0c;CnosDB 实现了一系列专用函数&#xff0c;快来和CC一起来看看吧&#xff01; CnosDB&#xff1a;深入了…

PHP下载安装以及基本配置

目录 引言 官网 下载 配置 1. 鼠标右键“此电脑”>“属性” 2. 打开高级系统设置 3. 打开环境变量 4. 双击系统变量中的path 5. 新建新的path 6. 将刚刚安装的位置加入环境变量 7. 检查是否安装成功 引言 PHP&#xff08;"PHP: Hypertext Preprocessor"…

Python-基于fastapi实现SSE流式返回(类似GPT)

最近在做大模型对话相关功能&#xff0c;需要将对话内容流式返回给前端页面&#xff08;类似GPT的效果&#xff09;。下面直接说下如何实现&#xff1a; 1.首先导入fastapi和sse流式返回所需要的包 from fastapi import APIRouter, Response, status from sse_starlette.sse …

指针的含义

我们还取前面图片解释的道理&#xff1a; pa表示的意思就是这个地址&#xff0c;并不会显示出10这个数字 *pa就是指针&#xff0c;最后指向了a10&#xff0c;所以他最后程序输出是10 &pa这个含义就是取pa的地址&#xff0c;那么pa是一个虚拟的地址&#xff0c;只是简单的…

鸿蒙开发语言介绍--ArkTS

1.编程语言介绍 ArkTS是HarmonyOS主力应用开发语言。它在TypeScript (简称TS)的基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 2.TypeScript简介 自行补充TypeScript知识吧。h…

AndroidStudio无法新建aidl文件解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 右键新建 aidl 文件&#xff0c; 提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file 解决办法 修改 app 的 build.…

python画图【03】泰坦尼克号数据分析

导包 import numpy as np import pandas as pdimport matplotlib import matplotlib.pyplot as plt %matplotlib inlineplt.rcParams[font.sans-serif] "Microsoft YaHei"import seaborn as sns加载数据集 titanic sns.load_dataset("titanic")titanic…

分布式事务2PC二阶段提交详解

文章目录 概述和概念执行过程和工作流程特点优劣势应用场景总结demo代码样例 概述和概念 二阶段提交&#xff08;2PC&#xff09;是一种用于确保在分布式系统中的所有节点在进行事务提交时保持一致性的算法 二阶段提交&#xff08;Two-Phase Commit&#xff0c;2PC&#xff09…