专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

使用Vite和TypeScript带你从零打造一个属于自己的

  前言
  随着前端技术的发展,业界涌现出了许多的UI组件库。例如我们熟知的ElementUI,Vant,AntDesign等等。但是作为一个前端开发者,你知道一个UI组件库是如何被打造出来的吗?
  读完这篇文章你将学会:如何使用pnpm搭建出一个Monorepo环境如何使用vite搭建一个基本的Vue3脚手架项目如何开发调试一个自己的UI组件库如何使用vite打包并发布自己的UI组件库
  作为一个前端拥有一个属于自己的UI组件库是一件非常酷的事情。它不仅能让我们对组件的原理有更深的理解,还能在找工作的时候为自己增色不少。试问有哪个前端不想拥有一套属于自己的UI组件库呢?
  本文将使用Vue3和TypeScript来编写一个组件库,使用ViteVue3来对这个组件库中的组件进行调试,最后使用vite来对组件库进行打包并且发布到npm上。最终的产物是一个名为kittyui的组件库。
  话不多说接下来让我们开始搭建属于我们自己的UI组件库吧Monorepo环境
  首先我们要了解什么是Monorepo及它是如何搭建的吧
  就是指在一个大的项目仓库中,管理多个模块包(package),这种类型的项目大都在项目根目录下有一个packages文件夹,分多个项目管理。大概结构如下:packagespkg1package。jsonpkg2package。jsonpackage。json
  简单来说就是单仓库多项目
  目前很多我们熟知的项目都是采用这种模式,如Vant,ElementUI,Vue3等。打造一个Monorepo环境的工具有很多,如:lerna、pnpm、yarn等,这里我们将使用pnpm来开发我们的UI组件库。
  为什么要使用pnpm?
  因为它简单高效,它没有太多杂乱的配置,它相比于lerna操作起来方便太多
  好了,下面我们就开始用pnpm来进行我们的组件库搭建吧使用pnpm安装npminstallpnpmg初始化package。jsonpnpminit新建配置文件。npmrcshamefullyhoisttrue
  这里简单说下为什么要配置shamefullyhoist。
  如果某些工具仅在根目录的nodemodules时才有效,可以将其设置为true来提升那些不在根目录的nodemodules,就是将你安装的依赖包的依赖包的依赖包的。。。都放到同一级别(扁平化)。说白了就是不设置为true有些包就有可能会出问题。monorepo的实现
  接下就是pnpm如何实现monorepo的了。
  为了我们各个项目之间能够互相引用我们要新建一个pnpmworkspace。yaml文件将我们的包关联起来packages:packagesexamples
  这样就能将我们项目下的packages目录和examples目录关联起来了,当然如果你想关联更多目录你只需要往里面添加即可。根据上面的目录结构很显然你在根目录下新packages和examples文件夹,packages文件夹存放我们开发的包,examples用来调试我们的组件
  examples文件夹就是接下来我们要使用vite搭建一个基本的Vue3脚手架项目的地方安装对应依赖
  我们开发环境中的依赖一般全部安装在整个项目根目录下,方便下面我们每个包都可以引用,所以在安装的时候需要加个wpnpmivuenexttypescriptlessDw
  因为我们开发的是vue3组件,所以需要安装vue3,当然ts肯定是必不可少的(当然如果你想要js开发也是可以的,甚至可以省略到很多配置和写法。但是ts可以为我们组件加上类型,并且使我们的组件有代码提示功能,未来ts也将成为主流);less为了我们写样式方便,以及使用它的命名空间(这个暂时这里没用到,后面有时间再补配置tsconfig。json
  这里的配置就不细说了,可以自行搜索都是代表什么意思。或者你可以先直接复制npxtscinit
  tsconfig。json:{compilerOptions:{baseUrl:。,jsx:preserve,strict:true,target:ES2015,module:ESNext,skipLibCheck:true,esModuleInterop:true,moduleResolution:Node,lib:〔esnext,dom〕}}手动搭建一个基于vite的vue3项目
  其实搭建一个vitevue3项目是非常容易的,因为vite已经帮我们做了大部分事情初始化仓库
  进入examples文件夹,执行pnpminit安装vite和vitejspluginvue
  vitejspluginvue用来支持。vue文件的转译pnpminstallvitevitejspluginvueDw
  这里安装的插件都放在根目录下配置vite。config。ts
  新建vite。config。tsimport{defineConfig}fromviteimportvuefromvitejspluginvueexportdefaultdefineConfig({plugins:〔vue()〕})新建html文件
  vitejspluginvue会默认加载examples下的index。html
  新建index。html!DOCTYPEhtmlhtmllangenheadmetacharsetUTF8metahttpequivXUACompatiblecontentIEedgemetanameviewportcontentwidthdevicewidth,initialscale1。0titleDocumenttitleheadbodybodyhtml
  注意:vite是基于esmodule的所以typemodule新建app。vue模板template启动测试template新建main。tsimport{createApp}fromvueimportAppfrom。app。vueconstappcreateApp(App)app。mount(app)
  此时会发现编译器会提示个错误:找不到模块。app。vue或其相应的类型声明
  因为直接引入。vue文件TS会找不到对应的类型声明;所以需要新建typings(命名没有明确规定,TS会自动寻找。d。ts文件)文件夹来专门放这些声明文件。
  typingsvueshim。d。ts
  TypeScriptTS默认只认ES模块。如果你要导入。vue文件就要declaremodule把他们声明出来。declaremodule。vue{importtype{DefineComponent}fromvue;constcomponent:DefineComponent{},{},any}配置脚本启动项目
  最后在package。json文件中配置scripts脚本。。。scripts:{dev:vite},。。。
  然后终端输入我们熟悉的命令:pnpmrundev
  vite启动默认端口为3000;在浏览器中打开localhost:3000就会看我们的启动测试页面。本地调试新建包文件
  本节可能和目前组件的开发关联不大,但是未来组件需要引入一些工具方法的时候会用到
  接下来就是要往我们的packages文件夹冲填充内容了。utils包
  一般packages要有utils包来存放我们公共方法,工具函数等
  既然它是一个包,所以我们新建utils目录后就需要初始化它,让它变成一个包;终端进入utils文件夹执行:pnpminit然后会生成一个package。json文件;这里需要改一下包名,我这里将name改成kittyuiutils表示这个utils包是属于kittyui这个组织下的。所以记住发布之前要登录npm新建一个组织;例如kittyui{name:kittyuiutils,version:1。0。0,description:,main:index。ts,scripts:{test:echoError:notestspecifiedexit1},keywords:〔〕,author:,license:ISC}
  因为我们使用ts写的,所以需要将入口文件index。js改为index。ts,并新建index。ts文件:(先导出一个简单的加法函数)exportconsttestfun(a:number,b:number):number{returnab}组件库包(这里命名为kittyui)
  components是我们用来存放各种UI组件的包
  新建components文件夹并执行pnpminit生成package。json{name:kittyui,version:1。0。0,description:,main:index。ts,scripts:{test:echoError:notestspecifiedexit1},keywords:〔〕,author:,license:ISC}
  新建index。ts入口文件并引入utils包import{testfun}fromkittyuiutilsconstresulttestfun(1,1)console。log(result)esno
  由于组件库是基于ts的,所以需要安装esno来执行ts文件便于测试组件之间的引入情况
  控制台输入esnoxxx。ts即可执行ts文件npmiesnog包之间本地调试
  进入components文件夹执行pnpminstallkittyuiutils
  你会发现pnpm会自动创建个软链接直接指向我们的utils包;此时components下的packages:{name:kittyui,version:1。0。0,description:,main:srcindex。ts,scripts:{test:echoError:notestspecifiedexit1},keywords:〔〕,author:,license:ISC,dependencies:{kittyuiutils:workspace:1。0。1}}
  你会发现它的依赖kittyuiutils对应的版本为:workspace:1。0。0;因为pnpm是由workspace管理的,所以有一个前缀workspace可以指向utils下的工作空间从而方便本地调试各个包直接的关联引用。
  到这里基本开发方法我们已经知道啦;接下来就要进入正题了,开发一个button组件试着开发一个button组件
  在components文件夹下新建src,同时在src下新建button组件目录和icon组件目录(新建icon为了便于调试);此时components文件目录如下componentssrcbuttoniconindex。tspackage。json
  让我们先测试一下我们的button组件能否在我们搭建的examples下的vue3项目本引用
  首先在button下新建一个简单的button。vuetemplatebutton测试按钮buttontemplate
  然后在buttonindex。ts将其导出importButtonfrom。button。vueexportdefaultButton
  因为我们开发组件库的时候不可能只有button,所以我们需要一个componentsindex。ts将我们开发的组件一个个的集中导出importButtonfrom。buttonexport{Button}
  好了,一个组件的大体目录差不多就是这样了,接下来请进入我们的examples来看看能否引入我们的button组件vue3项目使用button
  上面已经说过执行在workspace执行pnpmixxx的时候pnpm会自动创建个软链接直接指向我们的xxx包。
  所以这里我们直接在examples执行:pnpmikittyui
  此时你就会发现packages。json的依赖多了个kittyui:workspace:1。0。0
  这时候我们就能直接在我们的测试项目下引入我们本地的components组件库了,启动我们的测试项目,来到我们的examplesapp。vue直接引入ButtontemplateButtontemplate
  不出意外的话你的页面就会展示我们刚刚写的button组件了
  好了万事具。。。(其实还差个打包,这个后面再说);接下来的工作就是专注于组件的开发了;让我们回到我们的button组件目录下(测试页面不用关,此时我们已经可以边开发边调试边看效果了)
  因为我们的button组件是需要接收很多属性的,如type、size等等,所以我们要新建个types。ts文件来规范这些属性
  在button目录下新建types。tsimport{ExtractPropTypes}fromvueexportconstButtonType〔default,primary,success,warning,danger〕exportconstButtonSize〔large,normal,small,mini〕;exportconstbuttonProps{type:{type:String,values:ButtonType},size:{type:String,values:ButtonSize}}exporttypeButtonPropsExtractPropTypestypeofbuttonProps
  TIPS
  importtype表示只导入类型;ExtractPropTypes是vue3中内置的类型声明,它的作用是接收一个类型,然后把对应的vue3所接收的props类型提供出来,后面有需要可以直接使用
  很多时候我们在vue中使用一个组件会用的app。use将组件挂载到全局。要使用app。use函数的话我们需要让我们的每个组件都提供一个install方法,app。use()的时候就会调用这个方法;
  我们将buttonindex。ts调整为importbuttonfrom。button。vueimporttype{App,Plugin}fromvuetypeSFCWithInstallTTPluginconstwithInstallT(comp:T){(compasSFCWithInstallT)。install(app:App){注册组件app。component((compasany)。name,comp)}returncompasSFCWithInstallT}constButtonwithInstall(button)exportdefaultButton
  此时我们就可以使用app。use来挂载我们的组件啦
  其实withInstall方法可以做个公共方法放到工具库里,因为后续每个组件都会用到,这里等后面开发组件的时候再调整
  到这里组件开发的基本配置已经完成,最后我们对我们的组件库以及工具库进行打包,打包之前如果要发公共包的话记得将我们的各个包的协议改为MIT开源协议。。。license:MIT,。。。vite打包配置文件
  打包们这里选择vite,它有一个库模式专门为我们来打包这种库组件的。
  前面已经安装过vite了,所以这里直接在components下直接新建vite。config。ts(配置参数文件中已经注释):import{defineConfig}fromvite;importvuefromvitejspluginvueexportdefaultdefineConfig({build:{target:modules,打包文件目录outDir:es,压缩minify:false,css分离cssCodeSplit:true,rollupOptions:{忽略打包vue文件external:〔vue〕,input:〔srcindex。ts〕,output:〔{format:es,不用打包成。es。js,这里我们想把它打包成。jsentryFileNames:〔name〕。js,让打包目录和我们目录对应preserveModules:true,配置打包根目录dir:es,preserveModulesRoot:src},{format:cjs,entryFileNames:〔name〕。js,让打包目录和我们目录对应preserveModules:true,配置打包根目录dir:lib,preserveModulesRoot:src}〕},lib:{entry:。index。ts,formats:〔es,cjs〕}},plugins:〔vue()〕})
  这里我们选择打包cjs(CommonJS)和esm(ESModule)两种形式,cjs模式主要用于服务端引用(ssr),而esm就是我们现在经常使用的方式,它本身自带treeShaking而不需要额外配置按需引入(前提是你将模块分别导出),非常好用
  其实到这里就已经可以直接打包了;components下执行:pnpmrunbuild你就会发现打包了es和lib两个目录
  kitty1。jpg
  到这里其实打包的组件库只能给js项目使用,在ts项目下运行会出现一些错误,而且使用的时候还会失去代码提示功能,这样的话我们就失去了用ts开发组件库的意义了。所以我们需要在打包的库里加入声明文件(。d。ts)。
  那么如何向打包后的库里加入声明文件呢?其实很简单,只需要引入viteplugindtspnpmiviteplugindtsDw
  然后修改一下我们的vite。config。ts引入这个插件import{defineConfig}fromvite;importvuefromvitejspluginvueimportdtsfromviteplugindtsexportdefaultdefineConfig({build:{。。。},plugins:〔vue(),dts({指定使用的tsconfig。json为我们整个项目根目录下掉,如果不配置,你也可以在components下新建tsconfig。jsontsConfigFilePath:。。。。tsconfig。json}),因为这个插件默认打包到es下,我们想让lib目录下也生成声明文件需要再配置一个dts({outputDir:lib,tsConfigFilePath:。。。。tsconfig。json})〕})
  因为这个插件默认打包到es下,我们想让lib目录下也生成声明文件需要再配置一个dts插件,暂时没有想到其它更好的处理方法
  然后执行打包命令你就会发现你的es和lib下就有了声明文件
  其实后面就可以进行发布了,发布之前更改一下我们components下的package。json如下:{name:kittyui,version:1。0。0,main:libindex。js,module:esindex。js,scripts:{build:vitebuild},files:〔es,lib〕,keywords:〔kittyui,vue3组件库〕,author:小月,license:MIT,description:,typings:libindex。d。ts}
  解释一下里面部分字段
  pkg。module
  我们组件库默认入口文件是传统的CommonJS模块,但是如果你的环境支持ESModule的话,构建工具会优先使用我们的module入口
  pkg。files
  files是指我们1需要发布到npm上的目录,因为不可能components下的所有目录都被发布上去开始发布
  如果打包和发布流程你想做到自动化控制,你可以先点个赞,然后直接阅读从0搭建Vue3组件库:使用gulp自动化处理打包与发布〔1〕当然你也可以继续往下阅读,看下本篇文章的处理方式
  做了那么多终于到发布的阶段了;其实npm发包是很容易的,就拿我们的组件库kittyui举例吧
  发布之前记得到npm〔2〕官网注册个账户,如果你要发布xxxx这种包的话需要在npm新建个组织组织组织名就是后面的,比如我建的组织就是kittyui,注册完之后你就可以发布了
  首先要将我们代码提交到git仓库,不然pnpm发布无法通过,后面每次发版记得在对应包下执行pnpmversionpatch你就会发现这个包的版本号patch(版本号第三个数)1了,同样的pnpmversionmajormajor和pnpmversionminor分别对应版本号的第一和第二位增加。
  如果你发布的是公共包的话,在对应包下执行pnpmpublishaccesspublic
  输入你的账户和密码(记得输入密码的时候是不显示的,不要以为卡了)正常情况下应该是发布成功了
  注意
  发布的时候要将npm的源切换到npm的官方地址(registry。npmjs。org〔3〕);如果你使用了其它镜像源的话样式问题
  引入我们打包后的组件你会发现没有样式,所以你需要在全局引入我们的style。css才行;如main。ts中需要importkittyuiesstyle。css;
  很显然这种组件库并不是我们想要的,我们需要的组件库是每个css样式放在每个组件其对应目录下,这样就不需要每次都全量导入我们的css样式。
  下面就让我们来看下如何把样式拆分打包处理less文件
  首先我们需要做的是将less打包成css然后放到打包后对应的文件目录下,我们在components下新建build文件夹来存放我们的一些打包工具,然后新建buildLess。ts,首先我们需要先安装一些工具cpy和fastglobpnpmicpyfastglobDwcpy
  它可以直接复制我们规定的文件并将我们的文件copy到指定目录,比如buildLess。ts:importcpyfromcpyimport{resolve}frompathconstsourceDirresolve(dirname,。。src)lib文件consttargetLibresolve(dirname,。。lib)es文件consttargetEsresolve(dirname,。。es)console。log(sourceDir);constbuildLessasync(){awaitcpy({sourceDir}。less,targetLib)awaitcpy({sourceDir}。less,targetEs)}buildLess()
  然后在package。json中新增命令。。。scripts:{build:vitebuild,build:less:esnobuildbuildLess},。。。
  终端执行pnpmrunbuild:less你就会发现lib和es文件对应目录下就出现了less文件。
  但是我们最终要的并不是less文件而是css文件,所以我们要将less打包成css,所以我们需要用的less模块。在ts中引入less因为它本身没有声明文件所以会出现类型错误,所以我们要先安装它的typeslesspnpmisavedevtypeslessDw
  buildLess。ts如下(详细注释都在代码中)importcpyfromcpyimport{resolve,dirname}frompathimport{promisesasfs}fromfsimportlessfromlessimportglobfromfastglobconstsourceDirresolve(dirname,。。src)lib文件目录consttargetLibresolve(dirname,。。lib)es文件目录consttargetEsresolve(dirname,。。es)src目录constsrcDirresolve(dirname,。。src)constbuildLessasync(){直接将less文件复制到打包后目录awaitcpy({sourceDir}。less,targetLib)awaitcpy({sourceDir}。less,targetEs)获取打包后。less文件目录(lib和es一样)constlessFilsawaitglob(。less,{cwd:srcDir,onlyFiles:true})遍历含有less的目录for(letpathinlessFils){constfilePath{srcDir}{lessFils〔path〕}获取less文件字符串constlessCodeawaitfs。readFile(filePath,utf8)将less解析成cssconstcodeawaitless。render(lessCode,{指定src下对应less文件的文件夹为目录paths:〔srcDir,dirname(filePath)〕})拿到。css后缀pathconstcssPathlessFils〔path〕。replace(。less,。css)将css写入对应目录awaitfs。writeFile(resolve(targetLib,cssPath),code。css)awaitfs。writeFile(resolve(targetEs,cssPath),code。css)}}buildLess()
  执行打包命令之后你会发现对应文件夹下多了。css文件
  1657259623489。jpg
  现在我已经将css文件放入对应的目录下了,但是我们的相关组件并没有引入这个css文件;所以我们需要的是每个打包后组件的index。js中出现如:importxxxxxx。css
  之类的代码我们的css才会生效;所以我们需要对vite。config。ts进行相关配置
  首先我们先将。less文件忽略external:〔vue,。less〕,
  这时候打包后的文件中如buttonindex。js就会出现import。styleindex。less;
  然后我们再将打包后代码的。less换成。css就大功告成了。。。plugins:〔。。。{name:style,generateBundle(config,bundle){这里可以获取打包后的文件目录以及代码codeconstkeysObject。keys(bundle)for(constkeyofkeys){constbundler:anybundle〔keyasany〕rollup内置方法,将所有输出文件code中的。less换成。css,因为我们当时没有打包less文件this。emitFile({type:asset,fileName:key,文件名名不变source:bundler。code。replace(。lessg,。css)})}}}。。。〕。。。
  我们最终的vite。config。ts如下import{defineConfig}fromvite;importvuefromvitejspluginvueimportdtsfromviteplugindtsexportdefaultdefineConfig({build:{target:modules,打包文件目录outDir:es,压缩minify:false,css分离cssCodeSplit:true,rollupOptions:{忽略打包vue和。less文件external:〔vue,。less〕,input:〔srcindex。ts〕,output:〔{format:es,不用打包成。es。js,这里我们想把它打包成。jsentryFileNames:〔name〕。js,让打包目录和我们目录对应preserveModules:true,配置打包根目录dir:es,preserveModulesRoot:src},{format:cjs,不用打包成。mjsentryFileNames:〔name〕。js,让打包目录和我们目录对应preserveModules:true,配置打包根目录dir:lib,preserveModulesRoot:src}〕},lib:{entry:。index。ts,formats:〔es,cjs〕}},plugins:〔vue(),dts({指定使用的tsconfig。json为我们整个项目根目录下掉,如果不配置,你也可以在components下新建tsconfig。jsontsConfigFilePath:。。。。tsconfig。json}),因为这个插件默认打包到es下,我们想让lib目录下也生成声明文件需要再配置一个dts({outputDir:lib,tsConfigFilePath:。。。。tsconfig。json}),{name:style,generateBundle(config,bundle){这里可以获取打包后的文件目录以及代码codeconstkeysObject。keys(bundle)for(constkeyofkeys){constbundler:anybundle〔keyasany〕rollup内置方法,将所有输出文件code中的。less换成。css,因为我们当时没有打包less文件this。emitFile({type:asset,fileName:key,文件名名不变source:bundler。code。replace(。lessg,。css)})}}}〕})
  最后我们将打包less与打包组件合成一个命令(package。json):。。。scripts:{build:vitebuildesnobuildbuildLess},。。。
  后续直接执行pnpmrunbuild即可完成所有打包啦直接使用
  如果你不想一步步的搭建,想直接使用现成的话,你可以直接把项目clone下来kittyui〔4〕,然后你只需要以下几步便可将其完成安装pnpmnpmipnpmg安装esnonpmiesnog安装所有依赖pnpminstall本地测试进入examples文件夹执行pnpmrundev启动vue3项目打包pnpmrunbuild启动文档pnpmrundocs:dev打包文档pnpmrundocs:build启动打包后文档服务pnpmrundocs:serve写在最后
  由于作者水平有限,难免会存在一些错误或不妥之处,希望各位能够不吝指出,一定及时修改。如果你对这个项目有更好的想法或者建议也欢迎在评论区提出,不胜感激。
  后续我会对一些常用组件进行开发,每个组件的开发都会以文章的形式展现出来以供大家参考。如果有问题欢迎私信
  说明
  组件库最新代码导出方式写法有所改变,源码可能和文章有所出入,请注意查看

孩子们喜欢的奶香紫米包,做起来挺简单,包子松软馅料香甜,好吃我家两个小孩子都比较喜欢吃甜食,我自己也喜欢吃一些香甜软糯的食物。前段时间买了一些奶香紫米包,味道还不错,我和孩子们都挺喜欢的。寻思着也没什么难度,干脆买点紫米自己做吧。奶香紫米包喜欢记桃色日记的贪官潘玉梅,落马时家中搜出26公斤钞票清廉好比一瓶消毒液,我们时常要用它来消毒我们的心灵和双手又好似一块冰,我们时常要用它来冰冷一颗颗蠢蠢欲动的贪婪的心。自从我国十八大召开以后,就加大了反腐败的力度,不断有贪官污吏被组马卡利物浦是本泽马最喜欢的对手,本周主场作战他不会缺席直播吧3月14日讯欧冠八分之一决赛次回合,皇马将坐镇伯纳乌迎战利物浦。据马卡报报道,利物浦是本泽马最喜欢的对手之一,本周主场作战,这位皇马队长将不会缺席。虽然白衣军团在首回合以52湖北没落的七款名酒,哪一款最可惜?湖北名酒湖北省是国内的白酒产销大省,2020年的时候,湖北省白酒产量曾位居全国前三。目前,湖北的白酒市场份额超过了300亿,是国内兼香酒第一生产大省。自上世纪以来,湖北省就名酒辈出欧冠冠军vs其它洲冠军!官方2024年将开始新年度俱乐部冠军赛直播吧3月15日讯国际足联官方消息,从2024年开始将举办一年一度的洲际俱乐部冠军赛。当前的世俱杯将于2023年结束,32队的新世俱杯2025年开始。鉴于各协会表示,需要让顶级俱乐巴赫穆特决战时刻,乌总理坦白西方给的援助,都是乌克兰贷的款近日,巴赫穆特地区的战况越来越激烈,俄乌两军投入火力人力只增不减,就在乌克兰总统泽连斯基称要继续增援死守巴赫穆特之际,乌克兰总理坦白说其实乌克兰从西方拿到的都是贷款,乌克兰的国债已年度大烂片来了,比逐梦演艺圈还烂的那种好内容我来评大家好,欢迎来到烂片观众室我是不爱看烂片的诸葛小乔但是看烂片也要开心呀自诩看过很多烂片的小乔,终究还是低估了烂片的威力看过很多莫名奇妙的,逻辑不能自洽的就是没看过这么乱玩家请愿B社为星空添加阿拉伯语支持之前B社宣布星空将于9月6日发售,登陆Xbox和PC平台。现在数千名玩家在网上发起请愿,希望B社扩大本地化工作,为星空添加阿拉伯语支持。目前该请愿书已获得3400多名玩家支持,请愿历史上真实的孝庄丈夫不爱,儿子不亲,权力巅峰是刻骨的孤独她12岁嫁给皇太极,与姑姑哲哲姐姐海兰珠三人共侍一夫,一生从未回过故乡科尔沁,却以女子之身先后辅佐顺治康熙两代幼帝登基,稳定清初政治格局。在孝庄秘史康熙王朝等电视剧中,孝庄都是一个上年度最惨主角,只差一秒就能安全回家最近三年,我们在说世界电影的原创力正在下降时,常搬出疫情作为挡箭牌,但实际上这个观点在疫情之前就已出现。在谈及2022年欧洲十佳电影时,跟其他地区的感受相似,很难,有好的,但又不够中国启动星空地监测碳排放项目2023。3。15我国实现百兆比特率量子密钥分发中国科学技术大学潘建伟院士徐飞虎教授等与中科院上海微系统与信息技术研究所等单位的科研人员合作,通过发展高保真度集成光子学量子态调控高
观潮快评丨聚焦二十大中国化时代化的马克思主义,究竟为什么行?王小杨2020年9月17日,细雨飘飞的下午,习近平总书记走进千年学府岳麓书院,他在实事求是匾额前,凝思许久。2020年9月17日,习近平总书记来到湖南大学岳麓书院考察调研,勉励青年34岁本泽马捧起金球奖,梅罗时代谢幕当地时间10月17日,金球奖主办方法国足球官方宣布,效力皇家马德里的法国球员本泽马获得2022年金球奖。大器晚成202122赛季,本泽马以无懈可击的表现带领皇马队勇夺三冠王欧洲足球以小案释放司法温度湘潭岳塘区检察院在这样收获群众满意红网时刻记者肖帅通讯员徐高湘潭报道我们办的是案子,也是他们的人生,每一个小案件都关系到一个甚至多个家庭的切身利益,我们更应用情用心依法受理。今年9月第十五次全省检察工作会议上,湖南专访合肥市医保局局长唐世金医保支付方式改革有效遏制医疗费用不合理增长,群众次均个人负担费用同比下降20。8321世纪经济报道记者尤方明合肥报道2021年11月,国家医保局发布关于DRGDIP支付方式改革三年行动计划的通知(以下简称三年行动计划),DRG(按疾病诊断相关分组付费)与DIP(中统特工潜逃八年后在贵州当贫农,因说出四字暴露身份,结局如何如果您喜欢这篇文章,麻烦手动点击右上方的关注。感谢您的支持和鼓励,希望能带给您舒适的阅读体验。生要见人,死要见尸!他是周总理亲自点名追捕的国民党特务。他曾给总理寄过子弹出手打过郭沫传承非遗文化丰富群众生活绛州鼓乐走进洪洞大槐树景区近日,素有地动山摇闻声十里之誉的国家级非遗绛州鼓乐走进洪洞大槐树景区,为游客带来了一场精彩的鼓乐视听盛宴。这也是喜迎二十大奋进新征程2022年山西省群众文化活动的其中一项绛州鼓乐群构建制度环境引导社会资金投向科学研究中国网中国发展门户网讯本文的社会资金是指包括企业资金金融资本,以及以社会捐赠和基金会等为典型的非营利组织出资支持科学研究活动的各类经费科学研究是研究与发展(以下简称研发或RD)活动文旅部景区应提示引导来访旅游者遵守生态环境保护规定北京商报讯(记者吴其芸)10月18日,文旅部发布旅游景区文明引导工作指南,指导旅游景区及从业人员提示引导来访旅游者遵守生态环境保护规定,不践踏绿地花丛,不攀折花木果实,不破坏山石景习近平总书记参加党的二十大广西代表团讨论时的重要讲话引发热烈反响习近平总书记参加党的二十大广西代表团讨论时的重要讲话,在代表和广大干部群众中引发热烈反响。大家表示,要牢牢把握过去5年工作和新时代10年伟大变革的重大意义,牢牢把握习近平新时代中国为如期实现建军一百年奋斗目标砥砺奋进全军官兵认真收听收看党的二十大开幕会并展开学习讨论新华社北京10月18日电题为如期实现建军一百年奋斗目标砥砺奋进全军官兵认真收听收看党的二十大开幕会并展开学习讨论新华社记者同心向党庆盛会,凝心聚力向复兴。16日上午,党的二十大在京江西宜春,有个8000亿的目标前段时间发现了一张很有意思的图片,对此,有网友戏称真环江西发展。江西周边毗邻广东浙江福建等经济强省,这也让它在全国范围内几乎没什么存在感,甚至有很多人第一时间都想不起来江西的省会是
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网