瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案
本文样式方案学习了 cssModules 解决样式冲突的基本原理,并在此基础上改进以达到缩减样式文件 Size 的目的。
作者简介
(资料图)
Can,携程前端开发,目前从事小程序开发工作,对编译打包技术、小程序跨平台解决方案有浓厚兴趣。
一、概述
目前我们团队小程序是使用 Taro 跨端方案 React 框架进行开发,基于现有样式方案,在编译打包后会产生大量的样式代码冗余,在项目编译后的产物中占有较大比例。
分析了编译后的样式代码后,我们发现冗余代码主要体现在两个方面:
项目样式文件中大量使用了父子选择器作为作用域进行样式隔离,编译后出现类名大量重复冗余。如以下 SCSS 文件样式代码中,编译后.box .item重复冗余了三次。// 编译前代码.box { .item { .item1 {} .item2 {} .item3 {} .item4 {} }}// 编译后代码.box .item .item1 {}.box .item .item2 {}.box .item .item3 {}.box .item .item4 {}
样式代码中大量属性值重复冗余。如最常用的display: flex属性值,在项目中可能存在几百上千份重复冗余,而且为了兼容性开启了 Autoprefixer 插件后,display:flex将会变成display:-webkit-flex;display:-ms-flexbox;display:flex;,使得样式文件属性值的冗余情况更为严重。针对 Taro项目 React 框架小程序遇到的以上问题,本文将介绍一种新的样式解决方案。本方案在较少改变现有开发体验的条件下,采用 cssModules 样式方案语法要求,利用 Taro 插件的便利性给出对应的解决方案,以此对产物进行“瘦身”。最终样式文件的瘦身效果可以达到 50% – 70%,进一步缓解官方包 Size 的限制,便于业务的高速发展。
二、cssModules 简单介绍
本文样式方案学习了 cssModules 解决样式冲突的基本原理,并在此基础上改进以达到缩减样式文件 Size 的目的。因此在正式了解本方案之前,本文先用 Taro 官网中使用 cssModules 方案的例子代码作为示例,简单了解下其语法要求与原理。
2.1 语法要求
在配置开启了 cssModules 后,按照语法要求,Taro 项目中有 index.module.scss 和 index.js 两个文件,文件代码如下。cssModules 默认是开启部分自定义模式转换,只有文件名中包含.module.的样式文件才会经过 cssModules 转换处理。在如下 index.module.scss 样式文件中,我们正常使用了父子选择器、类选择器。但是在index.js 文件中,className 赋值不再是字符串,而是 SCSS 文件导出的 Object 的某个 Key,该 Key 为 SCSS 文件中的类选择器的命名。
import React, { Component } from "react"import { View, Text } from "@tarojs/components"import styles from "./index.module.scss"export default class Index extends Component { render() { return ( Hello world! ) }}
.test { color: red; .txt { font-size: 36px; }}
2.2 原理
Taro 项目开启 cssModules 配置后,在编译打包时,会使用实现了 cssModules 规范的 css-loader 对 SCSS 等样式文件进行处理。它首先会处理原 SCSS 文件中的类选择器,将类名进行哈希处理得到新类名如index-module__test___Bm2J6,生成新的样式代码输出到最终的 index.wxss,同时保存了原类名与哈希处理后的新类名的映射关系。此后它会将原 SCSS 文件 index.module.scss 编译为导出了原类名与哈希后的新类名的映射对象。JS 文件在运行时能通过该映射对象获取到哈希后的新类名,保证该文件类名不会与其他样式文件的同类名冲突,从而解决样式冲突问题。以下为编译后的代码示例,styles.test在运行时会会变成index-module__test___Bm2J6。
// index.module.scssexport default ({"test":"index-module__test___Bm2J6","txt":"index-module__txt___nIysk"});
// index.wxss.index-module__test___Bm2J6 { color: red;}.index-module__test___Bm2J6 .index-module__txt___nIysk { font-size: 36rpx;}
三、方案原理介绍
3.1 基本原理
3.1.1 当前样式文件 size 分析
在正式介绍本文方案是如何缩减样式文件 Size 之前,本文通过以下两个正则去分别匹配打包产物中所有样式文件的两个核心组成部分 ClassName 与 PropertyValue,并进行 Size 统计分析。
注:在本文中,有如该.txt .tit {color: #red;}CssRule代码,ClassName指的是其中的txt和tit,PropertyValue指的是color:#red;。
const classNamePattern = /(?<=\.)[A-Za-z0-9\-_]+(?=\s|{|:)/g // 匹配 ClassName 如 .txt {color: #red;}中的txtconst cssPropertyPattern = /(?<=\{)[^}]+(?=})/g // 匹配PropertyValue, 如 .txt {color: #red;}中 中括号之间的所有内容 color: #red;
下图是对整个编译打包后的小程序项目的样式文件进行组成 Size 分析。通过该图我们可以发现,我们项目打包编译后的所有的样式文件中,ClassName 占用大约有五分之一的空间,而 PropertyValue 则占用了有十分之七的空间,其余空间占比可能是如空格、伪类这种形态存在,本文暂不考虑。
3.1.2 处理方案
通过上一小节,我们可以知道一个样式文件中核心主要有两部分内容,一是 ClassName,二是 PropertyValue。本文样式方案对这两部分分别进行了处理来达到节省 Size 的目标。
1)缩减 ClassName 长度
核心就是将原 ClassName 替换成更短且唯一的 ClassName,在解决样式冲突的同时,也通过缩减了 ClassName 长度节省了 Size。当我们使用 cssModules 时,通常如第二章介绍 cssModules 时的示例代码一样,都是将 ClassName 进行 hash 化处理来保证唯一性,但是经过 hash 处理后的 ClassName 长度反而变得更长了,不符合我们缩减样式代码 Size 的目标。
本方案是从最短字符开始,逐渐递增的方式生成全项目唯一的 ClassName,从而保证唯一性的同时能够保证 ClassName 长度尽可能的短。如第一个解析到的 ClassName 替换成-a,第二个解析到的ClassName替换成-b,第五十二个解析到的 ClassName 替换成-Z,第五十三个解析到的 ClassName 替换成-aa。其中 ClassName 前面的-,用于防止新生成的类名与未转换的类名冲突。此外,新生成的 ClassName 注意需要符合规则,本插件算法先取prevString中一个字符,后续所有字符可以取任意charString中字符。
const prevString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 52个字符数const charString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" // 64个字符数
可能有人担心,随着整个项目中 ClassName 申明的越来越多,逐渐递增生成的 ClassName 也会越来越长,反而导致总 ClassName 过长。通过上述算法,算上最前面加上的 -, 当使用完三个字符长度的类名可 以替换 52 * 64 = 3328 个 ClassName 了,达到使用完四个字符长度需要 52 * 64 * 64 = 212992 个 className。新生成的 ClassName 不超过四个字符,就可以满足大部分项目的使用,使用本样式方案前可以检索下自己项目中 ClassName 的量级。
2)缩减 PropertyValue
通过上面的分析可以发现,其实占据样式文件 Size 最多的部分是 PropertyValue,因此缩减 PropertyValue 是本样式方案能够节省大量 Size 的核心手段。其实我们在开发时用到的样式属性值很多都是重复的,比如开发过程中用到的最多布局属性display:flex。每次用到该属性都需要新写一份,而且为了兼容性开启了Autoprefixer插件,display:flex将会变成display:-webkit-flex;display:-ms-flexbox;display:flex;,这使得样式文件的 Size 变得更大。本插件是通过尽可能复用 PropertyValue 的方式来缩减 PropertyValue。
本插件会将样式文件中的仅使用了类选择器的 CssRule 进行 PropertyValue 拆分,每一次拆分都会生成新的 PropertyValue ClassName。如以下示例代码,仅类选择器CssRuletxt被拆分了_a和_b两个 PropertyValue ClassName。后续若其他使用仅类选择器 CssRule 进行拆分时,若有相同的 PropertyValue 就会直接复用_a或者_b。
// 原代码.txt { display: flex;flex: 1; }// 处理后的代码._a {display: -webkit-flex; display: -ms-flexbox;display: flex;}._b {-webkit-flex: 1;-ms-flex: 1;flex: 1;}
而在使用 cssModules 样式写法的 js 文件中也需要进行相应的映射处理,通过 babel 插件在编译时进行转换处理,判断 css 文件的引用关系并进行替换,示例代码如下。
// 原代码import styles from "./index.module.scss"Index = () => { return }// 处理后的代码import "./index.module.scss"Index = () => { return }
本样式方案通过对仅使用了类选择器的 CssRule 的 PropertyValue 拆分成新的 PropertyValue ClassName,后续任何进行拆分的地方就可以直接复用该 PropertyValue ClassName,从而可以大量缩减 PropertyValue 重复冗余占用的 Size。
3)插件处理流程
以上两小节已经介绍了两个核心缩减 Size 的方案,本小节举一个更加全面的例子来介绍本插件是如何在编译时运用以上两个方案,对样式文件和 JS 文件进行处理转化的。主要有以下两步。
第一步,针对仅使用类选择器的 CssRule,进行 PropertyValue 拆分。如下示例代码中,.box{display:flex}拆分出了._a {display: -webkit-flex;display: -ms-flexbox;display: flex;},后续.item1` `.item2拆分时,直接复用了._a,缩减了 PropertyValue 重复冗余。
第二步,针对非仅使用类选择器的 CssRule,直接替换成全局唯一且更短的 ClassName。如下示例代码中,.box .item2{color: red;},原选择器中的 ClassName 直接替换成了更短的.-a .-b{ color: red;},并且添加了该映射关系styles = {box: “_a -a”, item1: “_a _b _c”, item2: “_a _b _d -b”},并在编译时进行替换。
// 原代码import React from "react"import styles from "./index.module.scss"export default Index = () => { return item1 item2 }// 处理后的代码import React from "react"import "./index.module.scss"// styles = {box: "_a -a", item1: "_a _b _c", item2: "_a _b _d -b"}export default Index = () => { return item1 item2 }
// 原index.module.scss代码.box { display: flex;}.item1{ display: flex; font-size: 32px; color: red;}.item2{ display: flex; font-size: 32px; color: grey;}.box .item2{ color: red;}// 处理后index.module.scss代码._a {display: -webkit-flex;display: -ms-flexbox;display: flex;}._b {font-size: 32px;}._c {color: red;}._d {color: grey;}.-a .-b{ color: red;}
3.2 需要注意的问题
3.2.1 styles 对象的属性不支持运行时
cssModules 方案中,JS 文件中引入的样式文件对象支持运行时计算属性的,如以下示例写法。这是因为在打包后的 JS 文件中,保存有一份原 ClassName 与 hash 后新 ClassName 映射关系的对象数据,因此运行时 styles 还能映射属性,但是这种处理方式会导致 js 文件 size 增大。
import styles from "./index.module.scss"const Index = () => { return }
本方案为了尽可能保证项目 Size 足够小,并没有采用 cssModules 这种处理方式。本方案在编译时会直接对原 CLassName 与拆分 PropertyValue 后的新 ClassName 直接进行了替换,如直接把className={styles.txt}替换成className=”_a _b”。
因此本方案styles对象不支持如上示例代码中,运行时计算得到txt属性,如需动态调整样式有两种方案,一是直接使用内联样式。二是新写 ClassName 而不是拼接,如className={value ? styles.txt1 : styles.txt2}}。
3.2.2 仅类选择器不依赖先后顺序定优先级
在上文中,提到过会拆分仅使用类选择器 CssRule,来尽可能复用已有的 PropertyValue ClassName。但是这种复用是有缺陷的,它会导致 ClassName 的先后顺序可能不符合预期,如下代码所示,通常来说我们认为标题颜色应当是grey。
// 原代码import styles from "./index.module.scss"const Index = () => { return 标题 }// 处理后的代码import styles from "./index.module.scss"const Index = () => { return 标题 }
// 原代码.other { color: green; color:red; }.tit1 { color: red; }.tit2 { color: green; }// 处理后的代码._a {color:green;}._b {color:red;}
但是经过本插件复用了 PropertyValue 后,导致._b{color:red;}出现在了._a{color:green;}后面了,此时标题的颜色也就变成了red,从而可能不符合开发者预期。
因此需要注意在编写仅类选择器 CssRule 的 ClassName 时,不能依赖类选择器先后顺序来定优先级,可通过兄弟选择器来将优先级提的更高,从而不受先后顺序影响,如下代码示例。这样就能确定标题颜色一定是green。
// 兄弟选择器来提高优先级.other { color: green; color:red; }.tit1 { color: red; }.tit1.tit2 { color: green; }
四、使用指南
4.1 使用
4.1.1 安装插件
本样式方案被集成在该 Taro 插件taro-plugin-split-class中,安装本插件。源码见仓库taro-plugin-split-class。
npm install -D taro-plugin-split-class
4.1.2 关闭cssModules功能
在 Taro 配置文件中,使得mini.posetcss.cssModules.enable = false,确保 cssModules 功能关闭,如下代码所示。
// config/index.js{ mini: { postcss: { cssModules: { enable: false } } }}
4.1.3 配置本插件
在 Taro 配置文件中,plugins配置中加入本插件taro-plugin-split-class。本插件支持配置类名转换白名单(实现功能类似 : global,见 2.4)classNameWhite,比如常用的 iconfont 是不需要转换的。
plugins: [ ["taro-plugin-split-class", { classNameWhite: ["iconfont", /^ifont-/] }]]
4.2 语法要求
a.样式文件命名需以 .module.xxx 结尾,如 index.module.scss,该样式文件方可被本插件转化处理。
b. 在 JS 文件中,将样式文件作为一个对象引入,并将类名作为对象的键进行使用。如下代码所示,使用className={styles.box}而不是className=”box”,其中box为定义在样式文件的中类名。
// 如下import styles from "./index.module.scss" // 而不是import "./index.module.scss"
c. 本方案支持所有选择器包括父子选择器、伪类选择器、兄弟选择器等等。但请尽可能的使用仅类选择器来定位元素,这样做可以便于插件尽可能复用 PropertyValue 从而更好的缩减 Size。本方案解决了类名冲突问题,因此开发者不需要担心因类名命名简单而导致的类名冲突。
// 如下仅类选择器的CssRule.box { display: flex; flex-direction: column; align-items: center;}.tit { display: flex; font-size: 40px; color: red;}// 而不是父子选择器.box { display: flex; flex-direction: column; align-items: center; .tit { display: flex; font-size: 40px; color: red; }}
d. 特殊类名不变
有时候我们希望一些特殊的 ClassName 不变,在 JS 文件中,不从 styles 取类名即可,如下代码中的extra。
import styles from "./index.module.scss"标题
但是在样式文件中默认所有 ClassName 都会被拆分或者压缩。如下代码示例,extra被处理成-a。
// 原类名.extra.tit {color: blue;}// 新类名.-a.-b { color: blue;}
因此需要特殊标识符让插件感知到不需要处理该 ClasName。本方案提供了类似 cssModules 的:global的解决方案,有两种使用方式,一是:global(.extra),被包裹的类名不会被替换。
// 编译前:global(.extra).tit { color: blue;}// 编译后.extra.-a { color: blue;}
二是以:global开头,后续所有的类名都不会被替换。
// 编译前:global .extra1 .extra2 { color: red;}// 编译后.extra1 .extra2 { color: red;}
4.3 打包效果展示
4.3.1 开发环境
使用本插件后,原类名会被替换或拆分成更短且更多的新类名。这样处理后的新类名可读性很差,开发者不能很好的定位到原类名代码。因此在开发环境下,会在更短且更多的新类名前会加上[文件夹_文件名_原类名]。保留了原类名相关信息,便于开发者查找原类名。如下图代码所示,原类名为box,经过插件拆分和缩短后的新类名为_a _g _h -c,在新类名前加上了index_indes-module_box,最终展示的完整类名为index_index-module_box _a _g _h -c。
4.3.2 生产环境
在生产环境了,不需要考虑新类名可读性,因此直接会直接将类名完全替换为新类名。如下图代码所示,box直接被替换成_a _g _h -c。
五、方案分析
5.1 实践效果
5.1.1 页面改造前后对比
在使用本样式方案对某个页面进行改造后,改造前后 Size 对比如下。可以发现样式文件缩减了 44KB,缩减了将近 70% 的 Size,JS 文件有这 2kb 的增长。
JS文件 | 样式文件 | 总和 | |
使用前 | 54kb | 63kb | 117kb |
使用后 | 56kb | 19kb | 75kb |
使用前编译后文件 Size 如下图:
使用后编译后文件 Size 如下图:
5.1.2 重构页面横向对比
最近我们项目重构了两个大型订单详情页面,本小节以这两个页面重构后的代码为例,分析编译打包前后的 Size 并进行横向对比。
整理出如下表格:
样式编码字符数 | 打包后实际Size | |
未使用本样式方案的订单详情页1 | 3620 | 86kb |
使用本样式方案的订单详情页2 | 6615 | 73kb |
两订单详情页代码组织结构类似,因此将它们进行横向对比。未采用本样式方案的订单详情页 1 的样式编码字符数为 3620,打包后实际 Size 为 86kb。若订单详情页 2 未使用本样式方案,打包前样式编码字符数为 6615,则预期打包后实际 Size 为 6615 / 3620 \* 86kb = 157kb,但订单详情页使用了本样式方案实际打包后为 73kb,相对于 157kb,缩减了 50% 左右的 Size。
以下为未使用本样式方案的订单详情页 1,该目录下样式文件包括了 50 个样式文件,共计 3620 个字符,最终打包出来的样式文件的 Size 为 86kb。
以下为使用了本样式方案的订单详情页 2,该目录下样式文件包括了 96 个样式文件,共计 6615 个字符,最终打包出来的样式文件 Size 为 73kb。
5.2 Size 缩减效果分析
以上两个实践效果,相较于项目中原样式写法方案,使用本方案后,主要从以下三个方面节省了 Size。
a. 本方案解决了样式冲突问题,编写样式代码时可以不再用父子选择器的方式来进行样式作用域隔离,减少了祖先选择器的冗余。如下使用了 sass 预处理器的样式代码所示,我们可以发现在最终编译生成的代码中,.box .item冗余了三次,而且若继续在.box .item下每新增一个叶子节点.item*,.box .item都会冗余一次。因此项目中使用父子选择器这种方式来隔离作用域,会导致大量的祖先选择器冗余。
// 编译前代码.box { .item { .item1 {} .item2 {} .item3 {} .item4 {} }}// 编译后代码.box .item .item1 {}.box .item .item2 {}.box .item .item3 {}.box .item .item4 {}
b. 将原 ClassName 直接缩短成更短的 ClassName,直接减少了字符数。这种方式较为直接,但优化效果有限。
c. 本方案尽可能拆分样式文件中仅类选择器的 CssRule,生成并复用 PropertyValue ClassName,尽可能减少了 PropertyValue 的重复冗余。虽然在 JS 文件中 ClassName 被替换成更短但更多的 PropertyValue ClassName,有一定的 Size 增加,如在实践效果 1 中,实践后 JS 文件有 2KB 的增长。但是相比于样式文件 Size 上的缩减效果可以忽略不计。
5.3 Size 增长分析
随着样式文件越多,采用本样式方案的项目,样式文件 Size 增长幅度将增长会越缓慢。本方案要求以仅类选择器的方式为主,少量场景使用其他选择器为辅的方式进行编写样式代码。随着项目中样式代码越来越多,仅类选择器 CssRule 经过本插件处理拆分生成的可复用的 PropertyValue CssRule 会越来越多。此时,在按要求新写仅类选择器 CssRule 使用到某个 PropertyValue 时,可复用的概率会更高。高概率的每一次复用都会节省一部分 Size,使得最终编译打包后生成的样式文件 Size 增长曲率逐渐放缓。
六、总结
针对 Taro 项目 React 框架小程序,本文介绍了一种新的样式解决方案,该方案被集成为一个 Taro 插件的形式,可以在在较少改变现有开发体验的条件下,缓解样式代码的冗余问题。
本样式方案学习借鉴了 cssModules 样式方案的语法规则以及原理,解决了样式冲突的问题,并且在此基础上从缩减 ClassName 长度和缩减 PropertyValue 两个方面实现了 Size 上的缩减,最终样式文件的瘦身效果可以达到 50%-70%。这有利缓解官方包 Size 的限制,便于业务的高速发展。
七、vscode 插件推荐
本方案基本语法跟 cssModules 一致,因此可以直接借助现有的 cssModules 插件,提升开发体验。
7.1 CSS-Modules-transform 插件
该插件支持让项目现有 JS 代码快速转成 cssModules 语法,将原类名使用方式,一键替换成本方案要求的类名使用语法,如classname=”a1″ => className={styles.a1}。需要注意的是,一键替换只支持非运行时的语法,运行时的语法还是需要手动替换。可以高效提高现有样式方案转化效率。
7.2 CSS Modules 插件
CSS Modules插件支持自动补全和类型定义,提高开发体验。
八、文章参考
GitHub – css-modules/css-modules: Documentation about css-modulescssModules插件图片
-
科比布莱恩特再次成为《NBA
中国女足出征2023女足世界杯
购车优惠3500元,特斯拉引荐
-
券商午后异动急拉,个股悉数
女子称自己患精神疾病儿子被
奇点汽车被申请破产审查 烧
上半年中欧班列累计开行8641列
2023年云南日报报业集团公开
广州“三旧”改造实施办法征
-
黑芝麻智能疑似深度绑定一汽
2023年兰州城区普通高中录取
跨界光伏者的N种“作死”法
路景交融 绿美常在 曲靖市
《八角笼中》成中国影史点映
唐山市疾控提醒:肠道传染病
-
本人生日怎么发朋友圈图片_
卫生间应放什么植物好
我的世界发射器怎样发射(我
“低门槛”副业好做吗?哪些
“后亚运时代”顶级自办赛事
热热热!阳光的威力!广东年
精彩推送
- 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案
- 科比布莱恩特再次成为《NBA 2K24》封面球星
- 北京今年首批老旧小区改造名单公布,涉及这些小区
- 维信诺股东户数下降6.36%,户均持股30.5万元
- 吕梁居然之家被罚款整改 存11项消防安全隐患
- 乌克兰已正式申请加入CPTPP,日本:“必须仔细评估”
- 圣诺生物拟定增募资不超1.6亿元 上市即巅峰募3.6亿
- 致尚科技超募3.9亿首日涨9.6% 过会曾被问3.26亿买房
- 敏芯股份拟定增募不超1.5亿 上市即巅峰募8.3亿2022亏
- 首创证券收股转系统监管措施 持续督导未勤勉尽责
- 中国女足出征2023女足世界杯
- 高价防晒服是智商税吗?专家:未必效果更好
- 快资讯:炼油行业谋划减碳发展路径
- 津膜科技(300334)7月7日主力资金净买入454.64万元
- 新一代全球个护科技品牌TYMO完成数千万人民币A轮融资,康煦投资、零一创投出手
- 现金短款处理会计分录
- 重庆三峡银行五名董事辞职
- 出新必热销!新世界耀胜尊府稳据长隆万博CBD人气封面
- 购车优惠3500元,特斯拉引荐奖励升级
- 全球化3.0时代企业品牌出海新思维
- 魏晨阳对话王勇——数字经济时代的创新动力
- 暑期游升温 文化味更足——年中旅游市场观察 天天消息
- 人均购买力平价gdp排名一览 购买力平价计算公式是什么
- 公告!事关HPV疫苗预约接种
- 股票量化交易软件:连续前行优化第八部分程序改进和修复
- 券商午后异动急拉,个股悉数翻红,券商ETF(512000)直线上攻涨逾1%!
- 购买力平价名词解释?购买力平价理论是谁提出来的?
- 教授称有人花百万留学回来月薪5000是真的吗?国外留学回来工资多少?
- 银行承兑汇票怎么承兑?为什么企业不愿意收承兑汇票?
- 私营企业破产清算赔偿五大顺序是什么?破产清算对法人的影响大吗?
- 公司破产清算要多久才完成?破产清算原有物资怎么处理?
- 银行承兑几个月到期?建行承兑贴现一般几个点?
- 破产清算组由哪些人组成?破产清算和破产重组的区别是什么?
- 破产清算员工怎么赔偿?公司申请破产的条件有哪些?
- 北京经开区国家级专精特新企业达87家——“小巨人”扎堆凸显科创实力 当前热点
- 传奇手游蓝月无限刀福利版:蓝月传奇宝石获取攻略
- 河南新乡再添农业“芯片” 食用菌新品种授权数量全国第一_环球快报
- 当前热讯:2023年鄂尔多斯市农村牧区供水工程已全部开工建设
- 已婚男同时交往5名女友,被发现后女友们联合报警!长沙检察官公开征集线索
- 当前最新:山西探索培养文物全科人才强化基层文保
- 雄安新区谋划出海通道完善交通“微细血管”_每日时讯
- 车子放久了电瓶没电了怎么启动(车子放久了电瓶没电怎么办)
- 天地源:前6月合约销售金额59.8亿元
- 保利置业:前6月合约销售金额374亿元
- 平安不动产180亿元公司债券发行计划获通过
- 绿城中国:前6月合约销售金额1342亿元_焦点日报
- 灿瑞科技:公司磁传感器、智能电机驱动芯片等产品均可用于机器人上
- 女子称自己患精神疾病儿子被游戏网友骗至缅北遭殴打,“再不去救,就要被卖到下家公司”,警方:已刑事立案
- 江苏公布打击整治网络谣言10起典型案例
- 小米手机还原网络设置
- 海通证券被北交所口头警示 保荐代表人信息披露违规
- 午评:指数延续震荡调整 种植业与林业板块强势
- 奇点汽车被申请破产审查 烧光170亿后迎来“至暗时刻”
- 标的物履行条款是什么?标的和标的物可能是一个东西吗?
- 提存期间标的物孳息归谁所有?标的物意外灭失风险的承担人是谁?
- 标的物的风险负担规则是什么?标的物风险转移的情况有哪两种?
- 威海市商业银行赋能“渔光互补”降减排 唱响“绿色兴农”协奏曲
- 金融期货标的物包括哪些工具?标的物提存的法定情形有哪些?
- 城市维护建设税计税基数是什么?个人需要交城市维护建设税吗?
- 全球坚果供应链巨头与三只松鼠在安徽合资建厂
- 我省将迎来入夏以来最强高温天气
- 盛洋科技终止向关联方买中交科技 财务顾问为中天国富
- 应交城市维护建设税包括哪些?城市维护建设税减半征收政策2023最新
- 城市维护建设税属于什么税种?城市维护建设税税收优惠政策有哪些?
- 【调研快报】苏州科达接待信达证券等多家机构调研
- 城市维护建设税是什么意思?城市维护建设税特征有哪些?城建费有什么用途?
- 上半年中欧班列累计开行8641列
- 法定盈余公积可以弥补亏损吗?法定盈余公积怎么提取?
- 法定盈余公积提取会计分录怎么写?法定盈余公积可以分配股利吗?
- 法定盈余公积可以转增资本吗?法定盈余公积意思解释
- 法定盈余公积必须提取吗?法定盈余公积怎么计算?
- 美国男篮官方公布世界杯12人大名单
- 苹果更新TestFlight应用程序 支持visionOS和Apple Vision Pro
- 2023年云南日报报业集团公开招聘人员面试公告
- 鼎镁科技IPO上会被否
- 鼎镁科技IPO上会被否
- 合众伟奇深交所上会被暂缓审议 保荐机构为光大证券
- 中信银行西安分行被罚 违反金融消费权益保护管理规定
- 万和科技终止北交所IPO 保荐机构为安信证券
- 华钰矿业7月7日盘中跌幅达5%
- 甘肃金昌:全面打造千亿级新能源产业集群-天天热文
- 全球即时看!爱乐汇交响乐团《完全贝多芬》2023-2024 音乐季发布
- 信息:福州“小电驴”新规首日:从“报废”到“上新”只需十几分钟
- 黑芝麻智能疑似深度绑定一汽,10轮融资后现金流仅够维持24个月
- 广州“三旧”改造实施办法征求民意,突出保护树木和历史文化
- 可转债新券再度暴涨 全部触发盘中临时停牌
- 齐齐哈尔市开展排水防涝应急抢险演练
- 大运河文化带建设高端智库成立:让大运河“活”起来|环球观热点
- 四川启动培育第二批500家“千户重点外贸企业”
- 马斯克称全面自动驾驶将在今年年末到来
- 圆尾斗鱼吃什么食物(圆尾斗鱼寿命)
- 2023年兰州城区普通高中录取最低控制线确定
- 禾信仪器终止不超2.3亿元可转债 2021年上市募3.1亿
- 广合科技过会:今年IPO过关第175家 民生证券过11单
- 基金分红:富国纯债债券发起式基金7月12日分红
- 兰州银行:副行长王毅任职资格获批
- 人民币兑美元中间价报7.2054 调升44个基点
- 今日上市:海科新源、致尚科技
- 避暑消费红火 催热“夏日经济”
- 西藏自治区党委巡视组原副厅级巡视专员罗红严重违纪违法被“双开”