新聞中心
用過 React 的同學都知道,React 作為一個視圖庫,在進行 Web 開發(fā)的時候需要安裝兩個模塊。

為濱海新區(qū)等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及濱海新區(qū)網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都做網(wǎng)站、成都網(wǎng)站制作、濱海新區(qū)網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
- npm install react --save
- npm install react-dom --save
react 模塊主要提供了組件的生命周期、虛擬 DOM Diff、Hooks 等能力,以及將 JSX 轉(zhuǎn)換為虛擬 DOM 的 h 方法。而 react-dom 主要對外暴露一個 render 方法,將虛擬 DOM 轉(zhuǎn)化為真實 DOM。
- import React from 'react'
- import ReactDOM from 'react-dom'
- /* import ReactDOM from 'react-dom/server' //服務的渲染 */
- class Hello extends React.component {
- render() {
- return
Hello, world!
,- }
- }
- ReactDOM.render(
, - document.getElementById('root')
- )
如果我們將 react-dom 換成 react-native 就可以將虛擬 DOM 轉(zhuǎn)換為安卓或 iOS 的原生組件。我在之前的文章中介紹過,虛擬 DOM 最大的優(yōu)勢并不是其 Diff 算法,而是將 JSX 轉(zhuǎn)換為統(tǒng)一的 DSL,通過其抽象能力實現(xiàn)了跨平臺的能力。除了官方提供的 react-dom、react-native ,甚至可以渲染到命令行上,這也是我們今天介紹的 ink。
- npm ink: https://www.npmjs.com/package/react-dom
[[413983]] Ink
ink內(nèi)部使用 facebook 基于 C++ 開發(fā)的一款跨平臺渲染引擎 yoga,支持 Flex 布局,功能十分強大。另外,React Native 內(nèi)部使用了該引擎。
初始化
這里有一個官方提供的腳手架,我們可以直接通過這個腳手架來創(chuàng)建一個項目。
- $ mkdir ink-app
- $ cd ink-app
- $ npx create-ink-app
如果你想使用 TypeScript 來編寫項目,你也可以使用如下命令:
- $ npx create-ink-app --typescript
生成的代碼如下:
- // src/cli.js
- #!/usr/bin/env node
- const ink = require('ink')
- const meow = require('meow')
- const React = require('react')
- const importJsx = require('import-jsx')
- const ui = importJsx('./ui')
- const cli = meow(`
- Usage
- $ ink-cli
- Options
- --name Your name
- `)
- ink.render(React.createElement(ui, cli.flags))
- // src/ui.js
- const App = (props) => (
- Hello,
- { props.name || 'UserName' }
- )
- module.exports = App;
除了 ink 和 react,腳手架項目還引入了 meow、import-jsx 兩個庫。
meow 的主要作用是運行命令時,對參數(shù)進行解析,將解析的參數(shù)放到 flags 屬性中,其作用與 yargs、commander 一樣,是構(gòu)建 CLI 工具的必備利器。
- const meow = require('meow')
- // 傳入的字符串,作為 help 信息。
- const cli = meow(`
- Options
- --name Your name
- --age Your age
- `)
- console.log('flags: ', cli.flags)
另一個 import-jsx 的主要作用,就是將 jsx 字符串轉(zhuǎn)化為 createElement 方法的形式。
- // ui.js
- const component = (props) => (
- Hello,
- { props.name || 'UserName' }
- )
- // cli.js
- const importJsx = require('import-jsx')
- const ui = importJsx('./ui')
- console.log(ui.toString()) // 輸出轉(zhuǎn)化后的結(jié)果
- // 轉(zhuǎn)化結(jié)果:
- props => /*#__PURE__*/React.createElement(
- Text,
- null,
- "Hello, ",
- /*#__PURE__*/React.createElement(
- Text, {
- color: "green"
- },
- props.name || 'UserName'
- )
- )
這一步的工作一般由 babel 完成,如果我們沒有通過 babel 轉(zhuǎn)義 jsx,使用 import-jsx 就相當于是運行時轉(zhuǎn)義,對性能會有損耗。但是,在 CLI 項目中,本身對性能要求也沒那么高,通過這種方式,也能更快速的進行項目搭建。
內(nèi)置組件
由于是非瀏覽器的運行環(huán)境,ink 與 react-native 一樣提供了內(nèi)置的一些組件,用于渲染終端中的特定元素。
DEMO:
- // ui.js
- const React = require('react')
- const { Text } = require('ink')
- moudle.exports = () => (<>
I am text I am bold I am italic I am underline I am strikethrough I am green I am blue on gray - >)
- // cli.js
- const React = require('react')
- const importJsx = require('import-jsx')
- const { render } = require('ink')
- const ui = importJsx('./ui')
- render(React.createElement(ui))
其主要作用就是設置渲染到終端上的文本樣式,有點類似于 HTML 中的 標簽。
除了這種常見的 HTML 相關的文本屬性,還支持比較特殊的 wrap 屬性,用于將溢出的文本進行截斷。
長文本在超出終端的長度時,默認會進行換行處理。
loooooooooooooooooooooooooooooooooooooooong text
如果加上 wrap 屬性,會對長文本進行截斷。
- loooooooooooooooooooooooooooooooooooooooong text
除了從尾部截斷文本,還支持從文本中間和文本開始處進行截斷。
- loooooooooooooooooooooooooooooooooooooooong text
- loooooooooooooooooooooooooooooooooooooooong text
- loooooooooooooooooooooooooooooooooooooooong text
下面我們先給一個 然后在給內(nèi)部的兩個 最終效果如下: 比較特殊的屬性是邊框的樣式:borderStyle,和 CSS 提供的邊框樣式有點出入。
上面兩段代碼的表現(xiàn)形式一致:
ink 除了提供一些布局用的組件,還提供了一些 Hooks。 可用于監(jiān)聽用戶的輸入,useInput 接受一個回調(diào)函數(shù),用戶每次按下鍵盤的按鍵,都會調(diào)用 useInput 傳入的回調(diào),并傳入兩個參數(shù)。 第一個參數(shù):input ,表示按下按鍵對應的字符。第二個參數(shù):key ,為一個對象,對應按下的一些功能鍵。 具體支持哪些功能按鍵,可以參考官方文檔: 下面通過一個 DEMO,展示其具體的使用方式,在終端上記錄用戶的所有輸出,如果按下的是刪除鍵,則刪除最近記錄的一個字符。
對外暴露一個 exit 方法,用于退出終端。
用于獲取命令行的輸入流。這里用一個簡單的案例,來模擬用戶登錄。
用于獲取命令行的輸出流。會暴露 stdout 的寫入流,還會暴露一個 write 方法,用于在終端進行輸入。
除了內(nèi)置的這些組件和 Hooks 外,還有豐富的第三方生態(tài)。比如:Loading組件、超鏈接組件、表格組件、高亮組件、多選組件、圖片組件……
ink 屬于 React 生態(tài),自然能夠支持 React 官方提供的調(diào)試工具 React Devtools。 然后,在啟動應用時,在前面設置 DEV 全局變量。 運行后的效果如下:
React 確實是視圖開發(fā)的一把利器,再加上 Hooks 的加持,其抽象能力得到了進一步的提升,統(tǒng)一的 DSL 加上 虛擬 DOM,照理來說,是可以在任何平臺進行渲染的。甚至,微軟官方都開發(fā)了一個 React Native for Windows,關鍵是這個東西不僅僅能開發(fā) Windows 的桌面軟件,還可以開發(fā) mac 的桌面軟件。 有點跑題,說回 ink,大家熟知的 Gatsby 的命令行工具也是通過 ink 進行開發(fā)的。如果大家后續(xù)有本地的 CLI 工具需要實現(xiàn),可以考慮這款工具,至少不必煩惱如何在命令行進行文本對齊。
內(nèi)置 Hooks
useInput
useApp
useStdin
useStdout
第三方組件
ink-spinner
ink-link
ink-table
ink-syntax-highlight
ink-muti-select
調(diào)試工具
總結(jié)
分享標題:在命令行里也能使用React
標題來源:http://m.fisionsoft.com.cn/article/djshsso.html


咨詢
建站咨詢
