From abc8dba6ea0c3520b4f6c7c774cc6a59a640fdff Mon Sep 17 00:00:00 2001 From: ykforerlang <1527997464@qq.com> Date: Thu, 19 Sep 2019 15:21:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(alita):=20=E6=B7=BB=E5=8A=A0init=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit alita 添加init命令,可以方便的初始化alita项目 --- README.md | 30 ++++++++-------- rn-template/index.js | 5 +++ rn-template/src/HelloWorld.js | 64 ++++++++++++++++++++++++++++++++++ rn-template/src/index.js | 42 ++++++++++++++++++++++ rn-template/src/rn_logo.png | Bin 0 -> 11247 bytes src/index.js | 9 ++++- src/util/initProject.js | 42 ++++++++++++++++++++++ 7 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 rn-template/index.js create mode 100644 rn-template/src/HelloWorld.js create mode 100644 rn-template/src/index.js create mode 100644 rn-template/src/rn_logo.png create mode 100644 src/util/initProject.js diff --git a/README.md b/README.md index 24aeda6..e3ac6bc 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > Alita,战斗天使阿丽塔,原型是《铳梦》中一位不断战斗和自我超越的生化改造少女。 [![npm Version](https://img.shields.io/npm/v/@areslabs/alita.svg)](https://www.npmjs.com/package/@areslabs/alita) -[![npm Downloads](https://img.shields.io/npm/dt/@areslabs/wx-react.svg)](https://www.npmjs.com/package/@areslabs/alita) +[![npm Downloads](https://img.shields.io/npm/dt/@areslabs/alita.svg)](https://www.npmjs.com/package/@areslabs/alita) [![npm License](https://img.shields.io/npm/l/@areslabs/alita.svg)](https://www.npmjs.com/package/@areslabs/alita) @@ -45,17 +45,22 @@ Alita不是新的框架,也没有提出新的语法规则,她只做一件事 若`-g`有权限问题,需要`sudo` ## Getting Started -我们在[examples](https://github.com/areslabs/alita/tree/master/examples)目录提供了丰富的样例代码,包括HelloWorld(Expo命令创建的HelloWorldExpo, 和react-native命令创建的HelloWorldRN), Todo, ReactRepos。 强烈建议你clone出一份,然后使用Alita转化,你可以在这些样例代码上尝试任何你想要的功能。 +我们在[examples](https://github.com/areslabs/alita/tree/master/examples)目录提供了丰富的样例代码, 强烈建议你clone出一份,然后使用Alita转化,你可以在这些样例代码上尝试任何你想要的功能。 -当然你也可以建立自己的RN应用: +当然你也可以使用如下的方式建立新的RN应用: ``` - react-native init myproject + react-native init myproject && alita init myproject ``` -**注意** 应用的路由需要使用[@areslabs/router](https://areslabs.github.io/alita/%E8%B7%AF%E7%94%B1.html)组件 +`alita init`命令 会对rn项目做一些调整。 -下面以`myproject`项目说明Alita的使用,由于Alita在转化的时候,依赖[@areslabs/router](https://areslabs.github.io/alita/%E8%B7%AF%E7%94%B1.html),所以请先参考Example目录下项目,做些许修改,然后在使用alita转化 +**注意:** RN 0.60 以后的项目,IOS需要依赖`CocoaPods`,导致初始化项目极其缓慢,可以使用其他版本的RN +``` + react-native init myproject --version 0.59.9 && alita init myproject +``` + +下面以`myproject`项目说明Alita的使用。 1. 调用alita命令将其转化为微信小程序应用 ``` @@ -68,21 +73,16 @@ Alita不是新的框架,也没有提出新的语法规则,她只做一件事 npm install ``` -3. 在[微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html)上运行`myprojectwp`代码。参考[微信小程序文档](https://developers.weixin.qq.com/miniprogram/dev/),导入`myprojectwp `目录, 运行。 +3. [微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html)从`myprojectwp`目录导入项目 - **Alita生成的小程序使用了小程序的npm功能, 所以需要在微信开发者工具下构建npm, 工具 --> 构建npm。如下图** +4. 在微信开发者工具下构建npm, 工具 --> 构建npm。如下图 ![buildnpm](./static/buildnpm.jpg) - (**如果开发者工具报:`module "xxx" is not defined"`,说明npm模块没有构建好,需要点击上图构建。**) -这样React Native应用就运行在了微信小程序 - -**注意**一般我们有两种方式创建React Native应用,一种是使用react-native命令, 另一种是使用expo。 这两种方式Alita都可以转化,但是不管是哪一种方式 -创建的项目,都会在项目根目录创建App.js, App.json文件。但是这两个文件在微信小程序平台有特别的意义,所以必须对这两个文件**重新命名**。 -react-native 命令创建的项目只需要把App.js 重命名比如RNApp.js即可, 而expo的方式需要[参考](https://docs.expo.io/versions/latest/sdk/register-root-component/#what-if-i-want-to-name-my) +5. 概率性的,由于构建npm发生在导入项目之后,可能会出现找不到包的错误,出现控制台错误,此时需要重启开发者工具,或者重新导入项目,[详见](https://github.com/areslabs/alita/issues/23)。 -另外, React Native命令默认会创建最新的版本,而目前最新的 0.45 及以上版本需要下载 boost 等几个第三方库编译。这些库在国内即便翻墙也很难下载成功,导致很多人无法运行iOS项目!!!中文网在论坛中提供了这些库的[国内下载链接](http://bbs.reactnative.cn/topic/4301/ios-rn-0-45%E4%BB%A5%E4%B8%8A%E7%89%88%E6%9C%AC%E6%89%80%E9%9C%80%E7%9A%84%E7%AC%AC%E4%B8%89%E6%96%B9%E7%BC%96%E8%AF%91%E5%BA%93-boost%E7%AD%89) +这样React Native应用就运行在了微信小程序 ## 命令行参数 alita命令有以下参数: diff --git a/rn-template/index.js b/rn-template/index.js new file mode 100644 index 0000000..94b28f8 --- /dev/null +++ b/rn-template/index.js @@ -0,0 +1,5 @@ +import {AppRegistry} from 'react-native'; +import App from './src/index'; +import {name as appName} from './app.json'; + +AppRegistry.registerComponent(appName, () => App); \ No newline at end of file diff --git a/rn-template/src/HelloWorld.js b/rn-template/src/HelloWorld.js new file mode 100644 index 0000000..9b7f6be --- /dev/null +++ b/rn-template/src/HelloWorld.js @@ -0,0 +1,64 @@ +import React, { Component } from "react"; +import { StyleSheet, Text, View, Platform } from "react-native" + +/** + * @areslabs/wx-animated 是参考小程序API实现的一套可以运行在React Native,小程序上的动画 + * 详情参考:https://areslabs.github.io/alita/%E5%8A%A8%E7%94%BB.html + */ +import {AnimatedImage, createAnimation} from '@areslabs/wx-animated' + +import rnLogoPng from './rn_logo.png' + +export default class HelloWorld extends Component { + + state = { + logoAni: null, + } + + componentDidMount() { + this.logoAni() + } + + render() { + return ( + + + + + + Hello {Platform.OS}! + + + + ); + } + + logoAni(num = 1) { + const ani = createAnimation({ + duration: 5000, + }) + ani.rotateZ(360 * num) + ani.step() + this.setState({ + logoAni: ani.export(() => { + this.logoAni(num + 1) + }) + }) + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "center", + alignItems: "center" + }, + logo: { + width: 100, + height: 100 + } +}) \ No newline at end of file diff --git a/rn-template/src/index.js b/rn-template/src/index.js new file mode 100644 index 0000000..f38f7e7 --- /dev/null +++ b/rn-template/src/index.js @@ -0,0 +1,42 @@ +/** + * 定义Router的文件,被称为入口文件,由于小程序的页面必须预先定义在 app.json 文件,json文件是静态的,所以入口文件的处理发生在编译阶段 + * 这就要求入口文件需要足够的静态可分析。 + * + * 具体对入口文件的限制,请参考:https://areslabs.github.io/alita/%E5%85%A5%E5%8F%A3%E6%96%87%E4%BB%B6.html + */ + +import React, {PureComponent} from 'react' + +/** + * alita转化的项目必须使用:@areslabs/router 路由,详细文档:https://areslabs.github.io/alita/%E8%B7%AF%E7%94%B1.html + */ +import {Router, Route, TabRouter} from '@areslabs/router' + +import HelloWorld from './HelloWorld' + +export default class App extends PureComponent { + + render() { + + return ( + + {/* + * 页面一定要在Router里面明确定义,即使应用只有一个页面 + */} + + + ) + } +} \ No newline at end of file diff --git a/rn-template/src/rn_logo.png b/rn-template/src/rn_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4ba9fcee40e45181f574677e5f1a1637cc27ec98 GIT binary patch literal 11247 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