add support of RN custom components with figwheel (issue #5)

- new CLI command use-component <name> which save name in .re-natal config for later use in use-figwheel command
- use-figwheel now generates a map of cached 'require' calls
- figwheel-bridge.js shims require function to lookup for components by name falls back to original if nothing found
This commit is contained in:
Artur Girenko 2016-01-04 23:10:13 +01:00
parent cc90e21425
commit 768f191a63
3 changed files with 53 additions and 6 deletions

View File

@ -120,6 +120,7 @@ generateConfig = (name) ->
log 'Creating Re-Natal config' log 'Creating Re-Natal config'
config = config =
name: name name: name
modules: []
writeConfig config writeConfig config
config config
@ -408,17 +409,26 @@ getDeviceUuids = ->
getDeviceList().map (line) -> line.match(/\[(.+)\]/)[1] getDeviceList().map (line) -> line.match(/\[(.+)\]/)[1]
generateRequireModulesCode = (modules) ->
jsCode = "var modules={'react-native': require('react-native')};"
for m in modules
jsCode += "modules['#{m}']=require('#{m}');";
jsCode += '\n'
generateDevScripts = (devHost) -> generateDevScripts = (devHost) ->
try try
projName = readConfig().name config = readConfig()
projName = config.name
projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase() projNameHyph = projName.replace(camelRx, '$1-$2').toLowerCase()
log 'Cleaning...' log 'Cleaning...'
exec 'lein clean' exec 'lein clean'
fs.writeFileSync 'index.ios.js', "require('figwheel-bridge').start('" + projName + "','ios', '" + devHost + "');" moduleMap = generateRequireModulesCode config.modules
fs.writeFileSync 'index.ios.js', "#{moduleMap}require('figwheel-bridge').withModules(modules).start('#{projName}','ios','#{devHost}');"
log 'index.ios.js was regenerated' log 'index.ios.js was regenerated'
fs.writeFileSync 'index.android.js', "require('figwheel-bridge').start('" + projName + "','android', '" + devHost + "');" fs.writeFileSync 'index.android.js', "#{moduleMap}require('figwheel-bridge').withModules(modules).start('#{projName}','android','#{devHost}');"
log 'index.android.js was regenerated' log 'index.android.js was regenerated'
copyDevEnvironmentFiles(projNameHyph, projName, devHost) copyDevEnvironmentFiles(projNameHyph, projName, devHost)
@ -442,6 +452,15 @@ doUpgrade = (config) ->
copyFigwheelBridge(projNameUs) copyFigwheelBridge(projNameUs)
log 'upgraded figwheel-bridge.js' log 'upgraded figwheel-bridge.js'
useComponent = (name) ->
log "Component '#{name}' is now configured for figwheel, please re-run 'use-figwheel' command to take effect"
try
config = readConfig()
config.modules.push name
writeConfig(config)
catch {message}
logErr message
cli._name = 're-natal' cli._name = 're-natal'
cli.version pkgJson.version cli.version pkgJson.version
@ -509,6 +528,11 @@ cli.command 'use-figwheel'
.action (cmd) -> .action (cmd) ->
generateDevScripts(cmd.host) generateDevScripts(cmd.host)
cli.command 'use-component <name>'
.description 'configures a custom component to work with figwheel. name is the value you pass to (js/require) function.'
.action (name) ->
useComponent(name)
cli.on '*', (command) -> cli.on '*', (command) ->
logErr "unknown command #{command[0]}. See re-natal --help for valid commands" logErr "unknown command #{command[0]}. See re-natal --help for valid commands"

View File

@ -5,7 +5,7 @@
[$PROJECT_NAME_HYPHENATED$.handlers] [$PROJECT_NAME_HYPHENATED$.handlers]
[$PROJECT_NAME_HYPHENATED$.subs])) [$PROJECT_NAME_HYPHENATED$.subs]))
(set! js/React (js/require "react-native/Libraries/react-native/react-native.js")) (set! js/React (js/require "react-native"))
(def app-registry (.-AppRegistry js/React)) (def app-registry (.-AppRegistry js/React))
(def text (r/adapt-react-class (.-Text js/React))) (def text (r/adapt-react-class (.-Text js/React)))

View File

@ -23,10 +23,12 @@ var config = {
}) })
}; };
var self;
var scriptQueue = []; var scriptQueue = [];
var server = null; // will be set dynamically var server = null; // will be set dynamically
var fileBasePath = null; // will be set dynamically var fileBasePath = null; // will be set dynamically
var evaluate = eval; // This is needed, direct calls to eval does not work (RN packager???) var evaluate = eval; // This is needed, direct calls to eval does not work (RN packager???)
var externalModules = {};
// evaluates js code ensuring proper ordering // evaluates js code ensuring proper ordering
function customEval(url, javascript, success, error) { function customEval(url, javascript, success, error) {
@ -92,12 +94,25 @@ function importJs(src, success, error) {
} }
function interceptRequire() {
var oldRequire = window.require;
console.info("Shimming require");
window.require = function (id) {
console.info("Requiring: " + id);
if (externalModules[id]) {
return externalModules[id];
}
return oldRequire(id);
};
}
function loadApp(platform, devHost) { function loadApp(platform, devHost) {
server = "http://"+ devHost + ":8081"; server = "http://" + devHost + ":8081";
fileBasePath = config.basePath + platform; fileBasePath = config.basePath + platform;
if (typeof goog === "undefined") { if (typeof goog === "undefined") {
console.log('Loading Closure base.'); console.log('Loading Closure base.');
interceptRequire();
importJs('goog/base.js', function () { importJs('goog/base.js', function () {
shimBaseGoog(); shimBaseGoog();
fakeLocalStorageAndDocument(); fakeLocalStorageAndDocument();
@ -124,6 +139,11 @@ function startApp(appName, platform, devHost) {
} }
} }
function withModules(moduleById) {
externalModules = moduleById;
return self;
}
// Goog fixes // Goog fixes
function shimBaseGoog() { function shimBaseGoog() {
console.info('Shimming goog functions.'); console.info('Shimming goog functions.');
@ -199,6 +219,9 @@ function shimJsLoader() {
}; };
} }
module.exports = { self = {
withModules: withModules,
start: startApp start: startApp
}; };
module.exports = self;