Skip to content

Commit 4ec155a

Browse files
author
徐远翔
committed
feat: renderer & runtime
1 parent 4c3de99 commit 4ec155a

File tree

18 files changed

+170
-99
lines changed

18 files changed

+170
-99
lines changed

packages/cli/src/ReactNativeService.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import { IServiceOpts, Service } from '@umijs/core';
2-
import { dirname } from 'path';
2+
import { existsSync } from 'fs';
3+
import { dirname, join } from 'path';
4+
import assert from './utils/assert';
35

46
export class ReactNativeService extends Service {
57
constructor(opts: IServiceOpts) {
68
process.env.UMI_VERSION = require('../package').version;
79
process.env.UMI_DIR = dirname(require.resolve('../package'));
10+
const rn = join(opts.cwd, 'node_modules', '.bin', 'react-native');
11+
assert(
12+
existsSync(rn),
13+
`react-native was not found, Please execute "yarn install" to fetch all dependencies into "node_modules"`,
14+
);
15+
const app = join(opts.cwd, 'app.json');
16+
assert(existsSync(app), `${app} not exists`);
817

918
super({
1019
...opts,

packages/cli/src/utils/assert.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function assert(value: boolean, message: string) {
2+
if (!value) throw new Error(message);
3+
}

packages/preset/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default function (): { plugins: string[] } {
1414
require.resolve('./plugins/generateFiles/umi'),
1515

1616
// bundle configs
17+
require('./plugins/features/appKey'),
1718
// require.resolve('./plugins/features/alias'),
1819
// require.resolve('./plugins/features/analyze'),
1920
// require.resolve('./plugins/features/autoprefixer'),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IApi } from '@umijs/types';
2+
3+
export default (api: IApi) => {
4+
api.describe({
5+
key: 'appKey',
6+
config: {
7+
default: '',
8+
schema(joi) {
9+
return joi.string().allow('');
10+
},
11+
},
12+
});
13+
};

packages/preset/src/plugins/generateFiles/umi.tpl

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{{{ polyfillImports }}}
22
{{{ importsAhead }}}
33
import { plugin } from './core/plugin';
4+
import { createHistory } from './core/history';
45
import { ApplyPluginsType } from '{{{ runtimePath }}}';
56
import { renderClient } from '{{{ rendererPath }}}';
67
{{{ imports }}}
@@ -15,6 +16,8 @@ const getClientRender = (args: { hot?: boolean } = {}) => plugin.applyPlugins({
1516
// @ts-ignore
1617
routes: require('./core/routes').routes,
1718
plugin,
19+
history: createHistory(args.hot),
20+
appKey: '{{{ appKey }}}',
1821
});
1922
},
2023
args,

packages/preset/src/plugins/generateFiles/umi.ts

+24-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { readFileSync } from 'fs';
1+
import { existsSync, readFileSync } from 'fs';
22
import { join, dirname } from 'path';
3+
import { EOL } from 'os';
34
import { IApi } from '@umijs/types';
45
import { winPath } from '@umijs/utils';
6+
import assert from 'umi-react-native-cli/lib/utils/assert';
57

6-
export function importsToStr(imports: { source: string; specifier?: string }[]): string[] {
8+
export function importsToStr(imports: { source: string; specifier?: string }[]) {
79
return imports.map((imp) => {
810
const { source, specifier } = imp;
911
if (specifier) {
@@ -14,7 +16,7 @@ export function importsToStr(imports: { source: string; specifier?: string }[]):
1416
});
1517
}
1618

17-
export default function (api: IApi): void {
19+
export default function (api: IApi) {
1820
const {
1921
utils: { Mustache },
2022
} = api;
@@ -24,13 +26,30 @@ export default function (api: IApi): void {
2426
const rendererPath = await api.applyPlugins({
2527
key: 'modifyRendererPath',
2628
type: api.ApplyPluginsType.modify,
27-
initialValue: require.resolve('umi-react-native-renderer'),
29+
initialValue: require.resolve('@umijs/renderer-react'),
2830
});
31+
let appKey = api.config.appKey;
32+
if (!appKey) {
33+
const appJsonFilename = join(api.paths.cwd || process.cwd(), 'app.json');
34+
if (!existsSync(appJsonFilename)) {
35+
throw new Error(`${appJsonFilename} was not exists.`);
36+
}
37+
try {
38+
const appJson = JSON.parse(readFileSync(appJsonFilename, 'utf8'));
39+
appKey = appJson.name;
40+
} catch (ignored) {}
41+
}
42+
if (!appKey) {
43+
throw new TypeError(
44+
`"appKey" 未配置。${EOL}1. 请在UMI配置文件(比如:.umirc.js)中添加"appKey"字段,并设置一个值;${EOL}2. 或者在工程根目录下的 app.json 文件中设置"name"字段和值。${EOL}小贴士:${EOL}"appKey"即RN JS代码域中: "AppRegistry.registerComponent(appKey, componentProvider);"的第一个参数;也是iOS/Android原生代码中加载bundle时所需的"moduleName",其值通常是使用 react-native 命令行工具初始化新建RN工程时指定的项目名称。`,
45+
);
46+
}
2947
api.writeTmpFile({
3048
path: 'umi.ts',
3149
content: Mustache.render(umiTpl, {
50+
appKey,
3251
rendererPath: winPath(rendererPath),
33-
runtimePath: winPath(dirname(require.resolve('umi-react-native-runtime/package.json'))),
52+
runtimePath: winPath(dirname(require.resolve('@umijs/runtime/package.json'))),
3453
entryCode: (
3554
await api.applyPlugins({
3655
key: 'addEntryCode',

packages/renderer/package.json

+19-11
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@
1010
"homepage": "https://github.com/xuyuanxiang/umi-react-native#readme",
1111
"license": "MIT",
1212
"main": "lib/index.js",
13-
"module": "esm/index.js",
14-
"jsnext:module": "esm/index.js",
15-
"typings": "types/index.d.ts",
16-
"types": "types/index.d.ts",
13+
"module": "lib/index.esm.js",
14+
"jsnext:module": "lib/index.esm.js",
15+
"typings": "lib/index.d.ts",
16+
"types": "lib/index.d.ts",
1717
"sideEffects": false,
1818
"directories": {
1919
"lib": "lib"
2020
},
2121
"files": [
22-
"lib",
23-
"esm",
24-
"types",
25-
"src"
22+
"lib"
2623
],
2724
"publishConfig": {
2825
"registry": "https://registry.npmjs.org/"
@@ -32,17 +29,28 @@
3229
"url": "git+https://github.com/xuyuanxiang/umi-react-native.git"
3330
},
3431
"scripts": {
35-
"build": "tsc | tsc -p tsconfig.esm.json",
36-
"watch": "tsc -w"
32+
"build": "tsc -b",
33+
"watch": "tsc -b -w"
3734
},
3835
"bugs": {
3936
"url": "https://github.com/xuyuanxiang/umi-react-native/issues"
4037
},
38+
"peerDependencies": {
39+
"react": "^16.13.1",
40+
"react-native": "^0.62.2"
41+
},
4142
"dependencies": {
43+
"history-with-query": "^4.10.3",
4244
"react-router-config": "^5.1.1",
45+
"react-router-native": "^5.1.2",
4346
"umi-react-native-runtime": "^0.0.0"
4447
},
4548
"devDependencies": {
46-
"@types/react-router-config": "^5.0.1"
49+
"@types/react": "^16.9.34",
50+
"@types/react-native": "^0.62.2",
51+
"@types/react-router-config": "^5.0.1",
52+
"@types/react-router-native": "^5.1.0",
53+
"react": "^16.13.1",
54+
"react-native": "^0.62.2"
4755
}
4856
}

packages/renderer/src/IRoute.ts

-17
This file was deleted.

packages/renderer/src/index.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1-
export * from './IRoute';
1+
import { FunctionComponent } from 'react';
2+
import { History, Location } from 'history-with-query';
3+
import { match } from 'react-router-native';
4+
5+
interface IComponent extends FunctionComponent {
6+
getInitialProps?: Function;
7+
}
8+
9+
export interface IRoute {
10+
path?: string;
11+
exact?: boolean;
12+
redirect?: string;
13+
component?: IComponent;
14+
routes?: IRoute[];
15+
key?: any;
16+
strict?: boolean;
17+
sensitive?: boolean;
18+
wrappers?: any[];
19+
}
20+
21+
export interface IRouteComponentProps {
22+
children: JSX.Element;
23+
location: Location;
24+
route: IRoute;
25+
history: History;
26+
match: match;
27+
}
28+
229
export { default as renderClient } from './renderClient/renderClient';
330
export { default as renderRoutes } from './renderRoutes/renderRoutes';
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,57 @@
11
import React, { useEffect } from 'react';
2-
import { ApplyPluginsType, Plugin, NativeRouter } from 'umi-react-native-runtime';
3-
// import { matchRoutes } from 'react-router-config';
4-
import { IRoute } from '../IRoute';
2+
import { AppRegistry } from 'react-native';
3+
import { ApplyPluginsType, Plugin, Router } from 'umi-react-native-runtime';
4+
import { matchRoutes } from 'react-router-config';
5+
import { IRoute } from '..';
56
import renderRoutes from '../renderRoutes/renderRoutes';
67

78
interface IRouterComponentProps {
89
routes: IRoute[];
910
plugin: Plugin;
11+
history: any;
1012
}
1113

1214
interface IOpts extends IRouterComponentProps {
13-
rootElement?: string | HTMLElement;
15+
appKey: string;
1416
}
1517

1618
function RouterComponent(props: IRouterComponentProps) {
19+
const { history, ...renderRoutesProps } = props;
20+
1721
useEffect(() => {
18-
// function routeChangeHandler(location: any, action?: string) {
19-
// const matchedRoutes = matchRoutes(props.routes, location.pathname);
20-
//
21-
// props.plugin.applyPlugins({
22-
// key: 'onRouteChange',
23-
// type: ApplyPluginsType.event,
24-
// args: {
25-
// routes: props.routes,
26-
// matchedRoutes,
27-
// location,
28-
// action,
29-
// },
30-
// });
31-
// }
32-
// routeChangeHandler(history.location, 'POP');
33-
// return history.listen(routeChangeHandler);
22+
function routeChangeHandler(location: any, action?: string) {
23+
const matchedRoutes = matchRoutes(props.routes, location.pathname);
24+
25+
props.plugin.applyPlugins({
26+
key: 'onRouteChange',
27+
type: ApplyPluginsType.event,
28+
args: {
29+
routes: props.routes,
30+
matchedRoutes,
31+
location,
32+
action,
33+
},
34+
});
35+
}
36+
37+
routeChangeHandler(history.location, 'POP');
38+
return history.listen(routeChangeHandler);
3439
}, [history]);
3540

36-
return <NativeRouter>{renderRoutes(props)}</NativeRouter>;
41+
return <Router history={history}>{renderRoutes(renderRoutesProps)}</Router>;
3742
}
3843

3944
export default function renderClient(opts: IOpts) {
4045
const rootContainer = opts.plugin.applyPlugins({
4146
type: ApplyPluginsType.modify,
4247
key: 'rootContainer',
43-
initialValue: <RouterComponent routes={opts.routes} plugin={opts.plugin} />,
48+
initialValue: <RouterComponent history={opts.history} routes={opts.routes} plugin={opts.plugin} />,
4449
args: {
50+
history: opts.history,
4551
routes: opts.routes,
4652
plugin: opts.plugin,
4753
},
4854
});
49-
55+
AppRegistry.registerComponent(opts.appKey, rootContainer);
5056
return rootContainer;
5157
}

packages/renderer/src/renderRoutes/renderRoutes.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useEffect, useState } from 'react';
22
import { Plugin, Redirect } from 'umi-react-native-runtime';
3-
import { IRoute } from '../IRoute';
3+
import { IRoute } from '..';
44
import Switch from './Switch';
55
import Route from './Route';
66

@@ -48,6 +48,7 @@ function render({ route, opts, props }: { route: IRoute; opts: IOpts; props: obj
4848
...opts.extraProps,
4949
route,
5050
};
51+
// @ts-ignore
5152
let ret = <Component {...newProps}>{routes}</Component>;
5253

5354
// route.wrappers

packages/renderer/tsconfig.esm.json

-12
This file was deleted.

packages/renderer/tsconfig.json

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"extends": "../../tsconfig",
33
"compilerOptions": {
4+
"target": "es5",
5+
"lib": ["esnext"],
46
"rootDir": "src",
57
"outDir": "lib",
68
"declarationDir": "types"

packages/runtime/package.json

+9-13
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,16 @@
1010
"homepage": "https://github.com/xuyuanxiang/umi-react-native#readme",
1111
"license": "MIT",
1212
"main": "lib/index.js",
13-
"module": "esm/index.js",
14-
"jsnext:module": "esm/index.js",
15-
"typings": "types/index.d.ts",
16-
"types": "types/index.d.ts",
13+
"module": "lib/index.esm.js",
14+
"jsnext:module": "lib/index.esm.js",
15+
"typings": "lib/index.d.ts",
16+
"types": "lib/index.d.ts",
1717
"sideEffects": false,
1818
"directories": {
19-
"lib": "lib",
20-
"test": "test"
19+
"lib": "lib"
2120
},
2221
"files": [
23-
"lib",
24-
"esm",
25-
"types",
26-
"src",
27-
"test"
22+
"lib"
2823
],
2924
"publishConfig": {
3025
"registry": "https://registry.npmjs.org/"
@@ -34,13 +29,14 @@
3429
"url": "git+https://github.com/xuyuanxiang/umi-react-native.git"
3530
},
3631
"scripts": {
37-
"build": "tsc | tsc -p tsconfig.esm.json",
38-
"watch": "tsc -w"
32+
"build": "tsc -b",
33+
"watch": "tsc -b -w"
3934
},
4035
"bugs": {
4136
"url": "https://github.com/xuyuanxiang/umi-react-native/issues"
4237
},
4338
"dependencies": {
39+
"history-with-query": "^4.10.3",
4440
"react-router": "^5.1.2",
4541
"react-router-native": "^5.1.2"
4642
},

0 commit comments

Comments
 (0)