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

微前端中的 CSS

本文为翻译 本文译者为 360 奇舞团前端开发工程师
原文标题:CSS in Micro Frontends 原文作者:Florian Rappl 原文地址:https://dev.to/florianrappl/css-in-micro-frontends-4jai

我被问得最多的问题之一是如何在微前端中处理 CSS。毕竟,样式始终是任何UI片段所需要的东西,然而,它也是全局共享的东西,因此它是潜在的冲突来源。

在这篇文章中,我想回顾一下现有的不同策略来驯服 CSS 并使其扩展以开发微前端。如果这里的任何内容对您来说听起来合理,那么也可以考虑研究“微前端的艺术”。

本文的代码可以在github.com/piral-samples/css-in-mf找到。请务必检查示例实现。

CSS 的处理是否会影响每个微前端解决方案?让我们检查可用的类型来验证这一点。

微前端的类型

过去我写了很多关于存在哪些类型的微前端、为什么存在以及何时应该使用什么类型的微前端架构的文章。采用 Web 方法意味着使用 iframe 来使用来自不同微前端的 UI 片段。在这种情况下,没有任何限制,因为无论如何每个片段都是完全隔离的。在任何其他情况下,无论您的解决方案使用客户端还是服务器端组合(或介于两者之间的东西),您最终都会得到在浏览器中评估的样式。因此,在所有其他情况下,您都会关心 CSS。让我们看看这里有哪些选项。

无特殊处理

好吧,第一个也许是最(或根据观点,最不)明显的解决方案是不进行任何特殊处理。相反,每个微前端都可以附带额外的样式表,然后在渲染微前端的组件时附加这些样式表。

理想情况下,每个组件仅在首次渲染时加载所需的样式,但是,由于这些样式中的任何一个都可能与现有样式冲突,我们也可以假装在微前端的任何组件渲染时加载所有有问题的样式。6d3a56beac7bbf20dd3cbea51dae2434.png这种方法的问题在于,当给出诸如div或之类的通用选择器时div a,我们还将重新设计其他元素的样式,而不仅仅是原始微前端的片段。更糟糕的是,类和属性也不是故障保护措施。类似的类.foobar也可以用在另一个微前端中。您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为solutions/default。

摆脱这种痛苦的一个好方法是进一步隔离组件————就像 Web 组件一样。

Shadow DOM

在自定义元素中,我们可以打开一个shadow root来将元素附加到专用的迷你文档,该迷你文档实际上与其父文档相互隔离。总的来说,这听起来是一个好主意,但与这里介绍的所有其他解决方案一样,并没有强制要求。1f9f911668a852117754e14890db7ce1.png理想情况下,微前端可以自由决定如何实现组件。因此,实际的 Shadow DOM 集成必须由微前端完成。

使用 Shadow DOM 有一些缺点。最重要的是,虽然 Shadow DOM 内部的样式保留在内部,但全局样式也不会影响 Shadow DOM。乍一看,这似乎是一个优势,但是,由于整篇文章的主要目标只是隔离微前端的样式,因此您可能会错过诸如应用某些全局设计系统(例如 Bootstrap)之类的要求。link要使用 Shadow DOM 进行样式设置,我们可以通过引用或标签将样式放入 Shadow DOM 中style。由于 Shadow DOM 是无样式的,并且外部的样式不会传播到其中,因此我们实际上需要它。除了编写一些内联样式之外,我们还可以使用捆绑器将.css(或者类似的东西.shadow.css)视为原始文本。这样,我们只会得到一些文本。

piral-cli-esbuild对于 esbuild,我们可以配置如下的预制配置:

module.exports = function(options) {options.loader['.css'] = 'text';options.plugins.splice(0, 1);return options;
};

这会删除初始 CSS 处理器 (SASS) 并为.css文件配置标准加载器。现在,shadow DOM 中的某些样式的工作方式如下:

import css from "./style.css";customElements.define(name, class extends HTMLElement {constructor() {super();this.attachShadow({ mode: "open" });}connectedCallback() {this.style.display = "contents";const style = this.shadowRoot.appendChild(document.createElement('style'));style.textContent = css;}});

