前言

大家好,我是webfansplz.继将 Vue 渲染到嵌入式液晶屏后,明天要跟大家分享的是如何将Vue渲染到命令行工具 :).对于命令行工具,大家应该都比拟相熟了,比方vue-cli、Vite等.咱们在编写前端利用面向用户时,通常会十分关注用户体验,作为开发者,咱们在应用工具时,它给予咱们的开发者体验(DX)咱们也会非常关注. 古代前端工程化离不开CLI的开发与应用、那么是否能有较低成本的计划能让前端小伙伴疾速开发CLI,大家能够像编写前端利用一样搞定它.因而,Temir应运而生.

Temir

介绍

Temir,一个用Vue组件来编写命令行界面利用的工具.开发者只须要应用Vue就能够编写命令行利用,不须要任何额定的学习老本.

<script lang="ts" setup>import { ref } from '@vue/runtime-core'import { TBox, TText } from '@temir/core'const counter = ref(0)setInterval(() => {  counter.value++}, 100)</script><template>  <TBox>    <TText color="green">      {{ counter }} tests passed    </TText>  </TBox></template>

组件

Temir提供了一些根底组件帮忙开发者编写与扩大命令行工具:

文本组件 (Text)

文本组件能够显示文本,将其款式更改为粗体、下划线、斜体或删除线.

<TText color="green">  I am green</TText><TText color="black" background-color="white">  I am black on white</TText><TText color="white">  I am white</TText><TText :bold="true">  I am bold</TText><TText :italic="true">  I am italic</TText><TText :underline="true">  I am underline</TText><TText :strikethrough="true">  I am strikethrough</TText><TText :inverse="true">  I am inversed</TText>

盒子组件 (Box)

<Box>是构建布局必不可少的Temir组件.就像在浏览器中<div style='display: flex'>.它提供了一些构建布局的罕用属性,比方尺寸、内外边距、对齐形式等.

<template>  <TBox justify-content="flex-start">    <TText>X</TText>  </TBox>  // [X      ]  <TBox justify-content="center">    <TText>X</TText>  </TBox>  // [   X   ]  <TBox justify-content="flex-end">    <TText>X</TText>  </TBox>  // [      X]  <TBox justify-content="space-between">    <TText>X</TText>    <TText>Y</TText>  </TBox>  // [X      Y]  <TBox justify-content="space-around">    <TText>X</TText>    <TText>Y</TText>  </TBox>  // [  X   Y  ]</template>

换行组件 (Newline)

增加一个或多个换行符(\n)。 必须在<Text>组件中应用。

<script>import { TBox, TNewline, TText } from '@temir/core'</script><template>  <TBox>    <TText>      <TText color="green">        Hello      </TText>      <TNewline />      <TText color="red">        World      </TText>    </TText>  </TBox></template>

填充组件 (Spacer)

沿其蕴含布局的主轴开展的灵便空间。 作为填充元素之间所有可用空间的快捷方式,它十分有用。

例如,在具备默认伸缩方向(row)的<Box>中应用<Spacer>将把"Left"定位到右边,并将"Right"推到左边。

<script lang="ts" setup>import { TBox, TSpacer, TText } from '@temir/core'</script><template>  <TBox>    <TText>Left</TText>    <TSpacer />    <TText>Right</TText>  </TBox></template>

超链接组件 (Link)

<script lang="ts" setup>import { TBox, TText } from '@temir/core'import TLink from '@temir/link'</script><template>  <TBox    :margin="5"    width="20"    border-style="round"    justify-content="center"  >    <TLink url="https://github.com">      <TText color="yellow">        Hi      </TText>      <TText color="cyan">        Github      </TText>    </TLink>  </TBox></template>

加载中组件 (Spinner)

<script lang="ts" setup>import { TBox, TText } from '@temir/core'import TSpinner from '@temir/spinner'</script><template>  <TBox    :margin="5"    width="20"    border-style="round"    justify-content="center"  >    <TText>      <TText color="yellow">        <TSpinner />      </TText>      Loading    </TText>  </TBox></template>

标签页组件 (Tab)

<script lang="ts" setup>import { computed, ref } from '@vue/runtime-core'import { TBox, TText } from '@temir/core'import { TTab, TTabs } from '@temir/tab'const tabs = ['Vue', 'React', 'Angular', 'Solid', 'Svelte']const activeIndex = ref(0)const selectedText = computed(() => tabs[activeIndex.value])</script><template>  <TBox>    <TText>      Selected Text :      <TText color="red">        {{ selectedText }}      </TText>    </TText>  </TBox>  <TBox>    <TTabs :on-change="(index) => activeIndex = +index">      <TTab v-for="item in tabs" :key="item">        {{ item }}      </TTab>    </TTabs>  </TBox></template>

抉择组件

<script lang="ts" setup>import TSelectInput from '@temir/select-input'const items = [  {    label: 'Vue',    value: 'Vue',  },  {    label: 'Vite',    value: 'Vite',  },  {    label: 'Temir',    value: 'Temir',  },]function onSelect(value) {  console.log('selected', value)}</script><template>  <TSelectInput :items="items" :on-select="onSelect" /></template>

装置

npm install @temir/core

应用

<script lang="ts" setup>import { ref } from '@vue/runtime-core'import { TBox, TText } from '@temir/core'const counter = ref(0)setInterval(() => {  counter.value++}, 100)</script><template>  <TBox>    <TText color="green">      {{ counter }} tests passed    </TText>  </TBox></template>

HMR反对

后面咱们提到了开发者体验(DX),在当初的前端工程中,对开发者很有帮忙且提效的就是HMR,这么香的货色Temir没有理由不领有它,话不多说,间接展现:

开箱即用

应用Temir定制化CLI非常简单,咱们提供了@temir/cli帮忙你疾速构建一个基于Temir的CLI.

mkdir my-temir-clicd my-temir-clitouch main.tsnpm install @temir/cl# Dev (开发)temir main.ts# Build (打包)temir build main.ts

你能够通过下载这个 例子 来疾速开始,你也能够关上 repl.it sandbox来在线体验和尝试它。

演示

Hi Temir

Borders

Table

Vitest

实现

  • createRenderer

Temir的实现次要得益于Vue3杰出的跨平台能力,咱们能够通过createRenderer API创立一个自定义渲染器,通过创立宿主环境中对应的Node和Element,并对元素进行增删改查操作.

  • Yoga

Vue提供了跑在命令行界面的接口,那咱们就还短少一个布局引擎就能把Vue
跑在命令行工具了.Temir应用了Yoga,一款Flexbox布局引擎.应用你在构建浏览器利用时应用过的相似CSS的属性,为你的CLI构建杰出的用户界面。

致谢

  • 这个我的项目的灵感来源于ink
  • vite-node为实现HMR提供了强力的反对

结语

文章到这里就完结了,如果我的文章和我的项目对你有所启发和帮忙,请给一个star反对作者 ✌