熟悉前端框架React的同学肯定都了解听说过Ink,这是一个使用React来构建命令行应用程序的库。目前该工具已经有一个实验性质好玩的小工具已经转换为功能全面,实用性的生产UI类库,并大量的APP所使用,包括Gatsby,Parcel,Yarn,Terraform,tap,Prisma,Shopify,New York Times。本文我们介绍一下Ink最新发布新版本Ink3,不管懂不懂React,这个工具都值得我们去玩玩,尝试一下。
稳定性和性能
Ink 3解决了很多渲染错误,彻底重新考虑了文本渲染以及对Flexbox的整体支持并进行了重写,对某些需要重新渲染的频率很高的应用,性能可以提高2倍。
Ink 3比以前简单得多,这使问题更易于调试,重现和解决。
之前版本的Ink具有针对各种布局问题的多种解决方法,所以在呈现效果上也会和与其结果会略有差异。Ink 3对此做了巨大的改善。
Text颜色属性
之前给文本上色,必须使用单独的组件,如果文本层级比较多时候,很容易会引起混乱。
Ink 3中,将组件的功能都合并到的组件中,更友好易用,也符合一贯的Html签语法。
Hello Chongchong
对支持颜色扩展的终端,也Ink3支持十六进制的颜色代码或者RGB颜色语法
新增加的backgroundColor属性,可以用来给文本增加彩色范围和color属性一样。
box边框
新版本中组件,可以支持设置非常好看时尚的边框了:
borderStyle="round"borderColor="green"paddingX={1}flexDirection="column">Run npm i -g my-cli to update
边框的样式上也很丰富,总共支持7种边框样式,可根据应用和爱好进行选择合适的边框样式:
内置Hook
Ink 3内置了一组强大的钩子来管理的应用程序,其中包括:
useInput:用于读取用户输入。
useApp:退出应用。
useStdin:访问标准输入stdin。
useStdout:访问标准输出stdout。
useStderr:访问标准错误stderr。
useFocus和useFocusManager:管理焦点。
特别是useInput,现在可以更可靠地解析用户输入,可以正确检测用户何时按下了组合键,例如Shift + Tab。
新<Static>组件
如果需要渲染不可预测的而且数量庞大的列表项,建议使用新推出的组件。可以将当做特定终端下的虚拟列表技术的实现,对其仅呈现必要的列表项。将所有新项目永久呈现在用户界面其他部分上,而且一旦它们显示就无法更新。如果要对于诸如Jest之类需要记录数百个需要完成的测试项的工具他是最理想的选择:
{(test, index) => (Completed {test})}
在Ink 3中,性能超过之前类似功能的react-tiny-virtual-list库的。
下面是一个类似于Jest的UI的示例,其中使用渲染了完整的测试。
React Devtools支持
在Ink3中可以使用React Devtools检查Ink应用程序的输出。更神奇的是,可以更改任何组件的属性,并且无需重新启动即可即时查看CLI更新。
我们无需进行任何更改即可支持它,只需设置DEV=true环境变量并打开Devtools:
DEV=true node examples/counter
npx react-devtools
内置错误处理程序和日志拦截
当某个组件抛出错误时,React会向控制台显示一条非常冗长的错误消息,并显示一堆长长的堆栈。然而大多数情况下,这并没有什么用,尤其对于不是很资深的开发者而言。
Ink3通过自定义全局React错误边界,呈现外观优美错误消息,从而为解决问题提供了更简单,更直观的解决方案。
为了进一步改善开发人员的UX,Ink 3拦截了对console.log和console.error的调用,以确保日志可以正确显示在应用程序UI的上方,并且保证互不干扰。这是必要的,因为Ink一直需要更新渲染UI,有可能会覆盖的输出console.log。
焦点管理
如果应用一次显示了多个用户输入,则检测哪个输入具有焦点并应接收数据可能会变有点棘手。为了简化该过程,Ink提供了两个新的React内置钩子(前面内置hook提到了):
useFocus:用于获得焦点。
useFocusManager:以编程方式对焦点进行管理。
当组件调用useFocus钩子时,它会通知Ink UI中有一个新的焦点组件。每次用户按下Tab键,Ink都会将焦点传递到队列中的下一个可聚焦组件。
const First = () => {const {isFocused} = useFocus();return ({isFocused ? 'First item is focused' : 'First item is not focused'});
};const Second = () => {const {isFocused} = useFocus();return ({isFocused ? 'Second item is focused' : 'Second item is not focused'});};
const Example = () => ();
在上面的示例中,当用户按下Tab键时,焦点将在First和Second组件之间来回传递。
当应用需要手动管理焦点而无需等待用户输入时,可以使用useFocusManager钩子。它使可以将焦点切换到下一个或上一个组件,或者完全将其打开/关闭。
新<Spacer>组件
组件是一个方便的框,它会自动展开以填充所有可用空间。它与SwiftUI的内置代码非常相似。在下面的示例中,"左"和"右"标签将被推到侧面,因为填充了它们之间的空间。
同样,当容器具有列方向时,将改为垂直扩展。
新<Newline>组件
组件基本上是对手动插入一个或多个\n字符的替代。请注意,组件只能在组件内部使用。
HelloChongchong
如果需要插入多个换行符,可以添加一个count属性:
领取专属 10元无门槛券
私享最新 技术干货