上面的代码是一个有效的自定义元素,从样式的角度来看它将是透明的(display: contents),即只有其内容会反映在渲染树中。它托管一个包含单个style元素的Shadow DOM。style 的内容设置为style.css文件的文本内容。

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为solutions/shadow-dom。

域组件避免使用Shadow DOM 的另一个原因是,并不是每个 UI 框架都能够处理Shadow DOM 中的元素。因此,无论如何都必须寻找一种替代方案。其中一种方式是转而使用一些 CSS 约定。

使用命名约定

如果每个微前端都遵循全局CSS约定,那么就可以在根上避免冲突。最简单的约定是在每个类前面加上微前端的名称。例如,如果调用一个微前端shopping,并调用另一个微前端checkout,则两者都会将其active类分别重命名为shopping-active/ checkout-active。1f30106c0feb12b53137a965c7b273e9.png

这同样适用于其他可能存在冲突的名称。例如,如果有一个名为 shopping 的微前端,那么我们可以将主按钮的ID从 primary-button 改为 shopping-primary-button。如果因某种原因需要为一个元素添加样式,我们应该使用后代选择器,例如 .shopping img,来为 img 标签添加样式。这样会应用于具有 shopping 类的元素内部的 img 元素。这种方法的问题在于 shopping 微前端可能还会使用其他微前端的元素。如果我们看到 div.shopping > div.checkout img,即使通过 checkout 微前端引入的组件承载/集成了 img,它仍然会受到 shopping 微前端 CSS 的样式影响。这并不理想。

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为https://github.com/piral-samples/css-in-mf/tree/main/solutions/default。

尽管命名约定在一定程度上解决了问题,但它们仍然容易出错并且使用起来很麻烦。如果我们重命名微前端会怎样?如果微前端在不同的应用程序中获得不同的名称怎么办?如果我们在某些时候忘记应用命名约定怎么办?这就是工具帮助我们的地方。

CSS Modules

自动添加前缀并避免命名冲突的最简单方法之一是使用 CSS 模块。根据您选择的打包工具,这可能是开箱即用的功能,或者通过更改一些配置实现。5085c59378d1f37d66fe1e56ee330d6e.png

// Import "default export" from CSSimport styles from './style.modules.css';// Apply<div className={styles.active}>Active</div>

导入的模块是一个生成的模块,将原始类名(例如 active)映射到生成的类名。生成的类名通常是CSS规则内容与原始类名混合后的哈希值。这样,生成的类名应该尽可能唯一.

例如,让我们考虑一个使用esbuild构建的微前端. 对于esbuild,您需要一个插件(esbuild-css-modules-plugin)和相应的配置更改来包含 CSS 模块。

使用Piral我们只需要调整已有的配置piral-cli-esbuild。我们删除标准 CSS 处理(使用 SASS)并替换为插件:

const cssModulesPlugin = require('esbuild-css-modules-plugin');module.exports = function(options) {options.plugins.splice(0, 1, cssModulesPlugin());return options;
};

现在我们可以像上面展示的那样在我们的代码中使用 CSS 模块了。

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为solutions/css-modules。

使用 CSS 模块会带来一些缺点。首先,它引入了几个语法扩展来区分我们想要导入的样式(因此需要进行预处理/哈希)和应保持原样的样式(即稍后无需导入即可使用的样式) 另一种方式是将 CSS 直接引入到 JS 文件中。

CSS-in-JS

CSS-in-JS 最近的名声很差,但是,我认为这是一个误解。我也更喜欢将其称为“CSS-in-Components”,因为它为组件本身带来了样式。一些框架(Astro、Svelte 等)甚至允许通过其他方式直接执行此操作。经常被提及的缺点是性能问题,这通常是由于在浏览器中编写 CSS 造成的。然而,这并不总是必要的,在最好的情况下,CSS-in-JS 库实际上是构建时间驱动的,即没有任何性能缺陷。b9a8afece3f89185cd367bca2d291685.png然而,当我们谈论 CSS-in-JS(或 CSS-in-Components)时,我们需要考虑现有的各种选择。为简单起见,我只包含三个:Emotion、Styled Components和Vanilla Extract。让我们看看它们如何帮助我们在一个应用程序中将多个微前端整合在一起时避免冲突。

