From 26dfa9a1d713312cdc2b5b94d6a64d6dd9b6727b Mon Sep 17 00:00:00 2001 From: Jhen-Jie Hong Date: Fri, 15 Feb 2019 15:26:20 +0800 Subject: [PATCH] Support RN ^0.59.0-rc.0 for Debugger and NPM package (#321) * [npm-package] Support inject script for @react-native-commonunity/cli (RN ^0.59.0-rc.0) * Update test * Add test for RN 0.59 * Update delta client for support RN 0.59 * Clear console.log --- app/middlewares/delta/DeltaPatcher.js | 57 ++-- app/middlewares/delta/deltaUrlToBlobUrl.js | 26 +- .../injectDevToolsMiddleware.test.js.snap | 317 ++++++++++++++++++ .../injectDevToolsMiddleware.test.js | 73 ++-- npm-package/src/injectDevToolsMiddleware.js | 68 ++-- npm-package/src/main.js | 31 +- 6 files changed, 477 insertions(+), 95 deletions(-) diff --git a/app/middlewares/delta/DeltaPatcher.js b/app/middlewares/delta/DeltaPatcher.js index deab2428..97413e32 100644 --- a/app/middlewares/delta/DeltaPatcher.js +++ b/app/middlewares/delta/DeltaPatcher.js @@ -54,10 +54,13 @@ export default class DeltaPatcher { * Applies a Delta Bundle to the current bundle. */ applyDelta(deltaBundle) { - const isOld = deltaBundle.id; + // NOTE: Support for RN <= 0.57 + const isLegacy = deltaBundle.id; + this._isLegacy = isLegacy; + // Make sure that the first received delta is a fresh one. if ( - isOld ? !this._initialized && !deltaBundle.reset : !this._initialized && !deltaBundle.base + isLegacy ? !this._initialized && !deltaBundle.reset : !this._initialized && !deltaBundle.base ) { throw new Error('DeltaPatcher should receive a fresh Delta when being initialized'); } @@ -65,7 +68,7 @@ export default class DeltaPatcher { this._initialized = true; // Reset the current delta when we receive a fresh delta. - if (deltaBundle.reset && isOld) { + if (deltaBundle.reset && isLegacy) { this._lastBundle = { pre: new Map(), post: new Map(), @@ -81,42 +84,50 @@ export default class DeltaPatcher { }; } - this._lastNumModifiedFiles = isOld - ? deltaBundle.pre.size + deltaBundle.post.size + deltaBundle.delta.size - : deltaBundle.modules.length; - - if (deltaBundle.deleted) { - this._lastNumModifiedFiles += deltaBundle.deleted.length; - } - - this._lastBundle.id = isOld ? deltaBundle.id : deltaBundle.revisionId; + if (isLegacy) { + this._lastNumModifiedFiles = + deltaBundle.pre.size + deltaBundle.post.size + deltaBundle.delta.size; - if (this._lastNumModifiedFiles > 0) { - this._lastModifiedDate = new Date(); - } + this._lastBundle.id = deltaBundle.id; - if (isOld) { this._patchMap(this._lastBundle.pre, deltaBundle.pre); this._patchMap(this._lastBundle.post, deltaBundle.post); this._patchMap(this._lastBundle.modules, deltaBundle.delta); - - this._lastBundle.id = deltaBundle.id; } else { - this._patchMap(this._lastBundle.modules, deltaBundle.modules); + // TODO T37123645 The former case is deprecated, but necessary in order to + // support older versions of the Metro bundler. + const modules = deltaBundle.modules + ? deltaBundle.modules + : deltaBundle.added.concat(deltaBundle.modified); + this._lastNumModifiedFiles = modules.length; + + if (deltaBundle.deleted) { + this._lastNumModifiedFiles += deltaBundle.deleted.length; + } + + this._lastBundle.id = deltaBundle.revisionId; + + this._patchMap(this._lastBundle.modules, modules); if (deltaBundle.deleted) { for (const id of deltaBundle.deleted) { this._lastBundle.modules.delete(id); } } + } - this._lastBundle.id = deltaBundle.revisionId; + if (this._lastNumModifiedFiles > 0) { + this._lastModifiedDate = new Date(); } return this; } - getLastBundleId() { + isLegacy() { + return this._isLegacy; + } + + getLastRevisionId() { return this._lastBundle.id; } @@ -134,8 +145,8 @@ export default class DeltaPatcher { return this._lastModifiedDate; } - getAllModules(isOld) { - return isOld + getAllModules(isLegacy) { + return isLegacy ? [].concat( Array.from(this._lastBundle.pre.values()), Array.from(this._lastBundle.modules.values()), diff --git a/app/middlewares/delta/deltaUrlToBlobUrl.js b/app/middlewares/delta/deltaUrlToBlobUrl.js index 7eaa17f1..cb5ac7a4 100644 --- a/app/middlewares/delta/deltaUrlToBlobUrl.js +++ b/app/middlewares/delta/deltaUrlToBlobUrl.js @@ -16,19 +16,25 @@ const cachedBundleUrls = new Map(); export default async function deltaUrlToBlobUrl(deltaUrl) { const client = DeltaPatcher.get(deltaUrl); - const lastBundleId = client.getLastBundleId(); - - const deltaBundleId = lastBundleId - ? `${deltaUrl.indexOf('?') === -1 ? '?' : '&'}deltaBundleId=${lastBundleId}` - : ''; + const isLegacy = client.isLegacy(); + let query; + if (isLegacy) { + const lastBundleId = client.getLastRevisionId(); + query = lastBundleId + ? `${deltaUrl.indexOf('?') === -1 ? '?' : '&'}deltaBundleId=${lastBundleId}` + : ''; + } else { + const lastRevisionId = client.getLastRevisionId(); + query = lastRevisionId + ? `${deltaUrl.indexOf('?') === -1 ? '?' : '&'}revisionId=${lastRevisionId}` + : ''; + } - const data = await fetch(deltaUrl + deltaBundleId); + const data = await fetch(deltaUrl + query); const bundle = await data.json(); - const isOld = bundle.id; - const deltaPatcher = client.applyDelta( - isOld + isLegacy ? { id: bundle.id, pre: new Map(bundle.pre), @@ -54,7 +60,7 @@ export default async function deltaUrlToBlobUrl(deltaUrl) { // To make Source Maps work correctly, we need to add a newline between // modules. - const blobContent = deltaPatcher.getAllModules(isOld).map(module => `${module}\n`); + const blobContent = deltaPatcher.getAllModules(isLegacy).map(module => `${module}\n`); // Build the blob with the whole JS bundle. const blob = new Blob(blobContent, { diff --git a/npm-package/src/__tests__/__snapshots__/injectDevToolsMiddleware.test.js.snap b/npm-package/src/__tests__/__snapshots__/injectDevToolsMiddleware.test.js.snap index 204b0ed9..81efe13b 100644 --- a/npm-package/src/__tests__/__snapshots__/injectDevToolsMiddleware.test.js.snap +++ b/npm-package/src/__tests__/__snapshots__/injectDevToolsMiddleware.test.js.snap @@ -1,5 +1,322 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-commonunity/cli (RN ^0.59.0-rc.0) 1`] = ` +"'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = getDevToolsMiddleware; + +var _launchChrome = _interopRequireDefault(require('../util/launchChrome')); + +var _logger = _interopRequireDefault(require('../../util/logger')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ +function launchChromeDevTools(host, port, args = '') { + const debuggerURL = \`http://\${host}:\${port}/debugger-ui\${args}\`; + + _logger.default.info('Launching Dev Tools...'); + + (0, _launchChrome.default)(debuggerURL); +} + +function launchDevTools({ host, port, watchFolders }, isChromeConnected) { + // Explicit config always wins + const customDebugger = process.env.REACT_DEBUGGER; + + if (customDebugger) { + customDebugger({ + watchFolders, + customDebugger + }); + } else if (!isChromeConnected()) { + // Dev tools are not yet open; we need to open a session + launchChromeDevTools(host, port); + } +} + +function getDevToolsMiddleware(options, isChromeConnected) { + return function devToolsMiddleware(req, res, next) { + if (req.url === '/launch-safari-devtools') { + // TODO: remove \`logger.info\` and dev tools binary + _logger.default.info( + 'We removed support for Safari dev-tools. ' + + 'If you still need this, please let us know.' + ); + } else if (req.url === '/launch-chrome-devtools') { + // TODO: Remove this case in the future + _logger.default.info( + 'The method /launch-chrome-devtools is deprecated. You are ' + + ' probably using an application created with an older CLI with the ' + + ' packager of a newer CLI. Please upgrade your application: ' + + 'https://facebook.github.io/react-native/docs/upgrading.html' + ); + + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else if (req.url === '/launch-js-devtools') { + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else { + next(); + } + }; +} +" +`; + +exports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-commonunity/cli (RN ^0.59.0-rc.0) 2`] = ` +"'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = getDevToolsMiddleware; + +var _launchChrome = _interopRequireDefault(require('../util/launchChrome')); + +var _logger = _interopRequireDefault(require('../../util/logger')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ +/* react-native-debugger-patch start */ +var __opn = require('opn'); +var __fs = require('fs'); +var __path = require('path'); +var __net = require('net'); +var __childProcess = require('child_process'); +var __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME'; +var __port_file = __path.join(process.env[__home_env], '.rndebugger_port'); + +function __connectToRND(rndPath, log, cb) { + var __port; + try { + __port = __fs.readFileSync(__port_file, 'utf-8'); + } catch (e) { + log && console.log( + '\\\\n[RNDebugger] The port file \`$HOME/.rndebugger_port\` not found\\\\n' + + 'Maybe the React Native Debugger (^0.3) is not open?\\\\n' + + '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' + ); + return cb(false); + } + var __c = __net.createConnection({ port: __port }, () => { + let pass = false; + __c.setEncoding('utf-8'); + __c.write(JSON.stringify({ path: rndPath })); + __c.on('data', data => { + pass = data === 'success'; + __c.end(); + }); + const __timeoutId = setTimeout(() => { + log && console.log( + '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n' + ); + __c.end(); + }, 1000); + __c.on('end', () => { + clearTimeout(__timeoutId); + !pass && log && console.log( + '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n' + ); + cb(pass); + }); + + }); +} + +var __rndebuggerIsOpening = false; +function launchChromeDevTools(host, port, args = '', skipRNDebugger) { + var __rnd_path = 'rndebugger://set-debugger-loc?host=localhost&port=' + (host && host.split(':')[1] || '8081') + '&args=' + args; + + if (__rndebuggerIsOpening) return; + __rndebuggerIsOpening = true; + if (process.platform === 'darwin' && !skipRNDebugger) { + var __env = Object.assign({}, process.env); + // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger + delete __env.ELECTRON_RUN_AS_NODE; + __childProcess + .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env }) + .once('close', code => { + if (code > 0) { + __connectToRND(__rnd_path, false, pass => { + if (!pass) { + console.log( + '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' + + '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' + + 'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n' + ); + } + __rndebuggerIsOpening = false; + !pass && launchChromeDevTools(host, port, args, true); + }); + } else { + __rndebuggerIsOpening = false; + } + }) + return; + } else if (!skipRNDebugger) { + __connectToRND(__rnd_path, true, pass => { + __rndebuggerIsOpening = false; + !pass && launchChromeDevTools(host, port, args, true); + }); + return; + } + __rndebuggerIsOpening = false; +/* react-native-debugger-patch end */ + + const debuggerURL = \`http://\${host}:\${port}/debugger-ui\${args}\`; + + _logger.default.info('Launching Dev Tools...'); + + (0, _launchChrome.default)(debuggerURL); +} + +function launchDevTools({ host, port, watchFolders }, isChromeConnected) { + // Explicit config always wins + const customDebugger = process.env.REACT_DEBUGGER; + + if (customDebugger) { + customDebugger({ + watchFolders, + customDebugger + }); + } else if (!isChromeConnected()) { + // Dev tools are not yet open; we need to open a session + launchChromeDevTools(host, port); + } +} + +function getDevToolsMiddleware(options, isChromeConnected) { + return function devToolsMiddleware(req, res, next) { + if (req.url === '/launch-safari-devtools') { + // TODO: remove \`logger.info\` and dev tools binary + _logger.default.info( + 'We removed support for Safari dev-tools. ' + + 'If you still need this, please let us know.' + ); + } else if (req.url === '/launch-chrome-devtools') { + // TODO: Remove this case in the future + _logger.default.info( + 'The method /launch-chrome-devtools is deprecated. You are ' + + ' probably using an application created with an older CLI with the ' + + ' packager of a newer CLI. Please upgrade your application: ' + + 'https://facebook.github.io/react-native/docs/upgrading.html' + ); + + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else if (req.url === '/launch-js-devtools') { + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else { + next(); + } + }; +} +" +`; + +exports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-commonunity/cli (RN ^0.59.0-rc.0) 3`] = ` +"'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = getDevToolsMiddleware; + +var _launchChrome = _interopRequireDefault(require('../util/launchChrome')); + +var _logger = _interopRequireDefault(require('../../util/logger')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; +} + +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ +function launchChromeDevTools(host, port, args = '') { + + const debuggerURL = \`http://\${host}:\${port}/debugger-ui\${args}\`; + + _logger.default.info('Launching Dev Tools...'); + + (0, _launchChrome.default)(debuggerURL); +} + +function launchDevTools({ host, port, watchFolders }, isChromeConnected) { + // Explicit config always wins + const customDebugger = process.env.REACT_DEBUGGER; + + if (customDebugger) { + customDebugger({ + watchFolders, + customDebugger + }); + } else if (!isChromeConnected()) { + // Dev tools are not yet open; we need to open a session + launchChromeDevTools(host, port); + } +} + +function getDevToolsMiddleware(options, isChromeConnected) { + return function devToolsMiddleware(req, res, next) { + if (req.url === '/launch-safari-devtools') { + // TODO: remove \`logger.info\` and dev tools binary + _logger.default.info( + 'We removed support for Safari dev-tools. ' + + 'If you still need this, please let us know.' + ); + } else if (req.url === '/launch-chrome-devtools') { + // TODO: Remove this case in the future + _logger.default.info( + 'The method /launch-chrome-devtools is deprecated. You are ' + + ' probably using an application created with an older CLI with the ' + + ' packager of a newer CLI. Please upgrade your application: ' + + 'https://facebook.github.io/react-native/docs/upgrading.html' + ); + + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else if (req.url === '/launch-js-devtools') { + launchDevTools(options, isChromeConnected); + res.end('OK'); + } else { + next(); + } + }; +} +" +`; + exports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.49 1`] = ` "/** * Copyright (c) 2015-present, Facebook, Inc. diff --git a/npm-package/src/__tests__/injectDevToolsMiddleware.test.js b/npm-package/src/__tests__/injectDevToolsMiddleware.test.js index 2b410198..3d838048 100644 --- a/npm-package/src/__tests__/injectDevToolsMiddleware.test.js +++ b/npm-package/src/__tests__/injectDevToolsMiddleware.test.js @@ -1,18 +1,16 @@ import fs from 'fs-extra'; import path from 'path'; import fetch from 'node-fetch'; -import { - dir as middlewareDir, - path as middlewarePath, - inject, - revert, -} from '../injectDevToolsMiddleware'; +import { inject, revert } from '../injectDevToolsMiddleware'; const getRemoteMiddlewarePath = version => `https://raw.githubusercontent.com/facebook/react-native/${version}-stable/local-cli/server/middleware/getDevToolsMiddleware.js`; const versions = ['0.49', '0.50']; const modulePath = path.join(__dirname, 'tmp'); +const middlewareDir = 'local-cli/server/middleware'; +const middlewarePath = path.join(middlewareDir, 'getDevToolsMiddleware.js'); + describe('Inject to devtoolsMiddleware of React Native packager', () => { afterEach(() => { fs.removeSync(path.join(__dirname, 'tmp')); @@ -20,10 +18,10 @@ describe('Inject to devtoolsMiddleware of React Native packager', () => { versions.forEach(version => { test(`inject / revert in react-native ${version}`, async () => { const code = await fetch(getRemoteMiddlewarePath(version)).then(res => res.text()); - fs.ensureDirSync(path.join(modulePath, middlewareDir)); - fs.outputFileSync(path.join(modulePath, middlewarePath), code); + fs.ensureDirSync(path.join(modulePath, 'react-native', middlewareDir)); + fs.outputFileSync(path.join(modulePath, 'react-native', middlewarePath), code); fs.outputFileSync( - path.join(modulePath, 'package.json'), + path.join(modulePath, 'react-native', 'package.json'), JSON.stringify({ version: `${version}.0`, name: 'react-native', @@ -31,10 +29,14 @@ describe('Inject to devtoolsMiddleware of React Native packager', () => { ); expect(code).toMatchSnapshot(); - inject(modulePath); - expect(fs.readFileSync(path.join(modulePath, middlewarePath), 'utf-8')).toMatchSnapshot(); - revert(modulePath); - expect(fs.readFileSync(path.join(modulePath, middlewarePath), 'utf-8')).toMatchSnapshot(); + inject(modulePath, 'react-native'); + expect( + fs.readFileSync(path.join(modulePath, 'react-native', middlewarePath), 'utf-8') + ).toMatchSnapshot(); + revert(modulePath, 'react-native'); + expect( + fs.readFileSync(path.join(modulePath, 'react-native', middlewarePath), 'utf-8') + ).toMatchSnapshot(); }); }); @@ -42,10 +44,10 @@ describe('Inject to devtoolsMiddleware of React Native packager', () => { const code = await fetch( 'https://raw.githubusercontent.com/ptmt/react-native-macos/merge-0.44.0/local-cli/server/middleware/getDevToolsMiddleware.js' ).then(res => res.text()); - fs.ensureDirSync(path.join(modulePath, middlewareDir)); - fs.outputFileSync(path.join(modulePath, middlewarePath), code); + fs.ensureDirSync(path.join(modulePath, 'react-native-macos', middlewareDir)); + fs.outputFileSync(path.join(modulePath, 'react-native-macos', middlewarePath), code); fs.outputFileSync( - path.join(modulePath, 'package.json'), + path.join(modulePath, 'react-native-macos', 'package.json'), JSON.stringify({ version: '0.8.7', name: 'react-native-macos', @@ -53,9 +55,40 @@ describe('Inject to devtoolsMiddleware of React Native packager', () => { ); expect(code).toMatchSnapshot(); - inject(modulePath); - expect(fs.readFileSync(path.join(modulePath, middlewarePath), 'utf-8')).toMatchSnapshot(); - revert(modulePath); - expect(fs.readFileSync(path.join(modulePath, middlewarePath), 'utf-8')).toMatchSnapshot(); + inject(modulePath, 'react-native-macos'); + expect( + fs.readFileSync(path.join(modulePath, 'react-native-macos', middlewarePath), 'utf-8') + ).toMatchSnapshot(); + revert(modulePath, 'react-native-macos'); + expect( + fs.readFileSync(path.join(modulePath, 'react-native-macos', middlewarePath), 'utf-8') + ).toMatchSnapshot(); + }); + + test('inject / revert in @react-native-commonunity/cli (RN ^0.59.0-rc.0)', async () => { + const mDir = 'build/server/middleware'; + const mPath = path.join(mDir, 'getDevToolsMiddleware.js'); + const code = await fetch( + 'https://unpkg.com/@react-native-community/cli@1.2.2/build/server/middleware/getDevToolsMiddleware.js' + ).then(res => res.text()); + fs.ensureDirSync(path.join(modulePath, '@react-native-community/cli', mDir)); + fs.outputFileSync(path.join(modulePath, '@react-native-community/cli', mPath), code); + fs.outputFileSync( + path.join(modulePath, 'react-native', 'package.json'), + JSON.stringify({ + version: '0.59.0-rc.0', + name: 'react-native', + }) + ); + + expect(code).toMatchSnapshot(); + inject(modulePath, 'react-native'); + expect( + fs.readFileSync(path.join(modulePath, '@react-native-community/cli', mPath), 'utf-8') + ).toMatchSnapshot(); + revert(modulePath, 'react-native'); + expect( + fs.readFileSync(path.join(modulePath, '@react-native-community/cli', mPath), 'utf-8') + ).toMatchSnapshot(); }); }); diff --git a/npm-package/src/injectDevToolsMiddleware.js b/npm-package/src/injectDevToolsMiddleware.js index 5958bda0..d4518fb2 100644 --- a/npm-package/src/injectDevToolsMiddleware.js +++ b/npm-package/src/injectDevToolsMiddleware.js @@ -16,20 +16,49 @@ const keyFunc = 'launchChromeDevTools'; const flags = { 'react-native': { '0.50.0-rc.0': { + target: 'react-native', + dir: 'local-cli/server/middleware', + file: 'getDevToolsMiddleware.js', func: `function ${keyFunc}(port, args = '') {`, replaceFunc: `function ${keyFunc}(port, args = '', skipRNDebugger) {`, funcCall: '(port, args, true)', args: "port + '&args=' + args", }, '0.53.0': { + target: 'react-native', + dir: 'local-cli/server/middleware', + file: 'getDevToolsMiddleware.js', func: `function ${keyFunc}(host, args = '') {`, replaceFunc: `function ${keyFunc}(host, args = '', skipRNDebugger) {`, funcCall: '(host, args, true)', args: "(host && host.split(':')[1] || '8081') + '&args=' + args", }, + '0.59.0-rc.0': { + target: '@react-native-community/cli', + dir: 'build/server/middleware', + file: 'getDevToolsMiddleware.js', + func: `function ${keyFunc}(host, port, args = '') {`, + replaceFunc: `function ${keyFunc}(host, port, args = '', skipRNDebugger) {`, + funcCall: '(host, port, args, true)', + args: "(host && host.split(':')[1] || '8081') + '&args=' + args", + }, }, - // react-native, react-native-macos + 'react-native-macos': { + '0.0.0': { + target: 'react-native-macos', + dir: 'local-cli/server/middleware', + file: 'getDevToolsMiddleware.js', + func: `function ${keyFunc}(port) {`, + replaceFunc: `function ${keyFunc}(port, skipRNDebugger) {`, + funcCall: '(port, true)', + args: 'port', + }, + }, + // react-native default: { + target: 'react-native', + dir: 'local-cli/server/middleware', + file: 'getDevToolsMiddleware.js', func: `function ${keyFunc}(port) {`, replaceFunc: `function ${keyFunc}(port, skipRNDebugger) {`, funcCall: '(port, true)', @@ -37,8 +66,8 @@ const flags = { }, }; -const getModuleInfo = modulePath => { - const pkg = JSON.parse(fs.readFileSync(join(modulePath, 'package.json'))); // eslint-disable-line +const getModuleInfo = (modulePath, moduleName) => { + const pkg = JSON.parse(fs.readFileSync(join(modulePath, moduleName, 'package.json'))); // eslint-disable-line return { version: pkg.version, name: pkg.name }; }; @@ -54,20 +83,20 @@ function getFlag(moduleName, version) { return flag; } -export const dir = 'local-cli/server/middleware'; -export const file = 'getDevToolsMiddleware.js'; -export const path = join(exports.dir, exports.file); - -export const inject = modulePath => { - const filePath = join(modulePath, exports.path); +export const inject = (modulePath, moduleName) => { + const info = getModuleInfo(modulePath, moduleName); + const { + func: funcFlag, + replaceFunc: replaceFuncFlag, + funcCall, + args, + target, + dir, + file, + } = getFlag(info.name, info.version); + const filePath = join(modulePath, target, dir, file); if (!fs.existsSync(filePath)) return false; - const info = getModuleInfo(modulePath); - const { func: funcFlag, replaceFunc: replaceFuncFlag, funcCall, args } = getFlag( - info.name, - info.version - ); - const code = es6Template(template, { startFlag, replaceFuncFlag, @@ -91,13 +120,12 @@ export const inject = modulePath => { return true; }; -export const revert = modulePath => { - const filePath = join(modulePath, exports.path); +export const revert = (modulePath, moduleName) => { + const info = getModuleInfo(modulePath, moduleName); + const { func: funcFlag, target, dir, file } = getFlag(info.name, info.version); + const filePath = join(modulePath, target, dir, file); if (!fs.existsSync(filePath)) return false; - const info = getModuleInfo(modulePath); - const { func: funcFlag } = getFlag(info.name, info.version); - const middlewareCode = fs.readFileSync(filePath, 'utf-8'); const start = middlewareCode.indexOf(startFlag); // already injected ? const end = middlewareCode.indexOf(endFlag) + endFlag.length; diff --git a/npm-package/src/main.js b/npm-package/src/main.js index f7aab081..8da1ad1d 100644 --- a/npm-package/src/main.js +++ b/npm-package/src/main.js @@ -2,13 +2,9 @@ import fs from 'fs'; import cp from 'child_process'; import path from 'path'; import chalk from 'chalk'; -import { - inject as injectMiddleware, - revert as revertMiddleware, - path as middlewarePath, -} from './injectDevToolsMiddleware'; +import { inject as injectMiddleware, revert as revertMiddleware } from './injectDevToolsMiddleware'; -const getModulePath = moduleName => path.join(process.cwd(), 'node_modules', moduleName); +const modulePath = path.join(process.cwd(), 'node_modules'); const log = (pass, msg) => { const prefix = pass ? chalk.green.bgBlack('PASS') : chalk.red.bgBlack('FAIL'); @@ -17,34 +13,25 @@ const log = (pass, msg) => { }; export default (argv, cb) => { - let modulePath; + let moduleName; if (argv.macos) { - modulePath = getModulePath('react-native-macos'); - } else if (argv.desktop) { - // react-native-macos is renamed from react-native-desktop - modulePath = getModulePath('react-native-desktop'); - if (!fs.existsSync(modulePath)) { - modulePath = getModulePath('react-native-macos'); - } + moduleName = 'react-native-macos'; } else { - modulePath = getModulePath('react-native'); + moduleName = 'react-native'; } // Revert injection if (argv.revert) { - const passMiddleware = revertMiddleware(modulePath); + const passMiddleware = revertMiddleware(modulePath, moduleName); const msg = 'Revert injection of React Native Debugger from React Native packager'; - log( - passMiddleware, - msg + (!passMiddleware ? `, the file '${middlewarePath}' not found.` : '.') - ); + log(passMiddleware, msg + (!passMiddleware ? ', the file inject file not found.' : '.')); return cb(passMiddleware); } const inject = () => { - const pass = injectMiddleware(modulePath); + const pass = injectMiddleware(modulePath, moduleName); const msg = 'Replace `open debugger-ui with Chrome` to `open React Native Debugger`'; - log(pass, msg + (pass ? '.' : `, the file '${middlewarePath}' not found.`)); + log(pass, msg + (pass ? '.' : ', the file inject file not found.')); cb(pass); };