SlideShare ist ein Scribd-Unternehmen logo
1 von 85
Downloaden Sie, um offline zu lesen
React Native GUIDE
⼊⾨からその裏側まで覗いてみよう
About Me
ビズリーチ・
キャンパス
学⽣、OB/OG 向けサイト
• Java8+Spring Boot
(Thymeleaf)
• ES2015+KnockoutJS
社内管理者向けサイト
• Java8+Spring Boot
• ES2015+React(+Redux)
アプリ
• Java8+Spring Boot
• Swift
React とは
React とは 1/3
https://facebook.github.io/react/ Facebook 製
• UI 構築⽤の JavaScript ライブラリ
• Declarative(宣⾔的)
– アプリの状態に応じたインタラクティブ
な UI を簡単に構築できる
– コードもわかりやすい
• Component-Based
– いわゆるコンポーネント(部品)指向
– ⾃分⾃⾝の状態も管理する
• Learn Once,Write Anywhere
– これだけ覚えればサーバサイドもスマホ
アプリも OK
React とは 2/3
https://speakerdeck.com/katamu
ki/es2015-react-dot-jswoxue-bu 弊社のおっさんが学んだ話(宣伝)
• コンポーネントを組み合わせて構築す
るコンポーネント指向の View ライブ
ラリ
• Facebook、インスタ、Yahoo!、
Airbnb などでも使われている
• VirtualDOMを⽤いた画⾯の差分描画を
⾏い⾼速な画⾯表⽰を提供する
React とは 3/3
https://facebook.github.io/react/t
utorial/tutorial.html
• Tutorial おすすめ
• ポイント
– ES2015
– React.Component
– this.prop
– this.state
– componentXXXMount
• ES2015 は以下ざっと読んでおくのが
おすすめ
– http://postd.cc/es6-cheatsheet/
– 「...」とか検索難易度⾼すぎる
React Native
とは
React Native とは 1/3
https://facebook.github.io/react-
native/ Facebook 製
• ネイティブアプリを JavaScript と
React を使⽤して構築できる
• ちゃんとサクサク動く本当のスマホア
プリが作れる
• (アプリなのに)ホットリローディン
グでさくさく開発できる
• Native コードも使える
React Native とは 2/3
https://facebook.github.io/react-
native/docs/getting-
started.html#content
アプリ⽤のコンポネントを確認して
おくと効率が良い
• こちらも Getting started から
Tutorial がおすすめ
React Native とは 3/3
http://www.slideshare.net/TadeuZagallo/a-tour-
of-react-native?qid=ddc291a4-7988-46dc-
b086-9cf3c92a7235&v=&b=&from_search=4 メリットとか
• 今後ますますアプリの需要は⾼まって
いく
• Android と iPhone で 70% 〜 90%
コードを共有可能
• ネイティブの勉強をゴリッとやらない
で良い
Question
React Native
の裏側を覗く
React Native の裏側を覗く
https://facebook.github.io/react-
native/docs/getting-
started.html#content Getting Started
• ⾊々インストール
– node
– watchman
– react-native-cli
– …
• 初期化
• 起動
react-native init AwesomeProject
react-native run-ios
React Native
の裏側を覗く
初期化処理を react-native init からみてみる
React Native の裏側を覗く
view `which react-native`
React Native の裏側を覗く
switch (commands[0]) {
case 'init':
if (!commands[1]) {
console.error(
'Usage: react-native init <ProjectName> [--verbose]'
);
process.exit(1);
} else {
init(commands[1], argv.verbose, argv.version);
}
break;
default:
...
React Native の裏側を覗く
function init(name, verbose, rnPackage) {
validatePackageName(name);
if (fs.existsSync(name)) {
createAfterConfirmation(name, verbose, rnPackage);
} else {
createProject(name, verbose, rnPackage);
}
}
React Native の裏側を覗く
function createProject(name, verbose, rnPackage) {
var root = path.resolve(name);
var projectName = path.basename(root);
console.log(
'This will walk you through creating a new React Native project in',
root
);
if (!fs.existsSync(root)) {
fs.mkdirSync(root);
}
・・・
React Native の裏側を覗く
・・・
var packageJson = {
name: projectName,
version: '0.0.1',
private: true,
scripts: {
start: 'node node_modules/react-native/local-cli/cli.js start'
}
};
fs.writeFileSync(path.join(root, 'package.json'),
JSON.stringify(packageJson));
process.chdir(root);
console.log('Installing react-native package from npm...');
・・・
React Native の裏側を覗く
・・・
if (verbose) {
runVerbose(root, projectName, rnPackage);
} else {
run(root, projectName, rnPackage);
}
}
React Native の裏側を覗く
function run(root, projectName, rnPackage) {
exec('npm install --save --save-exact ' + getInstallPackage(rnPackage),
function(e, stdout, stderr) {
if (e) {
console.log(stdout);
console.error(stderr);
console.error('`npm install --save --save-exact react-native`
failed');
process.exit(1);
}
checkNodeVersion();
var cli = require(CLI_MODULE_PATH());
cli.init(root, projectName);
});
}
React Native の裏側を覗く
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/cli.js
React Native の裏側を覗く
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional
grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
require('./packager/babelRegisterOnly')([
/private-cli¥/src/
]);
module.exports = require('./local-cli/cli.js');
React Native の裏側を覗く
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/cli.js
React Native の裏側を覗く
・・・
var cliEntry = require('./cliEntry');
if (require.main === module) {
cliEntry.run();
}
module.exports = cliEntry;
たらい回し
React Native の裏側を覗く
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/cliEntry.js
React Native の裏側を覗く
・・・
const init = require('./init/init');
・・・
module.exports = {
run: run,
init: init,
};
React Native の裏側を覗く
これ!
function run(root, projectName, rnPackage) {
exec('npm install --save --save-exact ' + getInstallPackage(rnPackage),
function(e, stdout, stderr) {
if (e) {
console.log(stdout);
console.error(stderr);
console.error('`npm install --save --save-exact react-native`
failed');
process.exit(1);
}
checkNodeVersion();
var cli = require(CLI_MODULE_PATH());
cli.init(root, projectName);
});
}
React Native の裏側を覗く
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/init/init.js
React Native の裏側を覗く
/**
* Creates the template for a React Native project given the provided
* parameters:
* @param projectDir Templates will be copied here.
* @param argsOrName Project name or full list of custom arguments
* for the generator.
*/
function init(projectDir, argsOrName) {
console.log('Setting up new React Native app in ' + projectDir);
const args = Array.isArray(argsOrName)
? argsOrName // argsOrName was e.g. ['AwesomeApp', '--verbose']
: [argsOrName].concat(process.argv.slice(4)); // argsOrName was e.g.
'AwesomeApp’
・・・続く
React Native の裏側を覗く
・・・続き
// args array is e.g. ['AwesomeApp', '--verbose']
if (!args || args.length === 0) {
console.error('react-native init requires a project name.');
return;
}
const newProjectName = args[0];
const options = minimist(args);
generateProject(projectDir, newProjectName, options);
}
React Native の裏側を覗く
function generateProject(destinationRoot, newProjectName, options) {
・・・中略
copyProjectTemplateAndReplace(
path.resolve('node_modules', 'react-native', 'local-cli', 'templates',
'HelloWorld'),
destinationRoot,
newProjectName
);
・・・中略
printRunInstructions(destinationRoot, newProjectName);
}
React Native の裏側を覗く
const copyProjectTemplateAndReplace =
require('../generator/copyProjectTemplateAndReplace');
・・・中略
require('../generator/printRunInstructions');
余談
余談(init.js)
const yarnVersion =
(!options.npm) &&
yarn.getYarnVersionIfAvailable() &&
yarn.isGlobalCliUsingYarn(destinationRoot);
・・・中略
if (yarnVersion) {
console.log('Adding React...');
execSync(`yarn add react@${reactVersion}`);
} else {
console.log('Installing React...');
execSync(`npm install react@${reactVersion} --save --save-exact`);
}
React Native の裏側を覗く
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/generator/copyProjectTemplateAndReplace.js
React Native の裏側を覗く
割愛します・・・
[react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/templates/HelloWorld
から
[react-native init したディレクトリ]/[アプリ名]
に HelloWorld を [アプリ名] に replace しながら頑張ってコピーしている処理
React Native の裏側を覗く
$ ls -l
total 64
drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 __tests__
-rw-r--r-- 1 ayumi.toukairin 386209875 31 12 8 20:25 _babelrc
-rw-r--r-- 1 ayumi.toukairin 386209875 114 12 8 20:25 _buckconfig
-rw-r--r-- 1 ayumi.toukairin 386209875 1425 12 8 20:25 _flowconfig
-rw-r--r-- 1 ayumi.toukairin 386209875 16 12 8 20:25 _gitattributes
-rw-r--r-- 1 ayumi.toukairin 386209875 415 12 8 20:25 _gitignore
-rw-r--r-- 1 ayumi.toukairin 386209875 2 12 8 20:25 _watchmanconfig
drwxr-xr-x 10 ayumi.toukairin 386209875 340 12 10 19:23 android
-rw-r--r-- 1 ayumi.toukairin 386209875 1106 12 8 20:25 index.android.js
-rw-r--r-- 1 ayumi.toukairin 386209875 1072 12 8 20:25 index.ios.js
drwxr-xr-x 5 ayumi.toukairin 386209875 170 12 10 19:23 ios
React Native の裏側を覗く
$ ls –l
total 24
drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 __tests__
drwxr-xr-x 10 ayumi.toukairin 386209875 340 12 10 19:23 android
-rw-r--r-- 1 ayumi.toukairin 386209875 1091 12 10 20:55 index.android.js
-rw-r--r-- 1 ayumi.toukairin 386209875 1057 12 10 20:55 index.ios.js
drwxr-xr-x 5 ayumi.toukairin 386209875 170 12 10 19:23 ios
drwxr-xr-x 569 ayumi.toukairin 386209875 19346 12 10 20:55 node_modules
-rw-r--r-- 1 ayumi.toukairin 386209875 421 12 10 20:55 package.json
React Native の裏側を覗く
$ ls –l ios
total 0
drwxr-xr-x 8 ayumi.toukairin 386209875 272 12 10 19:23 [アプリ名]
drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 [アプリ名].xcodeproj
drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 [アプリ名]Tests
というわけで
init 終わり!
Question
React Native
の裏側を覗く
続いて react-native run-ios をみてみる
React Native の裏側を覗く
view `which react-native`
React Native の裏側を覗く
・・・
var cli;
var cliPath = CLI_MODULE_PATH();
if (fs.existsSync(cliPath)) {
cli = require(cliPath);
}
// minimist api
var commands = argv._;
if (cli) {
cli.run();
} else {
・・・
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/cliEntry.js
React Native の裏側を覗く
React Native の裏側を覗く
function run() {
const setupEnvScript = /^win/.test(process.platform)
? 'setup_env.bat'
: 'setup_env.sh';
childProcess.execFileSync(path.join(__dirname, setupEnvScript));
const config = getCliConfig();
commands.forEach(cmd => addCommand(cmd, config));
commander.parse(process.argv);
・・・
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/setup_env.sh
React Native の裏側を覗く
React Native の裏側を覗く
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional
grant
# of patent rights can be found in the PATENTS file in the same directory.
# 2048 is the max for non root users on Mac
ulimit -n 2048
React Native の裏側を覗く
function run() {
const setupEnvScript = /^win/.test(process.platform)
? 'setup_env.bat'
: 'setup_env.sh';
childProcess.execFileSync(path.join(__dirname, setupEnvScript));
const config = getCliConfig();
commands.forEach(cmd => addCommand(cmd, config));
commander.parse(process.argv);
・・・続く
React Native の裏側を覗く
・・・続き
const isValidCommand = commands.find(cmd => cmd.name.split(' ')[0] ===
process.argv[2]);
if (!isValidCommand) {
printUnknownCommand(process.argv[2]);
return;
}
if (!commander.args.length) {
commander.help();
}
}
迷⼦になった
React Native の裏側を覗く
function run() {
const setupEnvScript = /^win/.test(process.platform)
? 'setup_env.bat'
: 'setup_env.sh';
childProcess.execFileSync(path.join(__dirname, setupEnvScript));
const config = getCliConfig();
commands.forEach(cmd => addCommand(cmd, config));
commander.parse(process.argv);
・・・続く ここらしい!
React Native の裏側を覗く
const commander = require('commander');
・・・中略
function run() {
const setupEnvScript = /^win/.test(process.platform)
? 'setup_env.bat'
: 'setup_env.sh';
childProcess.execFileSync(path.join(__dirname, setupEnvScript));
const config = getCliConfig();
commands.forEach(cmd => addCommand(cmd, config));
commander.parse(process.argv);
・・・
https://tj.github.io/commander.js/
### Command#parse()
Parse argv, settings options and invoking
commands when defined.
React Native の裏側を覗く
const addCommand = (command: Command, config: ConfigT) => {
const options = command.options || [];
const cmd = commander
.command(command.name, undefined, {
noHelp: !command.description,
})
.description(command.description)
.action(function runAction() {
const passedOptions = this.opts();
const argv: Array<string> = Array.from(arguments).slice(0, -1);
Promise.resolve()
.then(() => {
assertRequiredOptions(options, passedOptions);
return command.func(argv, config, passedOptions);
})
.catch(handleError);
});
・・・
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/runIOS/runIOS.js
React Native の裏側を覗く
React Native の裏側を覗く
function runIOS(argv, config, args) {
process.chdir(args.projectPath);
const xcodeProject = findXcodeProject(fs.readdirSync('.'));
if (!xcodeProject) {
throw new Error('Could not find Xcode project files in ios folder');
}
・・・中略
if (args.device) {
・・・中略
} else {
return runOnSimulator(xcodeProject, args, inferredSchemeName, scheme);
}
}
React Native の裏側を覗く
function runOnSimulator(xcodeProject, args, inferredSchemeName, scheme){
return new Promise((resolve) => {
try {
var simulators = JSON.parse(
child_process.execFileSync('xcrun', ['simctl', 'list', '--json',
'devices'], {encoding: 'utf8'})
);
} catch (e) {
throw new Error('Could not parse the simulator list output');
}
const selectedSimulator = findMatchingSimulator(simulators,
args.simulator);
if (!selectedSimulator) {
throw new Error(`Could not find ${args.simulator} simulator`);
}
・・・
React Native の裏側を覗く
Usage: xcrun [options] <tool name> ... arguments ...
Find and execute the named command line tool from the active developer directory.
The active developer directory can be set using `xcode-select`, or via the
DEVELOPER_DIR environment variable. See the xcrun and xcode-select manualpages for
more information.
React Native の裏側を覗く
・・・
const simulatorFullName = formattedDeviceName(selectedSimulator);
console.log(`Launching ${simulatorFullName}...`);
try {
child_process.spawnSync('xcrun', ['instruments', '-w',
selectedSimulator.udid]);
} catch (e) {
// instruments always fail with 255 because it expects more arguments,
// but we want it to only launch the simulator
}
resolve(selectedSimulator.udid)
})
・・・
React Native の裏側を覗く
・・・
.then((udid) => buildProject(xcodeProject, udid, scheme,
args.configuration))
.then((appName) => {
if (!appName) {
appName = inferredSchemeName;
}
let appPath = getBuildPath(args.configuration, appName);
console.log(`Installing ${appPath}`);
child_process.spawnSync('xcrun', ['simctl', 'install', 'booted',
appPath], {stdio: 'inherit'});
・・・
React Native の裏側を覗く
・・・
const bundleID = child_process.execFileSync(
'/usr/libexec/PlistBuddy',
['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')],
{encoding: 'utf8'}
).trim();
console.log(`Launching ${bundleID}`);
child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted',
bundleID], {stdio: 'inherit'});
})
}
view [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/packager/react-native-xcode.sh
React Native の裏側を覗く
React Native の裏側を覗く
#!/bin/bash
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
・・・中略
case "$CONFIGURATION" in
Debug)
# Speed up build times by skipping the creation of the offline package
for debug
# builds on the simulator since the packager is supposed to be running
anyways.
if [[ "$PLATFORM_NAME" == *simulator ]]; then
echo "Skipping bundling for Simulator platform"
exit 0;
fi
・・・
また
迷⼦になった
xcodebuild -project [アプリ名].xcodeproj -configuration Debug -scheme [アプリ
名] -destination id=[udid] -derivedDataPath build
React Native の裏側を覗く
vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/React/React.xcodeproj/project.pbxproj
React Native の裏側を覗く
React Native の裏側を覗く
#!/bin/sh
if [ -z "${RCT_NO_LAUNCH_PACKAGER+xxx}" ] ; then
if nc -w 5 -z localhost 8081 ; then
if ! curl -s "http://localhost:8081/status" | grep -q "packager-
status:running" ; then
echo "Port 8081 already in use, packager is either not running or not
running correctly"
exit 2
fi
else
open "$SRCROOT/../packager/launchPackager.command" || echo "Can't start
packager automatically"
fi
fi
vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/packager/launchPackager.command
React Native の裏側を覗く
React Native の裏側を覗く
#!/usr/bin/env bash
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
・・・中略
# Set terminal title
echo -en "¥033]0;React Packager¥a"
clear
THIS_DIR=$(dirname "$0")
pushd "$THIS_DIR"
source ./packager.sh
popd
echo "Process terminated. Press <enter> to close the window"
read
vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/packager/packager.sh
React Native の裏側を覗く
React Native の裏側を覗く
#!/usr/bin/env bash
# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional
grant
# of patent rights can be found in the PATENTS file in the same directory.
THIS_DIR=$(dirname "$0")
node "$THIS_DIR/../local-cli/cli.js" start "$@"
vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/server/server.js
React Native の裏側を覗く
React Native の裏側を覗く
/**
* Starts the React Native Packager Server.
*/
function server(argv, config, args) {
・・・中略
console.log(formatBanner(
'Running packager on port ' + args.port + '.¥n¥n' +
'Keep this packager running while developing on any JS projects. ' +
'Feel free to close this tab and run your own packager instance if you ' +
'prefer.¥n¥n' +
'https://github.com/facebook/react-native', {
marginLeft: 1,
marginRight: 1,
paddingBottom: 1,
})
);
・・・中略
runServer(args, config, () => console.log('¥nReact packager ready.¥n'));
}
vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react-
native/local-cli/server/runServer.js
React Native の裏側を覗く
いよいよ
HotDeploy部分
。。。
ごめんなさい。
まとめ
まとめ
• React の知識を覚えるとスマホアプリが作れる、ということでそのメリットは
⼤きい
• といいつつも、ハマった時のことを考えると node とアプリ構築(xcode)の
知識はある程度有ったほうが良さそう
• 割と⾟かった、でも勉強になった
– Simulator ⽴ち上げるまでのコードは⼤体把握できたので、ある程度トラブルシュー
ティングもできるようになれば良いな・・・
• いつか続きも読みたいな
Question
Thank
you

Weitere ähnliche Inhalte

Was ist angesagt?

今からでも遅くない! React事始め
今からでも遅くない! React事始め今からでも遅くない! React事始め
今からでも遅くない! React事始め
ynaruta
 
Spring Bootで変わる Javaアプリ開発! #jsug
Spring Bootで変わる Javaアプリ開発! #jsugSpring Bootで変わる Javaアプリ開発! #jsug
Spring Bootで変わる Javaアプリ開発! #jsug
Toshiaki Maki
 

Was ist angesagt? (20)

scala-kaigi1-sbt
scala-kaigi1-sbtscala-kaigi1-sbt
scala-kaigi1-sbt
 
今からでも遅くない! React事始め
今からでも遅くない! React事始め今からでも遅くない! React事始め
今からでも遅くない! React事始め
 
Java + React.jsでSever Side Rendering #reactjs_meetup
Java + React.jsでSever Side Rendering #reactjs_meetupJava + React.jsでSever Side Rendering #reactjs_meetup
Java + React.jsでSever Side Rendering #reactjs_meetup
 
Responsableを使ったadr実装
Responsableを使ったadr実装Responsableを使ったadr実装
Responsableを使ったadr実装
 
LaravelでAPI定義を管理する
LaravelでAPI定義を管理するLaravelでAPI定義を管理する
LaravelでAPI定義を管理する
 
Laravelでfacadeを使わない開発
Laravelでfacadeを使わない開発Laravelでfacadeを使わない開発
Laravelでfacadeを使わない開発
 
laravel x モバイルアプリ
laravel x モバイルアプリlaravel x モバイルアプリ
laravel x モバイルアプリ
 
Gradle布教活動
Gradle布教活動Gradle布教活動
Gradle布教活動
 
こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールこんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツール
 
WkWebViewのキャッシュについて調べた
WkWebViewのキャッシュについて調べたWkWebViewのキャッシュについて調べた
WkWebViewのキャッシュについて調べた
 
Laravel5を使って開発してみた
Laravel5を使って開発してみたLaravel5を使って開発してみた
Laravel5を使って開発してみた
 
Gradle handson
Gradle handsonGradle handson
Gradle handson
 
Service workerとwebプッシュ通知
Service workerとwebプッシュ通知Service workerとwebプッシュ通知
Service workerとwebプッシュ通知
 
javascript を Xcode でテスト
javascript を Xcode でテストjavascript を Xcode でテスト
javascript を Xcode でテスト
 
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsugSpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug
 
let UIWebView as WKWebView
let UIWebView as WKWebViewlet UIWebView as WKWebView
let UIWebView as WKWebView
 
フレームワーク品評会 Ruby on Rails #crossjp
フレームワーク品評会 Ruby on Rails #crossjpフレームワーク品評会 Ruby on Rails #crossjp
フレームワーク品評会 Ruby on Rails #crossjp
 
LightNode - Micro RPC/REST Framework
LightNode - Micro RPC/REST FrameworkLightNode - Micro RPC/REST Framework
LightNode - Micro RPC/REST Framework
 
Spring Bootで変わる Javaアプリ開発! #jsug
Spring Bootで変わる Javaアプリ開発! #jsugSpring Bootで変わる Javaアプリ開発! #jsug
Spring Bootで変わる Javaアプリ開発! #jsug
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koa
 

Andere mochten auch

簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
dcubeio
 

Andere mochten auch (20)

Intro to react native
Intro to react nativeIntro to react native
Intro to react native
 
React native - What, Why, How?
React native - What, Why, How?React native - What, Why, How?
React native - What, Why, How?
 
A tour of React Native
A tour of React NativeA tour of React Native
A tour of React Native
 
覚えて帰ろうJavaデザインパターン
覚えて帰ろうJavaデザインパターン覚えて帰ろうJavaデザインパターン
覚えて帰ろうJavaデザインパターン
 
はじめてのAws lambda
はじめてのAws lambdaはじめてのAws lambda
はじめてのAws lambda
 
React Native Introduction: Making Real iOS and Android Mobile App By JavaScript
React Native Introduction: Making Real iOS and Android Mobile App By JavaScriptReact Native Introduction: Making Real iOS and Android Mobile App By JavaScript
React Native Introduction: Making Real iOS and Android Mobile App By JavaScript
 
React NativeでTwitterクライアントを作ってみよう
React NativeでTwitterクライアントを作ってみようReact NativeでTwitterクライアントを作ってみよう
React NativeでTwitterクライアントを作ってみよう
 
簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
簡単、クレカ決済! PAY.JPを使ったクレカ決済の仕組み・開発運用時の考慮点について
 
Ansibleで始めるインフラ構築自動化
Ansibleで始めるインフラ構築自動化Ansibleで始めるインフラ構築自動化
Ansibleで始めるインフラ構築自動化
 
おっさんES6/ES2015,React.jsを学ぶ
おっさんES6/ES2015,React.jsを学ぶおっさんES6/ES2015,React.jsを学ぶ
おっさんES6/ES2015,React.jsを学ぶ
 
Intro To React Native
Intro To React NativeIntro To React Native
Intro To React Native
 
What's This React Native Thing I Keep Hearing About?
What's This React Native Thing I Keep Hearing About?What's This React Native Thing I Keep Hearing About?
What's This React Native Thing I Keep Hearing About?
 
Getting Started with React Native (and should I use it at all?)
Getting Started with React Native (and should I use it at all?)Getting Started with React Native (and should I use it at all?)
Getting Started with React Native (and should I use it at all?)
 
When to (use / not use) React Native.
When to (use / not use) React Native.When to (use / not use) React Native.
When to (use / not use) React Native.
 
React native vol3
React native vol3React native vol3
React native vol3
 
GoogleTagManagerを使ってタグ運用を楽にしませんか?
GoogleTagManagerを使ってタグ運用を楽にしませんか?GoogleTagManagerを使ってタグ運用を楽にしませんか?
GoogleTagManagerを使ってタグ運用を楽にしませんか?
 
バッチ高速化のあゆみ
バッチ高速化のあゆみバッチ高速化のあゆみ
バッチ高速化のあゆみ
 
[D3]サーバーレスでサービスを作ってみた話
[D3]サーバーレスでサービスを作ってみた話[D3]サーバーレスでサービスを作ってみた話
[D3]サーバーレスでサービスを作ってみた話
 
機械学習を支えるX86 64の拡張命令セットを読む会 20170212
機械学習を支えるX86 64の拡張命令セットを読む会 20170212機械学習を支えるX86 64の拡張命令セットを読む会 20170212
機械学習を支えるX86 64の拡張命令セットを読む会 20170212
 
React Native Internals
React Native InternalsReact Native Internals
React Native Internals
 

Ähnlich wie React Native GUIDE

13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
Takayoshi Tanaka
 
TDC20111031_Groovy_Geb
TDC20111031_Groovy_GebTDC20111031_Groovy_Geb
TDC20111031_Groovy_Geb
Nobuhiro Sue
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
papamitra
 
G*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+BetamaxG*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+Betamax
Nobuhiro Sue
 
明日から使える Java SE 7
明日から使える Java SE 7明日から使える Java SE 7
明日から使える Java SE 7
Yuichi Sakuraba
 
Ruby on Rails3 Tutorial Chapter3
Ruby on Rails3 Tutorial Chapter3Ruby on Rails3 Tutorial Chapter3
Ruby on Rails3 Tutorial Chapter3
Sea Mountain
 

Ähnlich wie React Native GUIDE (20)

Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for Java
 
どこよりも早い Spring Boot 1.2 解説 #渋谷Java
どこよりも早い Spring Boot 1.2 解説 #渋谷Javaどこよりも早い Spring Boot 1.2 解説 #渋谷Java
どこよりも早い Spring Boot 1.2 解説 #渋谷Java
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
RでつくるWebアプリ~rApache編~
RでつくるWebアプリ~rApache編~RでつくるWebアプリ~rApache編~
RでつくるWebアプリ~rApache編~
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
絶対落ちないアプリの作り方
絶対落ちないアプリの作り方絶対落ちないアプリの作り方
絶対落ちないアプリの作り方
 
Gws 20130315 gradle_handson
Gws 20130315 gradle_handsonGws 20130315 gradle_handson
Gws 20130315 gradle_handson
 
TDC20111031_Groovy_Geb
TDC20111031_Groovy_GebTDC20111031_Groovy_Geb
TDC20111031_Groovy_Geb
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
 
react_rails
react_railsreact_rails
react_rails
 
SDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireSDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 Whire
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
G*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+BetamaxG*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+Betamax
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
 
Tottoruby 20110903
Tottoruby 20110903Tottoruby 20110903
Tottoruby 20110903
 
明日から使える Java SE 7
明日から使える Java SE 7明日から使える Java SE 7
明日から使える Java SE 7
 
Ruby on Rails3 Tutorial Chapter3
Ruby on Rails3 Tutorial Chapter3Ruby on Rails3 Tutorial Chapter3
Ruby on Rails3 Tutorial Chapter3
 

Mehr von dcubeio

Mehr von dcubeio (20)

AWS Summit Tokyo 2019登壇資料「DevOpsの劇的改善!古いアーキテクチャから王道のマネージドサービスを活用しフルリプレイス! 」
AWS Summit Tokyo 2019登壇資料「DevOpsの劇的改善!古いアーキテクチャから王道のマネージドサービスを活用しフルリプレイス! 」AWS Summit Tokyo 2019登壇資料「DevOpsの劇的改善!古いアーキテクチャから王道のマネージドサービスを活用しフルリプレイス! 」
AWS Summit Tokyo 2019登壇資料「DevOpsの劇的改善!古いアーキテクチャから王道のマネージドサービスを活用しフルリプレイス! 」
 
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
 
ビットコインとブロックチェーンを初めからていねいに(超基礎編)
ビットコインとブロックチェーンを初めからていねいに(超基礎編)ビットコインとブロックチェーンを初めからていねいに(超基礎編)
ビットコインとブロックチェーンを初めからていねいに(超基礎編)
 
20171206 d3 health_tech発表資料
20171206 d3 health_tech発表資料20171206 d3 health_tech発表資料
20171206 d3 health_tech発表資料
 
Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話Go初心者がGoでコマンドラインツールの作成に挑戦した話
Go初心者がGoでコマンドラインツールの作成に挑戦した話
 
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
初めての Raspberry pi 〜プラレールをunityの世界の中で走らせよう〜 (1)
 
BizReach x Marketo連携
BizReach x Marketo連携BizReach x Marketo連携
BizReach x Marketo連携
 
Kinesis Firehoseを使ってみた
Kinesis Firehoseを使ってみたKinesis Firehoseを使ってみた
Kinesis Firehoseを使ってみた
 
Apiドキュメンテーションツールを使いこなす【api blueprint編】
Apiドキュメンテーションツールを使いこなす【api blueprint編】Apiドキュメンテーションツールを使いこなす【api blueprint編】
Apiドキュメンテーションツールを使いこなす【api blueprint編】
 
春の脆弱性祭り 2017/06/13
春の脆弱性祭り 2017/06/13春の脆弱性祭り 2017/06/13
春の脆弱性祭り 2017/06/13
 
DynamoDBを導入した話
DynamoDBを導入した話DynamoDBを導入した話
DynamoDBを導入した話
 
Play2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだことPlay2 scalaを2年やって学んだこと
Play2 scalaを2年やって学んだこと
 
すごーい!APIドキュメントを更新するだけでAPIが自動テストできちゃう!たのしー!
すごーい!APIドキュメントを更新するだけでAPIが自動テストできちゃう!たのしー! すごーい!APIドキュメントを更新するだけでAPIが自動テストできちゃう!たのしー!
すごーい!APIドキュメントを更新するだけでAPIが自動テストできちゃう!たのしー!
 
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
 
Bitcoin x Slack でマイクロペイメントを実現! 〜生活の必要上割り勘botを作るまで〜
Bitcoin x Slack でマイクロペイメントを実現! 〜生活の必要上割り勘botを作るまで〜Bitcoin x Slack でマイクロペイメントを実現! 〜生活の必要上割り勘botを作るまで〜
Bitcoin x Slack でマイクロペイメントを実現! 〜生活の必要上割り勘botを作るまで〜
 
【freee】プロダクトマネージャーの仕事と魅力
【freee】プロダクトマネージャーの仕事と魅力【freee】プロダクトマネージャーの仕事と魅力
【freee】プロダクトマネージャーの仕事と魅力
 
【ビズリーチ】プロダクトマネージャーの仕事と魅力
【ビズリーチ】プロダクトマネージャーの仕事と魅力【ビズリーチ】プロダクトマネージャーの仕事と魅力
【ビズリーチ】プロダクトマネージャーの仕事と魅力
 
Python × Herokuで作る 雑談slack bot
Python × Herokuで作る 雑談slack botPython × Herokuで作る 雑談slack bot
Python × Herokuで作る 雑談slack bot
 
HR Tech x 機械学習 導入事例紹介
HR Tech x 機械学習 導入事例紹介HR Tech x 機械学習 導入事例紹介
HR Tech x 機械学習 導入事例紹介
 
Scalaマクロ入門 bizr20170217
Scalaマクロ入門 bizr20170217 Scalaマクロ入門 bizr20170217
Scalaマクロ入門 bizr20170217
 

React Native GUIDE

  • 3. ビズリーチ・ キャンパス 学⽣、OB/OG 向けサイト • Java8+Spring Boot (Thymeleaf) • ES2015+KnockoutJS 社内管理者向けサイト • Java8+Spring Boot • ES2015+React(+Redux) アプリ • Java8+Spring Boot • Swift
  • 5. React とは 1/3 https://facebook.github.io/react/ Facebook 製 • UI 構築⽤の JavaScript ライブラリ • Declarative(宣⾔的) – アプリの状態に応じたインタラクティブ な UI を簡単に構築できる – コードもわかりやすい • Component-Based – いわゆるコンポーネント(部品)指向 – ⾃分⾃⾝の状態も管理する • Learn Once,Write Anywhere – これだけ覚えればサーバサイドもスマホ アプリも OK
  • 6. React とは 2/3 https://speakerdeck.com/katamu ki/es2015-react-dot-jswoxue-bu 弊社のおっさんが学んだ話(宣伝) • コンポーネントを組み合わせて構築す るコンポーネント指向の View ライブ ラリ • Facebook、インスタ、Yahoo!、 Airbnb などでも使われている • VirtualDOMを⽤いた画⾯の差分描画を ⾏い⾼速な画⾯表⽰を提供する
  • 7. React とは 3/3 https://facebook.github.io/react/t utorial/tutorial.html • Tutorial おすすめ • ポイント – ES2015 – React.Component – this.prop – this.state – componentXXXMount • ES2015 は以下ざっと読んでおくのが おすすめ – http://postd.cc/es6-cheatsheet/ – 「...」とか検索難易度⾼すぎる
  • 9. React Native とは 1/3 https://facebook.github.io/react- native/ Facebook 製 • ネイティブアプリを JavaScript と React を使⽤して構築できる • ちゃんとサクサク動く本当のスマホア プリが作れる • (アプリなのに)ホットリローディン グでさくさく開発できる • Native コードも使える
  • 10. React Native とは 2/3 https://facebook.github.io/react- native/docs/getting- started.html#content アプリ⽤のコンポネントを確認して おくと効率が良い • こちらも Getting started から Tutorial がおすすめ
  • 11. React Native とは 3/3 http://www.slideshare.net/TadeuZagallo/a-tour- of-react-native?qid=ddc291a4-7988-46dc- b086-9cf3c92a7235&v=&b=&from_search=4 メリットとか • 今後ますますアプリの需要は⾼まって いく • Android と iPhone で 70% 〜 90% コードを共有可能 • ネイティブの勉強をゴリッとやらない で良い
  • 14. React Native の裏側を覗く https://facebook.github.io/react- native/docs/getting- started.html#content Getting Started • ⾊々インストール – node – watchman – react-native-cli – … • 初期化 • 起動 react-native init AwesomeProject react-native run-ios
  • 16. React Native の裏側を覗く view `which react-native`
  • 17. React Native の裏側を覗く switch (commands[0]) { case 'init': if (!commands[1]) { console.error( 'Usage: react-native init <ProjectName> [--verbose]' ); process.exit(1); } else { init(commands[1], argv.verbose, argv.version); } break; default: ...
  • 18. React Native の裏側を覗く function init(name, verbose, rnPackage) { validatePackageName(name); if (fs.existsSync(name)) { createAfterConfirmation(name, verbose, rnPackage); } else { createProject(name, verbose, rnPackage); } }
  • 19. React Native の裏側を覗く function createProject(name, verbose, rnPackage) { var root = path.resolve(name); var projectName = path.basename(root); console.log( 'This will walk you through creating a new React Native project in', root ); if (!fs.existsSync(root)) { fs.mkdirSync(root); } ・・・
  • 20. React Native の裏側を覗く ・・・ var packageJson = { name: projectName, version: '0.0.1', private: true, scripts: { start: 'node node_modules/react-native/local-cli/cli.js start' } }; fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson)); process.chdir(root); console.log('Installing react-native package from npm...'); ・・・
  • 21. React Native の裏側を覗く ・・・ if (verbose) { runVerbose(root, projectName, rnPackage); } else { run(root, projectName, rnPackage); } }
  • 22. React Native の裏側を覗く function run(root, projectName, rnPackage) { exec('npm install --save --save-exact ' + getInstallPackage(rnPackage), function(e, stdout, stderr) { if (e) { console.log(stdout); console.error(stderr); console.error('`npm install --save --save-exact react-native` failed'); process.exit(1); } checkNodeVersion(); var cli = require(CLI_MODULE_PATH()); cli.init(root, projectName); }); }
  • 23. React Native の裏側を覗く view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/cli.js
  • 24. React Native の裏側を覗く /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ 'use strict'; require('./packager/babelRegisterOnly')([ /private-cli¥/src/ ]); module.exports = require('./local-cli/cli.js');
  • 25. React Native の裏側を覗く view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/cli.js
  • 26. React Native の裏側を覗く ・・・ var cliEntry = require('./cliEntry'); if (require.main === module) { cliEntry.run(); } module.exports = cliEntry;
  • 28. React Native の裏側を覗く view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/cliEntry.js
  • 29. React Native の裏側を覗く ・・・ const init = require('./init/init'); ・・・ module.exports = { run: run, init: init, };
  • 30. React Native の裏側を覗く これ! function run(root, projectName, rnPackage) { exec('npm install --save --save-exact ' + getInstallPackage(rnPackage), function(e, stdout, stderr) { if (e) { console.log(stdout); console.error(stderr); console.error('`npm install --save --save-exact react-native` failed'); process.exit(1); } checkNodeVersion(); var cli = require(CLI_MODULE_PATH()); cli.init(root, projectName); }); }
  • 31. React Native の裏側を覗く view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/init/init.js
  • 32. React Native の裏側を覗く /** * Creates the template for a React Native project given the provided * parameters: * @param projectDir Templates will be copied here. * @param argsOrName Project name or full list of custom arguments * for the generator. */ function init(projectDir, argsOrName) { console.log('Setting up new React Native app in ' + projectDir); const args = Array.isArray(argsOrName) ? argsOrName // argsOrName was e.g. ['AwesomeApp', '--verbose'] : [argsOrName].concat(process.argv.slice(4)); // argsOrName was e.g. 'AwesomeApp’ ・・・続く
  • 33. React Native の裏側を覗く ・・・続き // args array is e.g. ['AwesomeApp', '--verbose'] if (!args || args.length === 0) { console.error('react-native init requires a project name.'); return; } const newProjectName = args[0]; const options = minimist(args); generateProject(projectDir, newProjectName, options); }
  • 34. React Native の裏側を覗く function generateProject(destinationRoot, newProjectName, options) { ・・・中略 copyProjectTemplateAndReplace( path.resolve('node_modules', 'react-native', 'local-cli', 'templates', 'HelloWorld'), destinationRoot, newProjectName ); ・・・中略 printRunInstructions(destinationRoot, newProjectName); }
  • 35. React Native の裏側を覗く const copyProjectTemplateAndReplace = require('../generator/copyProjectTemplateAndReplace'); ・・・中略 require('../generator/printRunInstructions');
  • 37. 余談(init.js) const yarnVersion = (!options.npm) && yarn.getYarnVersionIfAvailable() && yarn.isGlobalCliUsingYarn(destinationRoot); ・・・中略 if (yarnVersion) { console.log('Adding React...'); execSync(`yarn add react@${reactVersion}`); } else { console.log('Installing React...'); execSync(`npm install react@${reactVersion} --save --save-exact`); }
  • 38. React Native の裏側を覗く view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/generator/copyProjectTemplateAndReplace.js
  • 39. React Native の裏側を覗く 割愛します・・・ [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/templates/HelloWorld から [react-native init したディレクトリ]/[アプリ名] に HelloWorld を [アプリ名] に replace しながら頑張ってコピーしている処理
  • 40. React Native の裏側を覗く $ ls -l total 64 drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 __tests__ -rw-r--r-- 1 ayumi.toukairin 386209875 31 12 8 20:25 _babelrc -rw-r--r-- 1 ayumi.toukairin 386209875 114 12 8 20:25 _buckconfig -rw-r--r-- 1 ayumi.toukairin 386209875 1425 12 8 20:25 _flowconfig -rw-r--r-- 1 ayumi.toukairin 386209875 16 12 8 20:25 _gitattributes -rw-r--r-- 1 ayumi.toukairin 386209875 415 12 8 20:25 _gitignore -rw-r--r-- 1 ayumi.toukairin 386209875 2 12 8 20:25 _watchmanconfig drwxr-xr-x 10 ayumi.toukairin 386209875 340 12 10 19:23 android -rw-r--r-- 1 ayumi.toukairin 386209875 1106 12 8 20:25 index.android.js -rw-r--r-- 1 ayumi.toukairin 386209875 1072 12 8 20:25 index.ios.js drwxr-xr-x 5 ayumi.toukairin 386209875 170 12 10 19:23 ios
  • 41. React Native の裏側を覗く $ ls –l total 24 drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 __tests__ drwxr-xr-x 10 ayumi.toukairin 386209875 340 12 10 19:23 android -rw-r--r-- 1 ayumi.toukairin 386209875 1091 12 10 20:55 index.android.js -rw-r--r-- 1 ayumi.toukairin 386209875 1057 12 10 20:55 index.ios.js drwxr-xr-x 5 ayumi.toukairin 386209875 170 12 10 19:23 ios drwxr-xr-x 569 ayumi.toukairin 386209875 19346 12 10 20:55 node_modules -rw-r--r-- 1 ayumi.toukairin 386209875 421 12 10 20:55 package.json
  • 42. React Native の裏側を覗く $ ls –l ios total 0 drwxr-xr-x 8 ayumi.toukairin 386209875 272 12 10 19:23 [アプリ名] drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 [アプリ名].xcodeproj drwxr-xr-x 4 ayumi.toukairin 386209875 136 12 10 19:23 [アプリ名]Tests
  • 47. React Native の裏側を覗く view `which react-native`
  • 48. React Native の裏側を覗く ・・・ var cli; var cliPath = CLI_MODULE_PATH(); if (fs.existsSync(cliPath)) { cli = require(cliPath); } // minimist api var commands = argv._; if (cli) { cli.run(); } else { ・・・
  • 49. view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/cliEntry.js React Native の裏側を覗く
  • 50. React Native の裏側を覗く function run() { const setupEnvScript = /^win/.test(process.platform) ? 'setup_env.bat' : 'setup_env.sh'; childProcess.execFileSync(path.join(__dirname, setupEnvScript)); const config = getCliConfig(); commands.forEach(cmd => addCommand(cmd, config)); commander.parse(process.argv); ・・・
  • 51. view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/setup_env.sh React Native の裏側を覗く
  • 52. React Native の裏側を覗く # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. # # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. An additional grant # of patent rights can be found in the PATENTS file in the same directory. # 2048 is the max for non root users on Mac ulimit -n 2048
  • 53. React Native の裏側を覗く function run() { const setupEnvScript = /^win/.test(process.platform) ? 'setup_env.bat' : 'setup_env.sh'; childProcess.execFileSync(path.join(__dirname, setupEnvScript)); const config = getCliConfig(); commands.forEach(cmd => addCommand(cmd, config)); commander.parse(process.argv); ・・・続く
  • 54. React Native の裏側を覗く ・・・続き const isValidCommand = commands.find(cmd => cmd.name.split(' ')[0] === process.argv[2]); if (!isValidCommand) { printUnknownCommand(process.argv[2]); return; } if (!commander.args.length) { commander.help(); } }
  • 56. React Native の裏側を覗く function run() { const setupEnvScript = /^win/.test(process.platform) ? 'setup_env.bat' : 'setup_env.sh'; childProcess.execFileSync(path.join(__dirname, setupEnvScript)); const config = getCliConfig(); commands.forEach(cmd => addCommand(cmd, config)); commander.parse(process.argv); ・・・続く ここらしい!
  • 57. React Native の裏側を覗く const commander = require('commander'); ・・・中略 function run() { const setupEnvScript = /^win/.test(process.platform) ? 'setup_env.bat' : 'setup_env.sh'; childProcess.execFileSync(path.join(__dirname, setupEnvScript)); const config = getCliConfig(); commands.forEach(cmd => addCommand(cmd, config)); commander.parse(process.argv); ・・・ https://tj.github.io/commander.js/ ### Command#parse() Parse argv, settings options and invoking commands when defined.
  • 58. React Native の裏側を覗く const addCommand = (command: Command, config: ConfigT) => { const options = command.options || []; const cmd = commander .command(command.name, undefined, { noHelp: !command.description, }) .description(command.description) .action(function runAction() { const passedOptions = this.opts(); const argv: Array<string> = Array.from(arguments).slice(0, -1); Promise.resolve() .then(() => { assertRequiredOptions(options, passedOptions); return command.func(argv, config, passedOptions); }) .catch(handleError); }); ・・・
  • 59. view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/runIOS/runIOS.js React Native の裏側を覗く
  • 60. React Native の裏側を覗く function runIOS(argv, config, args) { process.chdir(args.projectPath); const xcodeProject = findXcodeProject(fs.readdirSync('.')); if (!xcodeProject) { throw new Error('Could not find Xcode project files in ios folder'); } ・・・中略 if (args.device) { ・・・中略 } else { return runOnSimulator(xcodeProject, args, inferredSchemeName, scheme); } }
  • 61. React Native の裏側を覗く function runOnSimulator(xcodeProject, args, inferredSchemeName, scheme){ return new Promise((resolve) => { try { var simulators = JSON.parse( child_process.execFileSync('xcrun', ['simctl', 'list', '--json', 'devices'], {encoding: 'utf8'}) ); } catch (e) { throw new Error('Could not parse the simulator list output'); } const selectedSimulator = findMatchingSimulator(simulators, args.simulator); if (!selectedSimulator) { throw new Error(`Could not find ${args.simulator} simulator`); } ・・・
  • 62. React Native の裏側を覗く Usage: xcrun [options] <tool name> ... arguments ... Find and execute the named command line tool from the active developer directory. The active developer directory can be set using `xcode-select`, or via the DEVELOPER_DIR environment variable. See the xcrun and xcode-select manualpages for more information.
  • 63. React Native の裏側を覗く ・・・ const simulatorFullName = formattedDeviceName(selectedSimulator); console.log(`Launching ${simulatorFullName}...`); try { child_process.spawnSync('xcrun', ['instruments', '-w', selectedSimulator.udid]); } catch (e) { // instruments always fail with 255 because it expects more arguments, // but we want it to only launch the simulator } resolve(selectedSimulator.udid) }) ・・・
  • 64. React Native の裏側を覗く ・・・ .then((udid) => buildProject(xcodeProject, udid, scheme, args.configuration)) .then((appName) => { if (!appName) { appName = inferredSchemeName; } let appPath = getBuildPath(args.configuration, appName); console.log(`Installing ${appPath}`); child_process.spawnSync('xcrun', ['simctl', 'install', 'booted', appPath], {stdio: 'inherit'}); ・・・
  • 65. React Native の裏側を覗く ・・・ const bundleID = child_process.execFileSync( '/usr/libexec/PlistBuddy', ['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')], {encoding: 'utf8'} ).trim(); console.log(`Launching ${bundleID}`); child_process.spawnSync('xcrun', ['simctl', 'launch', 'booted', bundleID], {stdio: 'inherit'}); }) }
  • 66. view [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/packager/react-native-xcode.sh React Native の裏側を覗く
  • 67. React Native の裏側を覗く #!/bin/bash # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. # ・・・中略 case "$CONFIGURATION" in Debug) # Speed up build times by skipping the creation of the offline package for debug # builds on the simulator since the packager is supposed to be running anyways. if [[ "$PLATFORM_NAME" == *simulator ]]; then echo "Skipping bundling for Simulator platform" exit 0; fi ・・・
  • 69. xcodebuild -project [アプリ名].xcodeproj -configuration Debug -scheme [アプリ 名] -destination id=[udid] -derivedDataPath build React Native の裏側を覗く
  • 70. vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/React/React.xcodeproj/project.pbxproj React Native の裏側を覗く
  • 71. React Native の裏側を覗く #!/bin/sh if [ -z "${RCT_NO_LAUNCH_PACKAGER+xxx}" ] ; then if nc -w 5 -z localhost 8081 ; then if ! curl -s "http://localhost:8081/status" | grep -q "packager- status:running" ; then echo "Port 8081 already in use, packager is either not running or not running correctly" exit 2 fi else open "$SRCROOT/../packager/launchPackager.command" || echo "Can't start packager automatically" fi fi
  • 72. vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/packager/launchPackager.command React Native の裏側を覗く
  • 73. React Native の裏側を覗く #!/usr/bin/env bash # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. ・・・中略 # Set terminal title echo -en "¥033]0;React Packager¥a" clear THIS_DIR=$(dirname "$0") pushd "$THIS_DIR" source ./packager.sh popd echo "Process terminated. Press <enter> to close the window" read
  • 74. vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/packager/packager.sh React Native の裏側を覗く
  • 75. React Native の裏側を覗く #!/usr/bin/env bash # Copyright (c) 2015-present, Facebook, Inc. # All rights reserved. # # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. An additional grant # of patent rights can be found in the PATENTS file in the same directory. THIS_DIR=$(dirname "$0") node "$THIS_DIR/../local-cli/cli.js" start "$@"
  • 76. vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/server/server.js React Native の裏側を覗く
  • 77. React Native の裏側を覗く /** * Starts the React Native Packager Server. */ function server(argv, config, args) { ・・・中略 console.log(formatBanner( 'Running packager on port ' + args.port + '.¥n¥n' + 'Keep this packager running while developing on any JS projects. ' + 'Feel free to close this tab and run your own packager instance if you ' + 'prefer.¥n¥n' + 'https://github.com/facebook/react-native', { marginLeft: 1, marginRight: 1, paddingBottom: 1, }) ); ・・・中略 runServer(args, config, () => console.log('¥nReact packager ready.¥n')); }
  • 78. vim [react-native init したディレクトリ]/[アプリ名]/node_modules/react- native/local-cli/server/runServer.js React Native の裏側を覗く
  • 83. まとめ • React の知識を覚えるとスマホアプリが作れる、ということでそのメリットは ⼤きい • といいつつも、ハマった時のことを考えると node とアプリ構築(xcode)の 知識はある程度有ったほうが良さそう • 割と⾟かった、でも勉強になった – Simulator ⽴ち上げるまでのコードは⼤体把握できたので、ある程度トラブルシュー ティングもできるようになれば良いな・・・ • いつか続きも読みたいな