Skip to content

Commit 49b665f

Browse files
raartsbrentvatne
authored andcommitted
WIP: Add react-native-web to the template (expo#599)
Add react-native-web to the template
1 parent 5067fb8 commit 49b665f

File tree

21 files changed

+705
-39
lines changed

21 files changed

+705
-39
lines changed

react-native-scripts/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
},
1515
"files": [
1616
"build",
17-
"template"
17+
"template",
18+
"template-with-web"
1819
],
1920
"bin": {
2021
"react-native-scripts": "./build/bin/react-native-scripts.js"

react-native-scripts/src/scripts/eject.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ from \`babel-preset-expo\` to \`babel-preset-react-native-stage-0/decorator-supp
205205
pkgJson.jest.preset = 'react-native';
206206
newDevDependencies.push('jest-react-native');
207207
} else {
208-
log(`${chalk.bold('Warning')}: it looks like you've changed the Jest preset from jest-expo to ${pkgJson.jest.preset}. We recommend you make sure this Jest preset is compatible with ejected apps.`)
208+
log(
209+
`${chalk.bold('Warning')}: it looks like you've changed the Jest preset from jest-expo to ${pkgJson.jest.preset}. We recommend you make sure this Jest preset is compatible with ejected apps.`
210+
);
209211
}
210212

211213
// no longer relevant to an ejected project (maybe build is?)

react-native-scripts/src/scripts/init.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import fse from 'fs-extra';
55
import path from 'path';
66
import pathExists from 'path-exists';
77
import spawn from 'cross-spawn';
8+
import minimist from 'minimist';
89
import log from '../util/log';
910
import install from '../util/install';
1011
import { hasYarn } from '../util/pm';
@@ -16,12 +17,37 @@ const DEFAULT_DEPENDENCIES = {
1617
'react-native': '0.52.0',
1718
};
1819

20+
const WEB_DEFAULT_DEPENDENCIES = {
21+
'expo-web': '^0.0.12',
22+
'react-dom': '16.0.0',
23+
'react-native-web': '^0.4.0',
24+
webpack: '^3.11.0',
25+
'webpack-dev-server': '2.9.4',
26+
};
27+
1928
// TODO figure out how this interacts with ejection
2029
const DEFAULT_DEV_DEPENDENCIES = {
2130
'jest-expo': '25.0.0',
2231
'react-test-renderer': '16.2.0',
2332
};
2433

34+
const WEB_DEFAULT_DEV_DEPENDENCIES = {
35+
'react-native-scripts': '^1.11.1',
36+
'babel-loader': '^7.1.2',
37+
'babel-plugin-expo-web': '^0.0.5',
38+
'babel-plugin-react-native-web': '^0.4.0',
39+
'babel-plugin-transform-decorators-legacy': '^1.3.4',
40+
'babel-plugin-transform-imports': '^1.4.1',
41+
'babel-plugin-transform-runtime': '^6.23.0',
42+
'file-loader': '^1.1.7',
43+
'css-loader': '^0.28.7',
44+
'style-loader': '^0.19.0',
45+
};
46+
47+
const arg = minimist(process.argv.slice(2), {
48+
boolean: ['with-web-support'],
49+
});
50+
2551
module.exports = async (appPath: string, appName: string, verbose: boolean, cwd: string = '') => {
2652
const ownPackageName: string = require('../../package.json').name;
2753
const ownPath: string = path.join(appPath, 'node_modules', ownPackageName);
@@ -74,6 +100,13 @@ https://github.com/npm/npm/issues/16991
74100
test: 'jest',
75101
};
76102

103+
if (arg['with-web-support']) {
104+
Object.assign(appPackage.scripts, {
105+
web: 'webpack-dev-server -d --config ./webpack.config.js --inline --hot --colors --content-base public/',
106+
build: 'NODE_ENV=production webpack -p --config ./webpack.config.js',
107+
});
108+
}
109+
77110
appPackage.jest = {
78111
preset: 'jest-expo',
79112
};
@@ -91,11 +124,16 @@ https://github.com/npm/npm/issues/16991
91124
Object.assign(appPackage.dependencies, DEFAULT_DEPENDENCIES);
92125
Object.assign(appPackage.devDependencies, DEFAULT_DEV_DEPENDENCIES);
93126

