从0到1构建基于自身业务的前端工具库 独家
作者:京东零售
前言•在实际项目开发中无论 M 端、PC 端,或多或少都有一个 utils 文件目录去管理项目中用到的一些常用的工具方法,比如:时间处理、价格处理、解析url参数、加载脚本等,其中很多是重复、基础、或基于某种业务场景的工具,存在项目间冗余的痛点以及工具方法规范不统一的问题。
•在实际开发过程中,经常使用一些开源工具库,如 lodash,以方便、快捷的进行项目开发。但是当 npm上没有自己中意或符合自身业务的工具时,我们不得不自己动手,此时拥有自己的、基于业务的工具库就显得尤为重要。
(资料图)
•我们所熟知的Vue、React等诸多知名前端框架,或公司提供的一些类库,它们是如何开发、构建、打包出来的,本文将带领你了解到如何从0到1构建基于自身业务的前端工具库。
构建工具库主流方案1. WEBPACK
• webpack 提供了构建和打包不同模块化规则的库,只是需要自己去搭建开发底层架构。
• vue-cli,基于 webpack , vue-cli 脚手架工具可以快速初始化一个 vue 应用,它也可以初始化一个构建库。
2. ROLLUP
• rollup 是一个专门针对JavaScript模块打包器,可以将应用或库的小块代码编译成更复杂的功能代码。
• Vue、React 等许多流行前端框架的构建和打包都能看到 rollup 的身影。
为什么采用 ROLLUP 而不是 WEBPACK•webpack 主要职能是开发应用,而 rollup 主要针对的就是 js 库的开发,如果你要开发 js 库,那 webpack 的繁琐配置和打包后的文件体积就不太适用了,通过webpack打包构建出来的源代码增加了很多工具函数以外的模块依赖代码。
•rollup 只是把业务代码转码成目标 js ,小巧且轻便。rollup对于代码的Tree-shaking和ES6模块有着算法优势上的支持,如果只想构建一个简单的库,并且是基于ES6开发的,加上其简洁的API,rollup得到更多开发者的青睐。
工具库底层架构设计构建工具库底层架构大概需要哪些功能的支持:
架构依赖需知在对底层架构设计的基础上,首先需要把用到的依赖库简单熟悉一下:
rollup 全家桶
• rollup(工具库打包构建核心包)
• rollup-plugin-livereload(rollup 插件,热更新,方便本地 debugger 开发)
• rollup-plugin-serve(rollup 插件,本地服务代理,方便在本地 html 中调试工具)
• rollup-plugin-terser(rollup 插件,代码压缩混淆)
• rollup-plugin-visualizer(rollup 插件,可视化并分析 Rollup bundle,以查看模块占用)
• @rollup/plugin-babel(rollup 插件,rollup 的 babel 插件,ES6 转 ES5)
• @rollup/plugin-commonjs(rollup 插件,用来将 CommonJS 模块转换为 ES6,这样它们就可以包含在 Rollup 包中)
• @rollup/plugin-json(rollup 插件,它将.json 文件转换为 ES6 模块)
• @rollup/plugin-node-resolve(rollup 插件,它使用节点解析算法定位模块,用于在节点模块中使用第三方 node_modules 包)
• @rollup/plugin-typescript(rollup 插件,对 typescript 的支持,将 typescript 进行 tsc 转为 js)
typescript 相关
• typescript(使用 ts 开发工具库)
• tslib(TypeScript 的运行库,它包含了 TypeScript 所有的帮助函数)
• @typescript-eslint/eslint-plugin(TypeScript 的 eslint 插件,约束 ts 书写规范)
• @typescript-eslint/parser(ESLint 解析器,它利用 TypeScript ESTree 来允许 ESLint 检测 TypeScript 源代码)
文档相关
• typedoc(TypeScript 项目的文档生成器)
• gulp(使用 gulp 构建文档系统)
• gulp-typedoc(Gulp 插件来执行 TypeDoc 工具)
• browser-sync(文档系统热更新)
单元测试相关
• jest(一款优雅、简洁的 JavaScript 测试框架)
• @types/jest(Jest 的类型定义)
• ts-jest(一个支持源映射的 Jest 转换器,允许您使用 Jest 来测试用 TypeScript 编写的项目)
• @babel/preset-typescript(TypeScript 的 Babel 预设)
其他依赖
• eslint(代码规范约束)
• @babel/core(@rollup/plugin-babel 依赖的 babel 解析插件)
• @babel/plugin-transform-runtime(babel 转译依赖)
• @babel/preset-env(babel 转译依赖)
• chalk(控制台字符样式)
• rimraf(UNIX 命令 rm -rf 用于 node)
• cross-env(跨平台设置 node 环境变量)
底层架构搭建1. 初始化项目新建一个文件夹 utils-demo,执行 npm init,过程会询问构建项目的基本信息,按需填写即可:
npm init
2. 组织工具库业务开发 SRC 目录结构创建工具库业务开发 src 文件目录,明确怎样规划工具库包,里面放置的是工具库开发需要的业务代码:
3. 安装项目依赖要对 typescript 代码进行解析支持需要安装对 ts 支持的依赖,以及对开发的工具的一些依赖包:
yarn add typescript tslib rollup rollup-plugin-livereload rollup-plugin-serve rollup-plugin-terser rollup-plugin-visualizer @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @rollup/plugin-typescript @babel/core @babel/plugin-transform-runtime @babel/preset-env rimraf lodash chalk@^4.1.2 -D
这里遇到一个坑,关于最新 chalk5.0.0 不支持在 nodejs 中 require()导入,所以锁定包版本 chalk@^4.1.2
要对 typescript 进行解析和编译还需要配置 tsconfig.json,该文件中指定了用来编译这个项目的根文件和编译选项,在项目根目录,使用 tsc --init 命令快速生成 tsconfig.json 文件(前提全局安装 typescript)
npm i typescript -gtsc --init
初始化 tsconfig 完成之后,根目录自动生成 tsconfig.json 文件,需要对其进行简单的配置,以适用于 ts 项目,其中具体含义可以参考tsconfig.json官网
4. 组织项目打包构建 SCRIPTS 目录结构1) 根目录创建项目打包构建 scripts 脚本文件目录,里面放置的是有关于项目打包构建需要的文件:
生成rollup配置项函数核心代码:
const moduleName = camelCase(name) // 当format为iife和umd时必须提供,将作为全局变量挂在window下:window.moduleName=...const banner = generateBanner() // 包说明文案// 生成rollup配置文件函数const generateConfigs = (options) => { const { input, outputFile } = options console.log(chalk.greenBright(`获取打包入口:${input}`)) const result = [] const pushPlugins = ({ format, plugins, ext }) => { result.push({ input, // 打包入口文件 external: [], // 如果打包出来的文件有项目依赖,可以在这里配置是否将项目依赖一起打到包里面还是作为外部依赖 // 打包出口文件 output: { file: `${outputFile}${ext}`, // 出口文件名称 sourcemap: true, // // 是否生成sourcemap format, // 打包的模块化格式 name: moduleName, // 当format为iife和umd时必须提供,将作为全局变量挂在window下:window.moduleName=... exports: "named" /** Disable warning for default imports */, banner, // 打包出来的文件在最顶部的说明文案 globals: {} // 如果external设置了打包忽略的项目依赖,在此配置,项目依赖的全局变量 }, plugins // rollup插件 }) } buildType.forEach(({ format, ext }) => { let plugins = [...defaultPlugins] // 生产环境加入包分析以及代码压缩 plugins = [ ...plugins, visualizer({ gzipSize: true, brotliSize: true }), terser() ] pushPlugins({ format, plugins, ext }) })return result}
2) rollup 在打包构建的过程中需要进行 babel 的转译,需要在根目录添加.babelrc 文件告知 babel:
{ "presets": [ [ "@babel/preset-env" ] ], "plugins": ["@babel/plugin-transform-runtime"]}
3) 此时距离打包构建工具库只差一步之遥,配置打包脚本命令,在 package.json 中配置命令:
"scripts": { "build": "rimraf lib && rollup -c ./scripts/rollup.config.js" // rollup打包 },
4) 执行 yarn build,根目录会构建出一个 lib 文件夹,里面有打包构建的文件,还多了一个 stats.html,这个是可视化并分析 Rollup bundle,用来查看工具模块占用空间:
架构搭建优化项目搭建到这里,不知机智的你能否发现问题:
1) 只要添加了一个工具,就要在入口文件导出需要打包构建的工具,在多人开发提交代码的时候将引来冲突的产生:
2) 使用工具库的时候,按需引用的颗粒度太细了,不能满足一些要求颗粒度粗的朋友,比如:
• 我想使用该包里面 date 相关工具,要这样吗?
import { dateA, dateB, dateC } from "utils-demo"
能不能这样?
import { date } from "utils-demo"date.dateA()date.dateB()date.dateC()
• 在一些使用 script 脚本引入的场景下,就仅仅需要 date 相关的工具,要这样吗?
<script src="https://xxx/main.min.js">
能不能这样?
<script src="https://xxx/date.min.js">
这样仅仅使用 date 里面的工具,就没有必要将所有的工具都引入了
解决方案:
1) 针对第一个代码冲突的问题,可以根据 src > modules 下目录结构自动生成入口文件 index.ts
自动构建入口文件核心代码:
const fs = require("fs") // node fs模块const chalk = require("chalk") // 自定义输出样式const { resolveFile, getEntries } = require("./utils")let srcIndexContent = `// tips:此文件是自动生成的,无需手动添加`getEntries(resolveFile("src/modules/*")).forEach(({ baseName, entry }) => { let moduleIndexContent = `// tips:此文件是自动生成的,无需手动添加` try { // 判断是否文件夹 const stats = fs.statSync(entry) if (stats.isDirectory()) { getEntries(`${entry}/*.ts`).forEach(({ baseName }) => { baseName = baseName.split(".")[0] if (baseName.indexOf("index") === -1) { moduleIndexContent += `export * from "./${baseName}"` } }) fs.writeFileSync(`${entry}/index.ts`, moduleIndexContent, "utf-8") srcIndexContent += `export * from "./modules/${baseName}"export * as ${baseName} from "./modules/${baseName}"` } else { srcIndexContent += `export * from "./modules/${baseName.split(".")[0]}"` } } catch (e) { console.error(e) }})fs.writeFileSync(resolveFile("src/index.ts"), srcIndexContent, "utf-8")
2) 针对颗粒度的问题,可以将 modules 下各种类型工具文件夹下面也自动生成入口文件,除了全部导出,再追加 import * as 模块类名称 类型的导出
至此,基本上解决了工具库打包的问题,但是架构中还缺少本地开发调试的环境,下面为大家介绍如何架构中添加本地开发调试的系统。
本地开发调试系统首先要明确要加入本地开发调试系统的支持,需要做到以下:
• 跨平台(window不支持NODE_ENV=xxx)设置环境变量,根据环境配置不同的 rollup 配置项
• 引入本地开发需要的 html 静态服务器环境,并能做到热更新
1) 跨平台设置环境变量很简单,使用 cross-env 指定 node 的环境
yarn add cross-env -D
2) 配置 package.json 命令
"scripts": { "entry": "node ./scripts/build-entry.js", "dev": "rimraf lib && yarn entry && cross-env NODE_ENV=development rollup -w -c ./scripts/rollup.config.js", // -w 表示监听的工具模块的修改 "build": "rimraf lib && yarn entry && cross-env NODE_ENV=production rollup -c ./scripts/rollup.config.js" },
3) 根据最开始架构设计的模块,在项目根目录新建 debugger 文件夹,里面存放的是工具调试的 html 静态页面
4) 接下来就是配置 scripts > rollup.config.js ,将 NODE_ENV=development 环境加入 rollup 配置,修改生成rollup配置项函数核心代码:
(isProd ? buildType : devType).forEach(({ format, ext }) => { let plugins = [...defaultPlugins] if (isProd) { // 生产环境加入包分析以及代码压缩 plugins = [...plugins, visualizer({ gzipSize: true, brotliSize: true }), terser()] } else { // 非生产环境加入热更新和本地服务插件,方便本地debugger plugins = [...plugins, ...[ // 热更新 rollUpLiveLoad({ watch: ["debugger", "lib"], delay: 300 }), // 本地服务代理 rollupServe({ open: true, // resolveFile("")代理根目录原因是为了在ts代码里debugger时可以方便看到调试信息 contentBase: [resolveFile("debugger"), resolveFile("lib"), resolveFile("")] }) ]] } pushPlugins({ format, plugins, ext }) })
5) 执行 yarn dev 之后浏览器会新打开窗口,输入刚添加的工具链接,并且它是热更新的:
工具库文档系统
一个完备的工具库需要有一个文档来展示开发的工具函数,它可能需要具备以下几点支持:
• 支持工具库中方法的可视化预览
• 支持修改工具的时候,具备热更新机制
typedoc(TypeScript 项目的文档生成器)能完美支持 typescript 开发工具库的文档生成器的支持,它的核心原理就是读取源代码,根据工具的注释、ts的类型规范等,自动生成文档页面
关于热更新机制的支持,第一个自然想到 browser-sync(文档系统热更新)
由于文档系统的预览功能有很多插件组合来实现的,可以借助 gulp (基于流的自动化构建工具),typedoc正好有对应的 gulp-typedocGulp 插件来执行 TypeDoc 工具插件
构建完成后打开文档系统,并且它是热更新的,修改工具方法后自动更新文档:
单元测试为确保用户使用的工具代码的安全性、正确性以及可靠性,工具库的单元测试必不可少。单元测试选用的是 Facebook 出品的 Jest 测试框架,它对于 TypeScript 有很好的支持。
1. 环境搭建1) 首先全局安装 jest 使用 init 来初始化 jest 配置项
npm jest -gjest --init下面是本人设置的jest的配置项✔ Would you like to use Jest when running "test" script in "package.json"? … yes✔ Would you like to use Typescript for the configuration file? … yes✔ Choose the test environment that will be used for testing › jsdom (browser-like)✔ Do you want Jest to add coverage reports? … yes✔ Which provider should be used to instrument code for coverage? › babel✔ Automatically clear mock calls, instances and results before every test? … yes
执行完之后根目录会自动生成jest.config.ts 文件,里面设置了单元测试的配置规则,package.json 里面也多了一个 script 指令 test。
2) 关于jest.config.js文件配置项具体含义可以查看官网,要想完成 jest 对于 TypeScript 的测试,还需要安装一些依赖:
yarn add jest ts-jest @babel/preset-typescript @types/jest -D
3) jest 还需要借助 .babelrc 去解析 TypeScript 文件,再进行测试,编辑 .babelrc 文件,添加依赖包 @babel/preset-typescript:
{ "presets": [ "@babel/preset-typescript", [ "@babel/preset-env" ] ], "plugins": ["@babel/plugin-transform-runtime"]}
2. 单元测试文件的编写1) 通过以上环节,jest 单元测试环境基本搭建完毕,接下来在__tests__下编写测试用例
2) 执行 yarn test
可以看到关于 debounce 防抖工具函数的测试情况显示在了控制台:
• stmts 是语句覆盖率(statement coverage):是不是每个语句都执行了?
• Branch 分支覆盖率(branch coverage):是不是每个 if 代码块都执行了?
• Funcs 函数覆盖率(function coverage):是不是每个函数都调用了?
• Lines 行覆盖率(line coverage):是不是每一行都执行了?
3) 同时还会发现项目根目录多了一个 coverage 文件夹,里面就是 jest 生成的测试报告:
3. 单元测试文件的编写引发的思考每次修改单元测试都要执行 yarn test 去查看测试结果,怎么解决?
jest提供了 watch 指令,只需要配置 scripts 脚本就可以做到,单元测试的热更新。
"scripts": { "test": "jest --watchAll"},
以后会写很多工具的测试用例,每次 test 都将所有工具都进行了测试,能否只测试自己写的工具?
jest 也提供了测试单个文件的方法,这样 jest 只会对防抖函数进行测试(前提全局安装了 jest)。
jest debounce.test.ts --watch
工具库包的发布至此工具库距离开发者使用仅一步之遥,就是发布到npm上,发包前需要在 package.json 中声明库的一些入口,关键词等信息。
"main": "lib/main.js", // 告知引用该包模块化方式的默认文件路径 "module": "lib/main.esm.js", // 告知引用该包模块化方式的文件路径 "types": "lib/types/index.d.ts", // 告知引用该包的类型声明文件路径 "sideEffects": false, // false 为了告诉 webpack 我这个 npm 包里的所有文件代码都是没有副作用的 "files": [ // 开发者引用该包后node_modules包里面的文件 "lib", "README.md" ], "keywords": [ "typescript", "utils-demo", "utils" ], "scripts": { "pub": "npm publish" },
登陆npm,你会看到自己的 packages 里面有了刚刚发布的工具库包:
写在最后以上就是作者整理的从0到1构建基于自身业务的前端工具库的全过程,希望能给阅读本文的开发人员带来一些新的想法与尝试。
在此基础上已经成功在京东npm源发布了应用于京东汽车前端的工具库@jdcar/car-utils,并在各个业务线及系统得到落地。
当然,架构优化之路也还远未结束,比如:打包构建的速度、本地开发按需构建、工具库脚手架化等,后续我们也会基于自身业务以及一些新技术,持续深入优化,在性能上进一步提升,在功能上进一步丰富。本文或存在一些浅显不足之处,也欢迎大家评论指点。
参考资料[1] rollup 英文文档(https://rollupjs.org/guide/en/#quick-start)
[2] rollup 中文文档(https://rollupjs.org/guide/zh/#introduction)
[3] Rollup.js 实战学习笔记(https://chenshenhai.github.io/rollupjs-note/)
[4] Rollup 打包工具的使用(https://juejin.cn/post/6844904058394771470)
[5] TypeScript、Rollup 搭建工具库(https://juejin.cn/post/6844904035309322254)
[6] 使用 rollup.js 封装各项目共用的工具包(https://juejin.cn/post/6993720790046736420)
[7] 如何开发一个基于 TypeScript 的工具库并自动生成文档(https://juejin.cn/post/6844903881030238221)
[8] 一款优雅、简洁的 JavaScript 测试框架(https://jestjs.io/zh-Hans/)
标签:
相关阅读
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
推荐阅读
-
从0到1构建基于自身业务的前端工具库 独家
作者:京东零售前言•在实际项目开发中无论M端、PC端,或多或少都有一个utils文件目录去管理项目中用到的一更多
2023-05-10 14:18:44
-
浙江省消防救援总队开展水域救援师资力量培训
为深入推进全省水域救援力量体系建设,培养和储备消防救援队伍内部水域救援师资力量,近日,浙江省消防救援更多
2023-05-10 13:47:27
-
《平凡之路》金晨突破出演三高“白骨精”,戏内戏
所在团队集体跳槽,她是唯一留下收拾残局的人;公司人手不足,她是主动通宵加班的人;原有大客户要解约,她更多
2023-05-10 13:10:58
-
“艺海流金·阳光海南”内地与港澳文化和旅游界交
新海南客户端、南海网、南国都市报5月10日消息(记者苏桂除)“哇,琼海的这些杂粮色香味俱全,这些热带特更多
2023-05-10 12:36:09
-
环球今日报丨路边发现“毒草” 小伙选择立即报警
00:09扬子晚报网5月10日讯(通讯员吴雨欣记者王国柱)5月8日17时许,泰州市公安局医药高新区分局(高港分局)更多
2023-05-10 12:00:45
-
天天资讯:直系皖系奉系还有什么_直系 皖系 奉
1、皖系皖系军阀,北洋军阀派系之一。2、以其首领段祺瑞为安徽(简称皖)人而得名。3、主要人物有徐树铮、靳更多
2023-05-10 11:40:16
-
焦点热门:宝马iX1申报图曝光 有望7月正式上市
爱卡近日从工信部网站新一期申报目录中获取到宝马iX(参数|询价)1申报图,新车在此前上海车展正式亮相。据悉更多
2023-05-10 11:19:32
-
三人女篮系列赛中国队夺冠|全球快讯
原标题:三人女篮系列赛中国队夺冠人民日报海外版电(记者刘峣)2023年国际篮联三人篮球女子系列赛全球首站更多
2023-05-10 10:49:01
时尚热图
热门标签
精彩放送
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
05-10
-
今日必看
-
精彩话题
-
最新见闻
- 上海“大零号湾”,何以打造世界级科创湾区?
- 焦点快看:全力保障夏粮丰收 河南各地及时做好小麦夏管工作
- 康希诺重组新冠疫苗在中国香港获上市许可 即时
- 世界百事通!九安医疗:5月9日融券卖出6.64万股,融资融券余额12.96亿元
- 中超|李海新将执法京津之战 天天快报
- 全球热头条丨今年有23只基金截止清盘日基金净值仍未回到1元面值之上
- 【世界播资讯】党建引领共商共治 昌平区十三陵镇两处老旧小区改造顺利完工
- 全球时讯:腾讯大动作!面向抖音、快手、小红书“抢人”
- 环球通讯!北汽蓝谷2022年亏损近55亿元 同比亏损扩大4.22%
- 环球速讯:打造全流程智慧医院,这家社区医院为何被居民点赞?
- 早知道|雄鹿二将入选最佳防守一阵
- 期待!我国空间站未来将安排一大冰箱_当前快播
- 天天快报!独家述评|新时尚如何更好延续
- 科大智能参设新能源发展公司 经营范围含电池销售
- 购销两旺带动农民增收 江苏徐州3万多亩西瓜成熟上市
- 新民快评|加装电梯岂容“喇叭腔”
- 环球观速讯丨李小鹏任交通运输部党组书记
- a股开户流程有哪些?a股怎么开户?
- 5月10日央行公开市场开展20亿元7天期逆回购操作 世界关注
- 营利性医疗机构与非营利性一样吗?营利性医疗机构与非营利性主要区别有哪些?
- 银联是什么银行的卡?银行卡上都有银联标志的原因?
- 房屋买卖合同纠纷案大幅提升 检察机关给出三点提示
- 国产护肤品牌有哪些?盘点那些好用的国产护肤品牌
- 国内时尚运动品牌有哪些?耐克阿迪与国内运动品牌的差距在哪里?
- 个人黄金投资都有什么?投资实物黄金技巧
- 龟板胶的功效与作用及食用方法 龟板胶的禁忌及注意事项
- 中药企业2022年业绩分化明显 加强研发投入成行业趋势
- 云南特产有哪些呢?云南十大特产排行榜
- 宽松货币政策都有哪些?宽松货币政策对股市有什么影响?
- 可持续发展理念指的是什么?可持续发展理念又有什么含义?
- 转变经济发展方式的主要内容 转变经济发展方式与经济增加方式有什么不同?
- 什么是债转股?债转股协议有哪些内容?
- 什么是同工同酬?同工同酬的好处及不足是什么?
- 年化收益率计算公式?如何提高年化收益率?
- 黑洞究竟是怎样形成的?黑洞的形成过程?
- 法人股是什么意思?法人股应当如何流动呢?
- 哈雷彗星多少年出现一次?哈雷彗星究竟是什么?
- 环球观焦点:数字赋能福建加快建设现代农业体系
- 股市中什么是空窗期?空窗期的基础知识
- 支付宝限额是怎么回事呢?支付限额如何解除呢?
- 新零售是什么意思?新零售都有哪些特征?
- 环球视点!海通证券研究所早报
- 百姓身边的黑科技之“娱”|全景声还原真实世界听觉效果-每日速看
- 华昌化工:氮、磷、钾原料及产品价格近期呈下降趋势 全球快播
- 当前热讯:百姓身边的黑科技之“娱”|石景山集聚90余家科幻科技类企业
- 今日聚焦!华策影视:版权业务去年净利6560万元 视频素材服务于大模型训练等
- 武仙座(关于武仙座介绍)
- 即时:巴黎奥运排球资格赛落户宁波 中国女排目标直接晋级
- 中央纪委国家监委网站:严查利用“代理人”贪腐 环球报道
- 江南华南迎新一轮降雨 下周初北方多地迎今年首个高温日 环球关注
- 特斯拉2022年4月销售75842辆中国制造汽车
- 动态焦点:大雨!暴雨!广东雨水不退场 粤西等地未来三天雨势仍猛烈
- 天天快播:MLCC量价齐升 行业或处于景气度上行拐点前夜
- 老百姓身边的黑科技之娱|全景声电新场景 科幻炫酷年轻人_世界热点
- 热议:百姓身边的黑科技之“娱”|石景山建设10个创新平台服务科技企业
- 当前热讯:四川宜宾市兴文县发生3.6级地震
- A股研发投入榜单出炉:比亚迪研发人员最多 医药研发强度领跑
- 中国星辰丨服装、食品、饮用水......新一波“太空快递”即将发货|环球新动态
- 抖音规范平台AI生成内容 数据安全已成AI发展的前提保障_天天消息
- 每日热议!德邦证券给予福斯特买入评级 胶膜为基 多点开花
- 这一晚,马莱莱真的让人快乐-全球报道
- 万丰股份俞杏英:用缤纷色彩扮靓美好生活
- 低风险偏好基金 业绩稳健上行
- 世界速讯:骗取长护险资金歪风不可长
- 上海海洋石油局主题教育读书班开班-全球速看
- 每日速读!东吴证券:看好酒店服务消费持续复苏潜力 连锁酒店仍有广阔空间
- 天天亮点!空客:4月共交付54架飞机
- 农民有退休金是真的吗?什么时候后开始有? 快消息
- 中泰证券给予华海诚科买入评级 环氧塑封料稀缺标的 有望受益于先进封装和Chiplet发展-通讯
- 谷爱凌:现在我有了更强大的内心 全球播资讯
- 全球快讯:苏宁环球:确保房地产主营业务同时,持续加大对医美产业投入力度
- 锦源晟拟借壳日播时尚 “投资达人”梁丰再扩资本版图
- 快报:2022年平均工资出炉:IT业最高,金融业第二,房地产业下降
- 天天速看:哈药股份:目前哈药总厂原料药按计划陆续恢复,但整体规模较小
- 【世界热闻】莱登:尚未同首钢沟通续约
- culture读音是什么_culture读音 焦点速读
- 环球今头条!深圳公积金贷款政策2023最新_深圳公积金贷款
- 世界今头条!香港警队招人!报名人数激增三倍,年轻人反响热烈
- “上海地铁坐过站的原因找到了”上热搜!我们实测了10条线路
- 谷爱凌:有很多关于我的传言,其中90%都是假的
- 全球要闻:日本石川县发生5.0级地震
- 天天速读:南财早新闻丨五部门:7月起全国禁售不符合国六排放标准6b阶段的汽车;全国城镇非私营单位平均工资超10万元大关
- 我是安徽安庆人 暑假想去安徽省黄山市呈坎村游玩,请问一下具体路线,谢了
- 焦点观察:邮储银行湖州市分行 有效解决农户融资难融资贵问题
- 今日最新!一些习惯正在伤害你的颈椎 保护颈椎的正确打开方式是什么?
- 78.5%!中国品牌成“香饽饽”,经济学专家给国货“撑腰”
- 北京地铁标志系统,要上新啦!-环球观点
- 车企销量分化:理想领跑、蔚来下滑、小鹏挣扎-环球观察
- 每日精选:东方财富证券给予银轮股份买入评级
- 4月快递发展指数同比提升47.7% 单日最高业务量超3.9亿件
- 民企成外贸主力军 透露哪些外贸新趋势? 当前热点
- 广汽集团4月销量同比增长42.57%
- 5月零售业景气指数达51.1% 连续5个月保持在荣枯线以上 微动态
- 今日要闻!全国铁路完成固定资产投资1674亿元 同比增长6.3%
- 上海咖啡文化周5月20日开幕 环球快播报
- 暴风集团被强执847万,创始人被强执4亿,旗下暴风影音曾辉煌一时 环球信息
- 济宁召开全市创建食品安全管理规范化农贸市场工作推进会议
- 今日报丨这只A股年报“难产”!交易所出手:退市!网友:怎么办?
- 天天观点:陇神戎发2023年主打产品销售收入 预计保持良好增长趋势
- 教师思想工作总结摘要简短(教师思想工作总结个人)