UNPKG

@expo/cli

Version:
255 lines (254 loc) 10.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "DevServerManager", { enumerable: true, get: function() { return DevServerManager; } }); function _config() { const data = require("@expo/config"); _config = function() { return data; }; return data; } function _assert() { const data = /*#__PURE__*/ _interop_require_default(require("assert")); _assert = function() { return data; }; return data; } function _chalk() { const data = /*#__PURE__*/ _interop_require_default(require("chalk")); _chalk = function() { return data; }; return data; } const _DevToolsPluginManager = /*#__PURE__*/ _interop_require_default(require("./DevToolsPluginManager")); const _platformBundlers = require("./platformBundlers"); const _log = require("../../log"); const _FileNotifier = require("../../utils/FileNotifier"); const _env = require("../../utils/env"); const _TypeScriptProjectPrerequisite = require("../doctor/typescript/TypeScriptProjectPrerequisite"); const _commandsTable = require("../interface/commandsTable"); const _adb = /*#__PURE__*/ _interop_require_wildcard(require("../platforms/android/adb")); const _resolveOptions = require("../resolveOptions"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interop_require_wildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = { __proto__: null }; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for(var key in obj){ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const debug = require('debug')('expo:start:server:devServerManager'); const BUNDLERS = { webpack: ()=>require('./webpack/WebpackBundlerDevServer').WebpackBundlerDevServer, metro: ()=>require('./metro/MetroBundlerDevServer').MetroBundlerDevServer }; class DevServerManager { static async startMetroAsync(projectRoot, startOptions) { const devServerManager = new DevServerManager(projectRoot, startOptions); await devServerManager.startAsync([ { type: 'metro', options: startOptions } ]); return devServerManager; } constructor(projectRoot, /** Keep track of the original CLI options for bundlers that are started interactively. */ options){ this.projectRoot = projectRoot; this.options = options; this.devServers = []; this.projectPrerequisites = []; this.notifier = null; if (!options.isExporting) { this.notifier = this.watchBabelConfig(); } this.devtoolsPluginManager = new _DevToolsPluginManager.default(projectRoot); } watchBabelConfig() { const notifier = new _FileNotifier.FileNotifier(this.projectRoot, [ './babel.config.js', './babel.config.json', './.babelrc.json', './.babelrc', './.babelrc.js' ], { additionalWarning: (0, _chalk().default)` You may need to clear the bundler cache with the {bold --clear} flag for your changes to take effect.` }); notifier.startObserving(); return notifier; } /** Lazily load and assert a project-level prerequisite. */ async ensureProjectPrerequisiteAsync(PrerequisiteClass) { let prerequisite = this.projectPrerequisites.find((prerequisite)=>prerequisite instanceof PrerequisiteClass); if (!prerequisite) { prerequisite = new PrerequisiteClass(this.projectRoot); this.projectPrerequisites.push(prerequisite); } return await prerequisite.assertAsync(); } /** * Sends a message over web sockets to all connected devices, * does nothing when the dev server is not running. * * @param method name of the command. In RN projects `reload`, and `devMenu` are available. In Expo Go, `sendDevCommand` is available. * @param params extra event info to send over the socket. */ broadcastMessage(method, params) { this.devServers.forEach((server)=>{ server.broadcastMessage(method, params); }); } /** Get the port for the dev server (either Webpack or Metro) that is hosting code for React Native runtimes. */ getNativeDevServerPort() { var _server_getInstance; const server = this.devServers.find((server)=>server.isTargetingNative()); return (server == null ? void 0 : (_server_getInstance = server.getInstance()) == null ? void 0 : _server_getInstance.location.port) ?? null; } /** Get the first server that targets web. */ getWebDevServer() { const server = this.devServers.find((server)=>server.isTargetingWeb()); return server ?? null; } getDefaultDevServer() { // Return the first native dev server otherwise return the first dev server. const server = this.devServers.find((server)=>server.isTargetingNative()); const defaultServer = server ?? this.devServers[0]; (0, _assert().default)(defaultServer, 'No dev servers are running'); return defaultServer; } async ensureWebDevServerRunningAsync() { const [server] = this.devServers.filter((server)=>server.isTargetingWeb()); if (server) { return; } const { exp } = (0, _config().getConfig)(this.projectRoot, { skipPlugins: true, skipSDKVersionRequirement: true }); const bundler = (0, _platformBundlers.getPlatformBundlers)(this.projectRoot, exp).web; debug(`Starting ${bundler} dev server for web`); return this.startAsync([ { type: bundler, options: this.options } ]); } /** Switch between Expo Go and Expo Dev Clients. */ async toggleRuntimeMode(isUsingDevClient = !this.options.devClient) { const nextMode = isUsingDevClient ? '--dev-client' : '--go'; _log.Log.log((0, _commandsTable.printItem)((0, _chalk().default)`Switching to {bold ${nextMode}}`)); const nextScheme = await (0, _resolveOptions.resolveSchemeAsync)(this.projectRoot, { devClient: isUsingDevClient }); this.options.location.scheme = nextScheme; this.options.devClient = isUsingDevClient; for (const devServer of this.devServers){ devServer.isDevClient = isUsingDevClient; const urlCreator = devServer.getUrlCreator(); urlCreator.defaults ??= {}; urlCreator.defaults.scheme = nextScheme; } debug(`New runtime options (runtime: ${nextMode}):`, this.options); return true; } /** Start all dev servers. */ async startAsync(startOptions) { const { exp } = (0, _config().getConfig)(this.projectRoot, { skipSDKVersionRequirement: true }); const platformBundlers = (0, _platformBundlers.getPlatformBundlers)(this.projectRoot, exp); // Start all dev servers... for (const { type, options } of startOptions){ const BundlerDevServerClass = await BUNDLERS[type](); const server = new BundlerDevServerClass(this.projectRoot, platformBundlers, { devToolsPluginManager: this.devtoolsPluginManager, isDevClient: !!(options == null ? void 0 : options.devClient) }); await server.startAsync(options ?? this.options); this.devServers.push(server); } return exp; } async bootstrapTypeScriptAsync() { const typescriptPrerequisite = await this.ensureProjectPrerequisiteAsync(_TypeScriptProjectPrerequisite.TypeScriptProjectPrerequisite); if (_env.env.EXPO_NO_TYPESCRIPT_SETUP) { return; } // Optionally, wait for the user to add TypeScript during the // development cycle. const server = this.devServers.find((server)=>server.name === 'metro'); if (!server) { return; } // The dev server shouldn't wait for the typescript services if (!typescriptPrerequisite) { server.waitForTypeScriptAsync().then(async (success)=>{ if (success) { server.startTypeScriptServices(); } }); } else { server.startTypeScriptServices(); } } async watchEnvironmentVariables() { var _this_devServers_find; await ((_this_devServers_find = this.devServers.find((server)=>server.name === 'metro')) == null ? void 0 : _this_devServers_find.watchEnvironmentVariables()); } /** Stop all servers including ADB. */ async stopAsync() { var _this_notifier; await Promise.allSettled([ (_this_notifier = this.notifier) == null ? void 0 : _this_notifier.stopObserving(), // Stop ADB _adb.getServer().stopAsync(), // Stop all dev servers ...this.devServers.map((server)=>server.stopAsync().catch((error)=>{ _log.Log.error(`Failed to stop dev server (bundler: ${server.name})`); _log.Log.exception(error); })) ]); } } //# sourceMappingURL=DevServerManager.js.map