127+
if (arg['with-web-support']) {
128+
Object.assign(appPackage.dependencies, WEB_DEFAULT_DEPENDENCIES);
129+
Object.assign(appPackage.devDependencies, WEB_DEFAULT_DEV_DEPENDENCIES);
130+
}
131+
94132
// Write the new appPackage after copying so that we can include any existing
95133
await fse.writeFile(appPackagePath, JSON.stringify(appPackage, null, 2));
96134

97135
// Copy the files for the user
98-
await fse.copy(path.join(ownPath, 'template'), appPath);
136+
await fse.copy(path.join(ownPath, arg['with-web-support'] ? 'template-with-web' : 'template'), appPath);
99137

100138
// Rename gitignore after the fact to prevent npm from renaming it to .npmignore
101139
try {
@@ -128,7 +166,6 @@ https://github.com/npm/npm/issues/16991
128166

129167
log(
130168
`
131-
132169
Success! Created ${appName} at ${appPath}
133170
Inside that directory, you can run several commands:
134171

react-native-scripts/src/util/packager.js

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
// @flow
22

3-
import {
4-
PackagerLogsStream,
5-
Project,
6-
ProjectSettings,
7-
ProjectUtils,
8-
} from 'xdl';
3+
import { PackagerLogsStream, Project, ProjectSettings, ProjectUtils } from 'xdl';
94

105
import _ from 'lodash';
116
import spawn from 'cross-spawn';
@@ -46,9 +41,7 @@ async function cleanUpPackager(projectDir) {
4641
if (result === 'stopFailed') {
4742
// find RN packager pid, attempt to kill manually
4843
try {
49-
const { packagerPid } = await ProjectSettings.readPackagerInfoAsync(
50-
projectDir
51-
);
44+
const { packagerPid } = await ProjectSettings.readPackagerInfoAsync(projectDir);
5245
process.kill(packagerPid);
5346
} catch (e) {
5447
process.exit(1);
@@ -63,11 +56,7 @@ function shouldIgnoreMsg(msg) {
6356
msg.indexOf('Warning: PropTypes has been moved to a separate package') >= 0;
6457
}
6558

66-
function run(
67-
onReady: () => ?any,
68-
options: Object = {},
69-
isInteractive?: boolean = false
70-
) {
59+
function run(onReady: () => ?any, options: Object = {}, isInteractive?: boolean = false) {
7160
let packagerReady = false;
7261
let needsClear = false;
7362
let logBuffer = '';
@@ -78,9 +67,7 @@ function run(
7867
const watchmanExists = spawn.sync('which', ['watchman']).status === 0;
7968

8069
if (process.platform === 'darwin' && !watchmanExists) {
81-
const watcherDetails = spawn
82-
.sync('sysctl', ['kern.maxfiles'])
83-
.stdout.toString();
70+
const watcherDetails = spawn.sync('sysctl', ['kern.maxfiles']).stdout.toString();
8471
if (parseInt(watcherDetails.split(':')[1].trim()) < 5242880) {
8572
log.withTimestamp(
8673
`${chalk.red(`Unable to start server`)}
@@ -169,15 +156,12 @@ ${chalk.cyan(` sudo sysctl -w kern.maxfiles=5242880
169156
let packagerLogsStream = new PackagerLogsStream({
170157
projectRoot: projectDir,
171158
onStartBuildBundle: () => {
172-
progressBar = new ProgressBar(
173-
'Building JavaScript bundle [:bar] :percent',
174-
{
175-
total: 100,
176-
clear: true,
177-
complete: '=',
178-
incomplete: ' ',
179-
}
180-
);
159+
progressBar = new ProgressBar('Building JavaScript bundle [:bar] :percent', {
160+
total: 100,
161+
clear: true,
162+
complete: '=',
163+
incomplete: ' ',
164+
});
181165

182166
log.setBundleProgressBar(progressBar);
183167
},
@@ -199,9 +183,7 @@ ${chalk.cyan(` sudo sysctl -w kern.maxfiles=5242880
199183
log.withTimestamp(chalk.red(`Failed building JavaScript bundle`));
200184
} else {
201185
let duration = endTime - startTime;
202-
log.withTimestamp(
203-
chalk.green(`Finished building JavaScript bundle in ${duration}ms`)
204-
);
186+
log.withTimestamp(chalk.green(`Finished building JavaScript bundle in ${duration}ms`));
205187
}
206188
}
207189
},
@@ -296,11 +278,7 @@ const logStackTrace = (chunk, logFn, nestedLogFn, colorFn) => {
296278
}
297279

298280
if (unloggedFrames > 0) {
299-
nestedLogFn(
300-
colorFn(
301-
`- ... ${unloggedFrames} more stack frames from framework internals`
302-
)
303-
);
281+
nestedLogFn(colorFn(`- ... ${unloggedFrames} more stack frames from framework internals`));
304282
}
305283
};
306284