Emotion

Emotion 是一个非常棒的库,它为诸如React之类的框架提供了辅助功能,但并不要求将这些框架设置为先决条件。Emotion可以很好地优化和预先计算,并允许我们使用各种可用的 CSS 技术。

使用“pure”Emotion相对来说很简单;首先安装包:

npm i @emotion/css

现在您可以在代码中使用它,如下所示

import { css } from '@emotion/css';const tile = css`background: blue;color: yellow;flex: 1;display: flex;justify-content: center;align-items: center;`;// later<div className={tile}>Hello from Blue!</div>

css 助手允许我们编写 CSS,将其解析并放置在样式表中。返回值是生成的类名。

如果我们特别想使用 React,我们还可以使用Emotion 中的 jsx 工厂(引入一个名为 css 的新标准属性)或 styled 助手:

npm i @emotion/react @emotion/styled

现在感觉很像样式是 React 本身的一部分。例如,styled助手允许我们定义新组件:

const Output = styled.output`border: 1px dashed red;padding: 1rem;font-weight: bold;`;// later<Output>I am groot (from red)</Output>

相反,css助手属性使我们能够缩短表示法:

<div css={`background: red;color: white;flex: 1;display: flex;justify-content: center;align-items: center;`}>Hello from Red!</div>

总而言之,这生成的类名不会冲突,并提供了避免样式混乱的强大性能。特别是 styled 助手深受流行的 styled-components 库的启发。

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为:solutions/emotion。

Styled Components

styled-components库可以说是最受欢迎的CSS-in-JS解决方案,而且往往也是这类解决方案声誉不佳的原因。从历史上看,它实际上是关于在浏览器中组合CSS,但在过去几年中,它们确实在这方面取得了巨大进展。现在,您也可以对所使用的样式进行一些非常好的服务器端组合.

与emotion相比,styled-components库(对于React)需要安装一些少量的包。唯一的缺点是类型定义是事后添加的,因此您需要安装两个包以获得完整的TypeScript支持:

npm i styled-components --save
npm i @types/styled-components --save-dev

安装后,该库就已经完全可用:

import styled from 'styled-components';const Tile = styled.div`background: blue;color: yellow;flex: 1;display: flex;justify-content: center;align-items: center;
`;// later
<Tile>Hello from Blue!</Tile>

原理与 相同emotion。因此, 让我们探讨另一种尝试从一开始就实现零成本的选择, 而不是事后添加的.您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为: solutions/styled-components

Vanilla Extract

我之前提到的利用类型接近组件并避免不必要的运行时成本的方法正是最新一代的CSS-in-JS库所涵盖的。其中最有潜力的库之一是@vanilla-extract/css。它允许你在JavaScript中直接编写CSS,并静态提取类名,从而减小打包大小,提高性能。这是一种有前途的选择,可以以类型安全和高效的方式管理样式。使用该库有两种主要方式:

  • 与你的打包工具/框架集成

  • 直接使用 CLI 在这个例子中,我们选择了第一种方式———— 通过与 esbuild 集成。为了使集成正常工作,我们需要使用该@vanilla-extract/esbuild-plugin包。现在我们将其集成到构建过程中。使用piral-cli-esbuild配置, 我们只需要将其添加到配置的插件中即可:

const { vanillaExtractPlugin } = require("@vanilla-extract/esbuild-plugin");module.exports = function (options) {options.plugins.push(vanillaExtractPlugin());return options;
};

为了使 Vanilla Extract 正常工作,我们需要编写.css.ts文件而不是普通文件.css或.sass文件。这样的文件可能如下所示:

import { style } from "@vanilla-extract/css";
export const heading = style({color: "blue",
});

这是有效的 TypeScript 代码。最终我们将获得一个类名的导出————就像我们从 CSS modules、Emotion 等中获得的那样。因此,最终,上述样式将会应用如下:

import { heading } from "./Page.css.ts";// later
<h2 className={heading}>Blue Title (should be blue)</h2>

这将在构建时完全处理,不会有任何运行时成本。

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为:solutions/vanilla-extract。

