当前位置: 首页 > 后端技术 > Node.js

将react搭建的cli项目打包成二进制

时间:2023-04-03 23:56:59 Node.js

前言纯前端项目和nodejs项目的打包方式有很大的不同。本文的重点是如何在nodejs环境下使用react,并将其打包成二进制文件。我们平时开发前端项目使用的各种clis一般都是这样安装的npminstallxxxcli,这样安装后就可以使用对应的xxxcli了,但是要查看对应的cli文件;比如/usr/local/bin/安装完本例后会出现ink-app文件,查看这个文件的内容会发现是nodejs代码,所以依赖nodejs运行环境。如果要真正将nodejs项目转出binary包,还需要pkg命令将nodejs运行环境打包...这是为了解决react及其jsx语法带来的问题。查了一会儿发现没有这个操作,但是这里有一个项目wiki-cli,是node+react+ink搭建的cli项目。可以在源码中看到如果有bin目录,并且有可用的wiki二进制命令,说明上述思路是可行的。这引起了我的兴趣。示例按照下面链接中的步骤生成示例工程$mkdirink-app$cdink-app$npxcreate-ink-appcli.js文件大致如下。评论和中文是我整理思路后补上的。没有默认示例。//cli.js#!/usr/bin/envnode//'usestrict';//不开启严格模式//这些都是错误的//require("babel-register")//require("register")//加上这句话不能解决//require('@babel/register');constReact=require('react');constimportJsx=require('import-jsx');const{render}=require('ink');constmeow=require('meow');//节点v12.22.0支持这种语法constmyFunc=()=>{console.log('helloworld');}myFunc();//其他文件必须以这种形式导入,而这个文件代码是普通的nodejs代码codeandcannotcontainjsx//但是在打包的时候经常会出现找不到ui文件的错误constui=importJsx('./ui');constcli=meow(`用法$ink-app选项--name你的名字例子$ink-app--name=Jane你好,简`);渲染(React.createElement(ui,cli.flags));ui.js文件内容如下:constReact=require('react');const{Text,Box,useInput,useStdout,useStdin}=require('ink');const{useEffect,useState}=Reactmodule.exports=()=>(<>我是文本我是粗体我是斜体我是下划线我是删除线我是绿色的我是灰色的蓝色singledouble??roundboldsingleDoubledoubleSingle经典/>)运行nodecli.jscli.js和ui.js都是nodejs文件格式。ui.js中虽然可以使用react等jsx语法,但是在importJsx的时候都转成js代码,这样才能正常显示需要代码显示的功能。包装?ink-appgit:(master)?pkg.-tmac-oapp>pkg@5.3.1>错误!此实验性语法需要启用以下解析器插件之一:'jsx,flow,typescript'(5:24)/Users/xxxxx/ink-app/ui.js?ink-appgit:(master)?If你用pkg打包,会发现报错,查了很久都没有找到真正的解决办法。应该是我的想法太偏了。。。解决办法通常我们使用babel将不兼容浏览器的新语法编译成兼容的代码,以便在旧的浏览器或环境中运行除了编译运行之外,babel还提供了@babel/register来实时编译运行。@babel/register的使用方法很简单,只需要在需要编译运行的代码前面加上如下代码即可:require('@babel/register');如果要将jsx语法转为js,在文件入口头添加下面这句.require('@babel/register');这句话我加了各种版本,各种版本的名字都不对,大同小异。终于找到了正确的那句话....但是我运行的时候还是报错。..package文件找不到helloworld/snapshot/ink-app/node_modules/yoga-layout-prebuilt/yoga-layout/build/Release/nbind.js:53throwex;^Error:Cannotfindmodule'./ui'这种情况就得手动转换es6文件,然后用pkg打包转换后的文件。通用命令如下:babel*.js-ddist/&&pkg。-tmac-oappsummary然后加上cli.js文件的header上面的require('@babel/register');不能有效解决二进制打包的问题。先使用babel将文件中所有使用es6语法的文件转换成满足当前节点操作的文件,然后使用pkg将翻译后的js文件打包发布。.json供大家参考,有些地方需要配置修改。{"name":"ink-app","version":"0.0.0","license":"MIT","bin":"dist/cli.js","engines":{"node":">=10"},"scripts":{"test":"xo&&ava","start":"nodecli.js","build":"babel*.js-ddist/&&pkg.-tmac-oapp"},"files":["cli.js","ui.js"],"pkg":{"scripts":["dist/*.js"],"assets":["dist/*"]},"dependencies":{"import-jsx":"^4.0.0","ink":"^3.0.9","meow":"^9.0.0","react":"^17.0.2"},"devDependencies":{"@ava/babel":"^2.0.0","@babel/cli":"^7.14.8","@babel/core":"^7.14.8","@babel/preset-env":"^7.14.8","@babel/preset-react":"^7.14.5","@babel/register":"^7.14.5","ava":"^3.15.0","chalk":"^4.1.1","eslint-config-xo-react":"^0.25.0","eslint-plugin-react":"^7.24.0","eslint-plugin-react-hooks":"^4.2.0","ink-testing-library":"^2.1.0","xo":"^0.39.1"},"ava":{"babel":true,"require":["@babel/register"]},"babel":{"presets":["@babel/preset-env","@babel/preset-react"]},"xo":{"extends":"xo-react","rules":{"react/prop-types":"off"}}}我基础不扎实,上网查资料,有想法还要摸索很久。。.前端之路漫漫!参考文章你也可以在命令行使用Reactink库nodejs使用ES6语法(两种方法)语法转换babel容易误导老例子nodepkg通过babel-register打包成一个可执行程序(linux,windows,mac)在nodejs端使用es6