UNPKG

@expo/cli

Version:
281 lines (280 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { loadMetroConfigAsync: ()=>loadMetroConfigAsync, instantiateMetroAsync: ()=>instantiateMetroAsync, isWatchEnabled: ()=>isWatchEnabled }); function _config() { const data = require("@expo/config"); _config = function() { return data; }; return data; } function _metroConfig() { const data = require("@expo/metro-config"); _metroConfig = function() { return data; }; return data; } function _chalk() { const data = /*#__PURE__*/ _interopRequireDefault(require("chalk")); _chalk = function() { return data; }; return data; } function _metroConfig1() { const data = require("metro-config"); _metroConfig1 = function() { return data; }; return data; } function _metroCore() { const data = require("metro-core"); _metroCore = function() { return data; }; return data; } function _nodeUtil() { const data = /*#__PURE__*/ _interopRequireDefault(require("node:util")); _nodeUtil = function() { return data; }; return data; } function _semver() { const data = /*#__PURE__*/ _interopRequireDefault(require("semver")); _semver = function() { return data; }; return data; } function _url() { const data = require("url"); _url = function() { return data; }; return data; } const _devToolsPluginWebsocketEndpoint = require("./DevToolsPluginWebsocketEndpoint"); const _metroTerminalReporter = require("./MetroTerminalReporter"); const _attachAtlas = require("./debugging/attachAtlas"); const _createDebugMiddleware = require("./debugging/createDebugMiddleware"); const _runServerFork = require("./runServer-fork"); const _withMetroMultiPlatform = require("./withMetroMultiPlatform"); const _log = require("../../../log"); const _getMetroProperties = require("../../../utils/analytics/getMetroProperties"); const _metroDebuggerMiddleware = require("../../../utils/analytics/metroDebuggerMiddleware"); const _env = require("../../../utils/env"); const _telemetry = require("../../../utils/telemetry"); const _corsMiddleware = require("../middleware/CorsMiddleware"); const _manifestMiddleware = require("../middleware/ManifestMiddleware"); const _createJsInspectorMiddleware = require("../middleware/inspector/createJsInspectorMiddleware"); const _mutations = require("../middleware/mutations"); const _suppressErrorMiddleware = require("../middleware/suppressErrorMiddleware"); const _platformBundlers = require("../platformBundlers"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function gteSdkVersion(exp, sdkVersion) { if (!exp.sdkVersion) { return false; } if (exp.sdkVersion === "UNVERSIONED") { return true; } try { return _semver().default.gte(exp.sdkVersion, sdkVersion); } catch { throw new Error(`${exp.sdkVersion} is not a valid version. Must be in the form of x.y.z`); } } // Wrap terminal and polyfill console.log so we can log during bundling without breaking the indicator. class LogRespectingTerminal extends _metroCore().Terminal { constructor(stream){ super(stream); const sendLog = (...args)=>{ // @ts-expect-error this._logLines.push(// format args like console.log _nodeUtil().default.format(...args)); // @ts-expect-error this._scheduleUpdate(); // Flush the logs to the terminal immediately so logs at the end of the process are not lost. this.flush(); }; console.log = sendLog; console.info = sendLog; } } // Share one instance of Terminal for all instances of Metro. const terminal = new LogRespectingTerminal(process.stdout); async function loadMetroConfigAsync(projectRoot, options, { exp , isExporting , getMetroBundler }) { var ref, ref1, ref2, ref3; let reportEvent; const serverRoot = (0, _manifestMiddleware.getMetroServerRoot)(projectRoot); const terminalReporter = new _metroTerminalReporter.MetroTerminalReporter(serverRoot, terminal); const hasConfig = await (0, _metroConfig1().resolveConfig)(options.config, projectRoot); let config = { ...await (0, _metroConfig1().loadConfig)({ cwd: projectRoot, projectRoot, ...options }, // If the project does not have a metro.config.js, then we use the default config. hasConfig.isEmpty ? (0, _metroConfig().getDefaultConfig)(projectRoot) : undefined), reporter: { update (event) { terminalReporter.update(event); if (reportEvent) { reportEvent(event); } } } }; if (// Requires SDK 50 for expo-assets hashAssetPlugin change. !exp.sdkVersion || gteSdkVersion(exp, "50.0.0")) { if (isExporting) { var ref4; var ref5; // This token will be used in the asset plugin to ensure the path is correct for writing locally. // @ts-expect-error: typed as readonly. config.transformer.publicPath = `/assets?export_path=${((ref5 = (ref4 = exp.experiments) == null ? void 0 : ref4.baseUrl) != null ? ref5 : "") + "/assets"}`; } else { // @ts-expect-error: typed as readonly config.transformer.publicPath = "/assets/?unstable_path=."; } } else { var ref6; if (isExporting && ((ref6 = exp.experiments) == null ? void 0 : ref6.baseUrl)) { var ref7; // This token will be used in the asset plugin to ensure the path is correct for writing locally. // @ts-expect-error: typed as readonly. config.transformer.publicPath = (ref7 = exp.experiments) == null ? void 0 : ref7.baseUrl; } } const platformBundlers = (0, _platformBundlers.getPlatformBundlers)(projectRoot, exp); if ((ref = exp.experiments) == null ? void 0 : ref.reactCompiler) { _log.Log.warn(`Experimental React Compiler is enabled.`); } var ref8, ref9, ref10; config = await (0, _withMetroMultiPlatform.withMetroMultiPlatformAsync)(projectRoot, { config, exp, platformBundlers, isTsconfigPathsEnabled: (ref8 = (ref1 = exp.experiments) == null ? void 0 : ref1.tsconfigPaths) != null ? ref8 : true, webOutput: (ref9 = (ref2 = exp.web) == null ? void 0 : ref2.output) != null ? ref9 : "single", isFastResolverEnabled: _env.env.EXPO_USE_FAST_RESOLVER, isExporting, isReactCanaryEnabled: (ref10 = (ref3 = exp.experiments) == null ? void 0 : ref3.reactCanary) != null ? ref10 : false, getMetroBundler }); if (process.env.NODE_ENV !== "test") { (0, _telemetry.logEventAsync)("metro config", (0, _getMetroProperties.getMetroProperties)(projectRoot, exp, config)); } return { config, setEventReporter: (logger)=>reportEvent = logger, reporter: terminalReporter }; } async function instantiateMetroAsync(metroBundler, options, { isExporting , exp =(0, _config().getConfig)(metroBundler.projectRoot, { skipSDKVersionRequirement: true }).exp }) { const projectRoot = metroBundler.projectRoot; const { config: metroConfig , setEventReporter } = await loadMetroConfigAsync(projectRoot, options, { exp, isExporting, getMetroBundler () { return metro.getBundler().getBundler(); } }); const { createDevServerMiddleware , securityHeadersMiddleware } = require("@react-native-community/cli-server-api"); const { middleware , messageSocketEndpoint , eventsSocketEndpoint , websocketEndpoints } = createDevServerMiddleware({ port: metroConfig.server.port, watchFolders: metroConfig.watchFolders }); let debugWebsocketEndpoints = {}; if (!isExporting) { // The `securityHeadersMiddleware` does not support cross-origin requests, we replace with the enhanced version. (0, _mutations.replaceMiddlewareWith)(middleware, securityHeadersMiddleware, (0, _corsMiddleware.createCorsMiddleware)(exp)); (0, _mutations.prependMiddleware)(middleware, _suppressErrorMiddleware.suppressRemoteDebuggingErrorMiddleware); // TODO: We can probably drop this now. const customEnhanceMiddleware = metroConfig.server.enhanceMiddleware; // @ts-expect-error: can't mutate readonly config metroConfig.server.enhanceMiddleware = (metroMiddleware, server)=>{ if (customEnhanceMiddleware) { metroMiddleware = customEnhanceMiddleware(metroMiddleware, server); } return middleware.use(metroMiddleware); }; middleware.use((0, _metroDebuggerMiddleware.createDebuggerTelemetryMiddleware)(projectRoot, exp)); // Initialize all React Native debug features const { debugMiddleware , ...options1 } = (0, _createDebugMiddleware.createDebugMiddleware)(metroBundler); debugWebsocketEndpoints = options1.debugWebsocketEndpoints; (0, _mutations.prependMiddleware)(middleware, debugMiddleware); middleware.use("/_expo/debugger", (0, _createJsInspectorMiddleware.createJsInspectorMiddleware)()); } // Attach Expo Atlas if enabled const atlas = await (0, _attachAtlas.attachAtlasAsync)({ isExporting, exp, projectRoot, middleware, metroConfig, // NOTE(cedric): reset the Atlas file once, and reuse it for static exports resetAtlasFile: isExporting }); const { server , metro } = await (0, _runServerFork.runServer)(metroBundler, metroConfig, { // @ts-expect-error: Inconsistent `websocketEndpoints` type between metro and @react-native-community/cli-server-api websocketEndpoints: { ...websocketEndpoints, ...debugWebsocketEndpoints, ...(0, _devToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)() }, watch: !isExporting && isWatchEnabled() }, { mockServer: isExporting }); // If Atlas is enabled, and can register to Metro, attach it to listen for changes atlas == null ? void 0 : atlas.registerMetro(metro); (0, _mutations.prependMiddleware)(middleware, (req, res, next)=>{ // If the URL is a Metro asset request, then we need to skip all other middleware to prevent // the community CLI's serve-static from hosting `/assets/index.html` in place of all assets if it exists. // /assets/?unstable_path=. if (req.url) { const url = new (_url()).URL(req.url, "http://localhost:8000"); if (url.pathname.match(/^\/assets\/?/) && url.searchParams.get("unstable_path") != null) { return metro.processRequest(req, res, next); } } return next(); }); setEventReporter(eventsSocketEndpoint.reportEvent); return { metro, server, middleware, messageSocket: messageSocketEndpoint }; } function isWatchEnabled() { if (_env.env.CI) { _log.Log.log((0, _chalk().default)`Metro is running in CI mode, reloads are disabled. Remove {bold CI=true} to enable watch mode.`); } return !_env.env.CI; } //# sourceMappingURL=instantiateMetro.js.map