您可能会感兴趣的另一种方法是使用 CSS 实用程序库,例如 Tailwind。

CSS 实用程序,例如 Tailwind

这是一个独立的类别,但考虑到Tailwind是该类别中的主导工具,我只会介绍Tailwind。Tailwind的主导地位甚至到了一些人问“你是写CSS还是Tailwind?”这样的地步。这与2010年左右jQuery在DOM操作领域的主导地位非常相似,当时人们会问“这是JavaScript还是jQuery?”

无论如何,使用CSS实用库的优势在于样式是基于使用而生成的。这些样式不会冲突,因为它们始终由实用库以相同的方式定义。因此,每个微前端只需提供所需的实用库部分,以按预期显示微前端。

3121f301c0417bf7d6f6df39eb355f50.png如果使用 Tailwind 和 esbuild,我们还需要安装以下软件包:

npm i autoprefixer tailwindcss esbuild-style-plugin

esbuild的配置比以前略微复杂一些。esbuild-style-plugin本质上是esbuild的一个PostCSS插件,所以必须正确配置

const postCssPlugin = require("esbuild-style-plugin");module.exports = function (options) {const postCss = postCssPlugin({postcss: {plugins: [require("tailwindcss"), require("autoprefixer")],},});options.plugins.splice(0, 1, postCss);return options;
};

在这里,我们移除了默认的CSS处理插件(SASS),并用PostCSS插件替代它——同时使用autoprefixer和tailwindcss这两个PostCSS扩展。现在我们需要添加一个有效的tailwind.config.js文件:

module.exports = {content: ["./src/**/*.tsx"],theme: {extend: {},},plugins: [],
};

这本质上是配置 Tailwind 的最低要求。它只是提到tsx应该扫描文件以了解 Tailwind 实用程序类的使用情况。然后找到的类将被放入 CSS 文件中。

因此,CSS 文件还需要知道生成/使用的声明应包含在哪里。作为最低要求,我们只有以下CSS内容:

@tailwind utilities;

还有其他@tailwind指令。例如,Tailwind自带一个重置和基础层。但是,在微前端中,我们通常不关心这些层。这属于应用程序 shell 或编排应用程序的关注范围,而不是领域应用程序的关注点。

然后,CSS将被来自Tailwind中已经指定的类所替代:

<div className="bg-red-600 text-white flex flex-1 justify-center items-center">Hello from Red!</div>

您将在引用的演示存储库中找到两个冲突的微前端的示例,网址为solutions/tailwind。

比较

到目前为止,所提出的几种方法都是微前端的可行选择。总的来说,这些解决方案也可以混合使用。一个微前端可以采用Shadow DOM方法,而另一个微前端可以使用Emotion。第三个库可能会选择Vanilla Extract。最重要的是所选择的解决方案不会产生冲突,并且没有(巨大的)运行时成本。虽然有些方法比其他方法更高效,但它们都提供了所需的样式隔离性。73d26ca8764ee8b533da012f058c74c5.png性能影响在很大程度上取决于实现方式。例如,对于CSS-in-JS,如果解析和组合都在运行时完成,可能会产生很大的性能影响。如果样式已经预解析,只在运行时组合,则可能性能影响较小。对于类似Vanilla Extract这样的解决方案,几乎没有任何性能影响。

对于 Shadow DOM,主要的性能影响可能是 Shadow DOM 内部元素的投影或移动(本质上为零)以及标签的重新评估style。然而,这是相当低的,甚至可能会产生一些性能优势,给定的样式总是切中要害,并且仅专用于要在Shadow DOM 中显示的某个组件。在示例中,我们有以下捆绑包大小:73650352a765ceb7838ab49d31731305.png对于Emotion和Styled Components,这些数字仅供参考,因为运行时可能(并且很可能应该)被共享。此外,给定的微前端示例确实很小(所有UI片段的总大小为3KB)。对于一个更大的微前端,增长肯定不会像这里描述的那样成为问题。

Shadow DOM解决方案的大小增加可以解释为我们提供的简单实用脚本,用于将现有的React渲染轻松包装到Shadow DOM中(而不创建新的树结构)。如果这样的实用脚本在中心共享,那么其大小将更接近于其他更轻量级的解决方案。