@@ -309,7 +287,7 @@ const logWithLevel = chunk => {
309287
return;
310288
}
311289

312-
let colorFn = (str) => str;
290+
let colorFn = str => str;
313291
if (chunk.level === bunyan.WARN) {
314292
colorFn = chalk.yellow;
315293
} else if (chunk.level === bunyan.ERROR) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"presets": ["babel-preset-expo"],
3+
"env": {
4+
"development": {
5+
"plugins": ["transform-react-jsx-source"]
6+
}
7+
}
8+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
[ignore]
2+
; We fork some components by platform
3+
.*/*[.]android.js
4+
5+
; Ignore templates for 'react-native init'
6+
<PROJECT_ROOT>/node_modules/react-native/local-cli/templates/.*
7+
8+
; Ignore RN jest
9+
<PROJECT_ROOT>/node_modules/react-native/jest/.*
10+
11+
; Ignore RNTester
12+
<PROJECT_ROOT>/node_modules/react-native/RNTester/.*
13+
14+
; Ignore the website subdir
15+
<PROJECT_ROOT>/node_modules/react-native/website/.*
16+
17+
; Ignore the Dangerfile
18+
<PROJECT_ROOT>/node_modules/react-native/danger/dangerfile.js
19+
20+
; Ignore Fbemitter
21+
<PROJECT_ROOT>/node_modules/fbemitter/.*
22+
23+
; Ignore "BUCK" generated dirs
24+
<PROJECT_ROOT>/node_modules/react-native/\.buckd/
25+
26+
; Ignore unexpected extra "@providesModule"
27+
.*/node_modules/.*/node_modules/fbjs/.*
28+
29+
; Ignore polyfills
30+
<PROJECT_ROOT>/node_modules/react-native/Libraries/polyfills/.*
31+
32+
; Ignore various node_modules
33+
<PROJECT_ROOT>/node_modules/react-native-gesture-handler/.*
34+
<PROJECT_ROOT>/node_modules/expo/.*
35+
<PROJECT_ROOT>/node_modules/react-navigation/.*
36+
<PROJECT_ROOT>/node_modules/xdl/.*
37+
<PROJECT_ROOT>/node_modules/reqwest/.*
38+
<PROJECT_ROOT>/node_modules/metro-bundler/.*
39+
40+
[include]
41+
42+
[libs]
43+
node_modules/react-native/Libraries/react-native/react-native-interface.js
44+
node_modules/react-native/flow/
45+
node_modules/expo/flow/
46+
47+
[options]
48+
emoji=true
49+
50+
module.system=haste
51+
52+
module.file_ext=.js
53+
module.file_ext=.jsx
54+
module.file_ext=.json
55+
module.file_ext=.ios.js
56+
57+
munge_underscores=true
58+
59+
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
60+
61+
suppress_type=$FlowIssue
62+
suppress_type=$FlowFixMe
63+
suppress_type=$FlowFixMeProps
64+
suppress_type=$FlowFixMeState
65+
suppress_type=$FixMe
66+
67+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
68+
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
69+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
70+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
71+
72+
unsafe.enable_getters_and_setters=true
73+
74+
[version]
75+
^0.56.0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import App from './src/App';
2+
3+
export default App;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react';
2+
import App from './App';
3+
4+
import renderer from 'react-test-renderer';
5+
6+
it('renders without crashing', () => {
7+
const rendered = renderer.create(<App />).toJSON();
8+
expect(rendered).toBeTruthy();
9+
});

0 commit comments

Comments
 (0)