前言
纯前端我的项目和nodejs我的项目打包形式有很大的不同,本文的重点是如何在nodejs环境中应用react,并打包成二进制文件.
咱们通常开发前端我的项目时应用的各种cli个别都是这么装置的 npm install xxxcli ,这样装置后就能应用相应的xxxcli, 然而查看对应的cli文件;
如装置完本示例后就会现出 /usr/local/bin/ink-app这个文件, 查看此文件内容就会发现是nodejs代码,所以是依赖nodejs的运行环境的.
而想把nodejs我的项目真正转出二进制包,须要pkg命令把nodejs运行环境也打包进去...这就要解决react及其jsx语法带来的问题.
查了一会发现没有这么操作的,但这里有个我的项目wiki-cli 就是通过 node+react+ink 构建的一个cli我的项目,能够看到源码中有bin目录并且有可用的wiki二进制命令那就阐明下面的思路是可行的.这就引起了我的趣味.
示例
按上面链接中的步骤操作生成示例我的项目
$ mkdir ink-app$ cd ink-app$ npx create-ink-app
cli.js 文件大略如下,其中的正文和中文都是我前面理清思路后加的,默认示例中是没有的.
// cli.js#!/usr/bin/env node// 'use strict'; // 不启用严格模式// 这些都是谬误的// require("babel-register") // require("register")// 这句是才是对的// require('@babel/register');const React = require('react');const importJsx = require('import-jsx');const { render } = require('ink');const meow = require('meow');// node v12.22.0 反对此语法const myFunc = () => { console.log('hello world');}myFunc();// 其余的文件必须都得通过这种模式导入,并且此文件代码是失常的nodejs代码而不能蕴含jsxconst ui = importJsx('./ui');const cli = meow(` Usage $ ink-app Options --name Your name Examples $ ink-app --name=Jane Hello, Jane`);render(React.createElement(ui, cli.flags));
ui.js文件内容如下:
const React = require('react');const { Text, Box, useInput, useStdout, useStdin } = require('ink');const { useEffect, useState } = Reactmodule.exports = () => (<> <Text>I am text</Text> <Text bold>I am bold</Text> <Text italic>I am italic</Text> <Text underline>I am underline</Text> <Text strikethrough>I am strikethrough</Text> <Text color="green">I am green</Text> <Text color="blue" backgroundColor="gray">I am blue on gray</Text> <Box borderStyle="single"> <Text>single</Text> </Box> <Box borderStyle="double"> <Text>double</Text> </Box> <Box borderStyle="round"> <Text>round</Text> </Box> <Box borderStyle="bold"> <Text>bold</Text> </Box> <Box borderStyle="singleDouble"> <Text>singleDouble</Text> </Box> <Box borderStyle="doubleSingle"> <Text>doubleSingle</Text> </Box> <Box borderStyle="classic"> <Text>classic</Text> </Box></>)
运行
node cli.js
cli.js和ui.js都是nodejs文件格式,ui.js中尽管能应用react等jsx语法,但都在importJsx时进行了转化成js代码.这样运行能失常显示代码索要展现的性能.
打包
➜ ink-app git:(master) ✗ pkg . -t mac -o app> pkg@5.3.1> Error! This experimental syntax requires enabling one of the following parser plugin(s): 'jsx, flow, typescript' (5:24) /Users/xxxxx/ink-app/ui.js➜ ink-app git:(master) ✗
应用pkg打包就会发现报错了,查了半天也没找到真正能解决,应该是我这个想法太偏了...
解决
通常咱们会用 babel 来将浏览器未兼容的新语法编译为兼容的代码,以便在旧浏览器或者环境下运行。
除了编译运行外,babel 还提供了 @babel/register 来即时编译运行。
应用 @babel/register 的形式很简略,只须要将以下代码放在须要编译运行的代码引入前:require('@babel/register');想将jsx语法转成js,在文件入口头部加上上面这句.
require('@babel/register');
就这一句我加了各种版本的,各种版本不对名字类似终于让我找到了这句正确的....但运行发现还是报错...
而后我突发奇想的把ui.js改名成ui.jsx再运行,发现能够了!
我猜想是babel/register判断文件格式时可能会参考文件后缀.
总结
- 再cli.js文件头部加上 require('@babel/register');
- 将用到jsx语法的文件后缀都改成jsx
我这半吊子根底不扎实,网上找材料东一块西一块,有个思路也要摸索半天...前端之路路漫漫!
参考文章
在命令行里也能用 React
ink库
容易误人的古老示例
node pkg 打包一个为一个可执行程序(linux、windows、mac)
通过babel-register在nodejs端应用es6