结论

在微前端解决方案中处理CSS并不需要变得困难,只需要从一开始就以有结构、有序的方式进行处理,否则就会出现冲突和问题。通常情况下,建议选择 CSS 模块、Tailwind 或可扩展的 CSS-in-JS 实现等解决方案.

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

683a6f879d6e6c70c096410189d08f31.png

相关文章:

微前端中的 CSS

本文为翻译 本文译者为 360 奇舞团前端开发工程师原文标题&#xff1a;CSS in Micro Frontends 原文作者&#xff1a;Florian Rappl 原文地址&#xff1a;https://dev.to/florianrappl/css-in-micro-frontends-4jai 我被问得最多的问题之一是如何在微前端中处理 CSS。毕竟&…...

在CSDN学Golang场景化解决方案(分布式日志系统)

一&#xff0c;传统 elk 解决方案及其弊端 传统ELK&#xff08;Elasticsearch Logstash Kibana&#xff09;方案是一种流行的分布式日志系统解决方案&#xff0c;但也存在一些弊端&#xff1a; 依赖性&#xff1a;ELK使用Java编写&#xff0c;需要安装JVM&#xff0c;并且还…...

电脑第一次使用屏幕键盘

操作流程 1.在键盘上同时按WinR打开运行; 2.输入control 3.找到设置中心 4.点击屏幕键盘 效果 具体怎么使用 我不咋清除 简单 测试了一下 可以用鼠标点击屏幕键盘的按键 用键盘 按字母键和数字键 是和屏幕键盘不同步的 其他 tab、shift、后退、enter好像同步...

【C#学习笔记】类型转换

文章目录 类型转换字符转数字GetNumericValueConvert.ToInt32隐式转换计算 字符串转数字Parse 或 TryParse 方法 字节数组转整数 as&#xff0c;is强制类型转换isas 用户定义的转换 类型转换 我们简单地将值类型分为5种&#xff1a;整数型&#xff0c;浮点型&#xff0c;布尔型…...

SpringBoot+SSM实战<一>:打造高效便捷的企业级Java外卖订购系统

文章目录 项目简介项目架构功能模块管理端用户端 技术选型用户层网关层应用层数据层工具 项目优缺点结语 黑马程序员最新Java项目实战《苍穹外卖》&#xff1a;让你轻松掌握SpringBootSSM的企业级开发技巧项目简介 《苍穹外卖》是一款为餐饮企业&#xff08;餐厅、饭店&#x…...

笙默考试管理系统-MyExamTest--calculagraph

笙默考试管理系统-MyExamTest--calculagra&#xff08;1&#xff09; 目录 一、 笙默考试管理系统-MyExamTest--calculagra 二、 笙默考试管理系统-MyExamTest--calculagra 三、 笙默考试管理系统-MyExamTest--calculagra 四、 笙默考试管理系统-MyExamTest--calculagra …...

Mysql面试突击班索引,事务与锁

Mysql面试突击班索引&#xff0c;事务与锁 1.为什么Mysql要使用B树做为索引而不用B树 B树能显著减少IO次数&#xff0c;提高效率B树的查询效率更加稳定&#xff0c;因为数据放在叶子节点B树能提高范围查询的效率&#xff0c;因为叶子节点指向下一个叶子节点B树采取顺序读 2.…...

数据结构——AVL树

文章目录 一.AVL树的定义二.AVL树的插入三.插入后更新平衡因子四.AVL树的旋转1.左单旋2.右单旋3.先左单旋再右单旋4.先右单旋再左单旋 五.AVL树的性能分析六.检查是否满足AVL树七.源码 一.AVL树的定义 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉…...

AI写作宝有哪些,分享两种AI写作工具

AI写作宝是一种基于人工智能技术的写作辅助工具。它可以根据用户输入的关键词和主题快速生成文章。AI写作宝可以为用户节省大量的时间和精力&#xff0c;帮助用户快速生成高质量的文章。今天就为大家推荐两款AI写作宝&#xff1a; 一、AI创作家 AI创作家是一款基于人工智能技…...

【uniapp 控制页面滑动速度】

