将react构建的cli项目打包成二进制
前言
纯前端项目和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代码而不能包含jsx
const ui = importJsx('./ui');
const cli = meow(`
Usage
$ ink-appOptions
--nameYour nameExamples
$ 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 = () => (<>
I am text
I am bold
I am italic
I am underline
I am strikethrough
I am green
I am blue on gray
single
double
round
bold
singleDouble
doubleSingle
classic
>)
运行
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构建的cli项目打包成二进制】在命令行里也能用 React
ink库
容易误人的陈旧示例 node pkg 打包一个为一个可执行程序(linux、windows、mac)
通过babel-register在nodejs端使用es6
推荐阅读
- 即将到手三百万
- 思友人
- 20210307《挑战赛怂人胆》【能量将帅挑战赛(01)】
- 苍灵十二将I|苍灵十二将I 第一百二十五章 关门猎兽
- 那条灰色的人行道
- react|react 安装
- 《没有你我将会很幸福》
- 《将来的你,一定会感谢现在战胜烦恼的自己-------第四章/第十一节/用逆向思维解除烦恼》
- Flutter的ListView
- 牧人将归