可以使用 uni-app 提供的 onTouchMove 事件来控制页面滑动速度。 可以在 onTouchMove 事件方法中使用 event.deltaY 计算页面滑动的速度&#xff0c;然后根据需要来调整速度值&#xff0c;最后通过 event.preventDefault() 阻止默认的滑动行为&#xff0c;从而实现控制页面滑动…...

7-24 整数的分类处理 (20 分)

7-24 整数的分类处理 &#xff08;20 分) 给定 N 个正整数&#xff0c;要求你从中得到下列三种计算结果&#xff1a; A1 能被 3 整除的最大整数 A2 存在整数 K 使之可以表示为 3K1 的整数的个数 A3 存在整数 K 使之可以表示为 3K2 的所有整数的平均值&#xff08;精确到小数…...

MYSQL事务同时修改单条记录

疑问&#xff1a;Mysql多事务默认情况下&#xff0c;同时修改同一条记录运行修改吗&#xff1f;是否要手动加上for update行锁。 猜想&#xff1a;MySQL 会自动对涉及的数据行加上写锁&#xff08;排他锁&#xff09;&#xff0c;以确保数据的一致性和隔离性。这是在默认的事务…...

安装skywalking并集成到微服务项目

文章目录 一、前言二、介绍1. 架构 三、安装skywalking服务端四、启动skywalking服务端五、微服务项目开发注册中心网关服务商品服务订单服务支付服务测试 六、下载java客户端七、微服务集成skywalking客户端1. idea启动2. 命令行启动3. 集成效果4. 服务实例5. 修改服务实例名称…...

一支笔,一双手,一道力扣(Leetcode)做一宿

文章目录 一、分享自己相关的经历二、分析可能存在的问题三、根据问题进行分解或建立思维导图四、分享好用的刷题网站并进行介绍 一、分享自己相关的经历 我是一名计算机专业的学生&#xff0c;之前在学习算法和数据结构时&#xff0c;对于简单题目还算能够顺利地刷过去。但是…...

Kubernetes(K8s)从入门到精通系列之九:使用kubeadm工具快速安装K8s集群

Kubernetes K8s从入门到精通系列之九:使用kubeadm工具快速安装K8s集群 一、安装kubeadm二、修改kubeadm的默认配置三、下载K8s相关镜像四、运行kubeadm imit命令安装Master节点五、将新的Node加入集群六、安装CNI网络插件七、验证K8s集群是否工作正常八、搭建高可用K8s集群详细…...

RabbitMQ 教程 | 第11章 RabbitMQ 扩展

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…...

一分钟完成centos7安装docker

action: 1、下载安装包2、安装docker 1、背景 使用CentOS / Redhat 7 版本的应该偏多。但是&#xff0c;Docker CE在系统中安装的时候&#xff0c;往往会出现一堆依赖包的报错&#xff0c;解决依赖包需要耗费不短的时间。 经验证&#xff0c;目前已找到兼容能力强的版本&am…...

NativePHP:使用PHP构建跨平台桌面应用的新框架

NativePHP是一个用于使用PHP构建桌面应用的框架。它允许PHP开发人员使用熟悉的工具和技术创建跨平台的原生应用。NativePHP具有一系列易于使用的类&#xff0c;一套用于构建和打包应用程序的工具以及一个静态跨平台PHP运行时。 官网地址&#xff1a;https://nativephp.comNati…...

删除这4个文件夹,流畅使用手机无忧

在现代社会中&#xff0c;手机已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着使用时间的增长&#xff0c;我们可能会遇到手机卡顿和内存不足的问题&#xff0c;让我们感到十分困扰。手机卡顿不仅影响使用体验&#xff0c;还可能导致应用程序运行缓慢&#xff0c;甚…...

使用Bert预训练模型处理序列推荐任务

最近的工作有涉及该任务&#xff0c;整理一下思路以及代码细节。 流程 总体来说思路就是首先用预训练的bert模型&#xff0c;在训练集的序列上进行CLS任务。对序列内容&#xff08;这里默认是token id的sequence&#xff09;以0.3左右的概率进行随机mask&#xff0c;然后将相…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

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

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...