@expo/metro-config
Advanced tools
Comparing version 0.19.1 to 0.19.2
@@ -33,4 +33,8 @@ import { MixedOutput, Module, ReadOnlyGraph, Reporter } from 'metro'; | ||
} | ||
export declare function createStableModuleIdFactory(root: string): (path: string, context?: { | ||
platform: string; | ||
environment?: string; | ||
}) => number; | ||
export declare function getDefaultConfig(projectRoot: string, { mode, isCSSEnabled, unstable_beforeAssetSerializationPlugins }?: DefaultConfigOptions): InputConfigT; | ||
export { MetroConfig, INTERNAL_CALLSITES_REGEX }; | ||
export declare const EXPO_DEBUG: boolean; |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EXPO_DEBUG = exports.INTERNAL_CALLSITES_REGEX = exports.getDefaultConfig = void 0; | ||
exports.EXPO_DEBUG = exports.INTERNAL_CALLSITES_REGEX = exports.getDefaultConfig = exports.createStableModuleIdFactory = void 0; | ||
// Copyright 2023-present 650 Industries (Expo). All rights reserved. | ||
@@ -105,29 +105,53 @@ const config_1 = require("@expo/config"); | ||
} | ||
function memoize(fn) { | ||
const cache = new Map(); | ||
return ((...args) => { | ||
const key = JSON.stringify(args); | ||
if (cache.has(key)) { | ||
return cache.get(key); | ||
} | ||
const result = fn(...args); | ||
cache.set(key, result); | ||
return result; | ||
}); | ||
} | ||
function createStableModuleIdFactory(root) { | ||
const fileToIdMap = new Map(); | ||
const getModulePath = (modulePath, scope) => { | ||
// NOTE: Metro allows this but it can lead to confusing errors when dynamic requires cannot be resolved, e.g. `module 456 cannot be found`. | ||
if (modulePath == null) { | ||
return 'MODULE_NOT_FOUND'; | ||
} | ||
else if ((0, sideEffects_1.isVirtualModule)(modulePath)) { | ||
// Virtual modules should be stable. | ||
return modulePath; | ||
} | ||
else if (path_1.default.isAbsolute(modulePath)) { | ||
return path_1.default.relative(root, modulePath) + scope; | ||
} | ||
else { | ||
return modulePath + scope; | ||
} | ||
}; | ||
const memoizedGetModulePath = memoize(getModulePath); | ||
// This is an absolute file path. | ||
return (modulePath) => { | ||
// TODO: We may want a hashed version for production builds in the future. | ||
let id = fileToIdMap.get(modulePath); | ||
if (id == null) { | ||
// NOTE: Metro allows this but it can lead to confusing errors when dynamic requires cannot be resolved, e.g. `module 456 cannot be found`. | ||
if (modulePath == null) { | ||
id = 'MODULE_NOT_FOUND'; | ||
} | ||
else if ((0, sideEffects_1.isVirtualModule)(modulePath)) { | ||
// Virtual modules should be stable. | ||
id = modulePath; | ||
} | ||
else if (path_1.default.isAbsolute(modulePath)) { | ||
id = path_1.default.relative(root, modulePath); | ||
} | ||
else { | ||
id = modulePath; | ||
} | ||
fileToIdMap.set(modulePath, id); | ||
// TODO: We may want a hashed version for production builds in the future. | ||
return (modulePath, context) => { | ||
const env = context?.environment ?? 'client'; | ||
if (env === 'client') { | ||
// Only need scope for server bundles where multiple dimensions could run simultaneously. | ||
// @ts-expect-error: we patch this to support being a string. | ||
return memoizedGetModulePath(modulePath, ''); | ||
} | ||
// Helps find missing parts to the patch. | ||
if (!context?.platform) { | ||
// context = { platform: 'web' }; | ||
throw new Error('createStableModuleIdFactory: `context.platform` is required'); | ||
} | ||
// Only need scope for server bundles where multiple dimensions could run simultaneously. | ||
const scope = env !== 'client' ? `?platform=${context?.platform}&env=${env}` : ''; | ||
// @ts-expect-error: we patch this to support being a string. | ||
return id; | ||
return memoizedGetModulePath(modulePath, scope); | ||
}; | ||
} | ||
exports.createStableModuleIdFactory = createStableModuleIdFactory; | ||
function getDefaultConfig(projectRoot, { mode, isCSSEnabled = true, unstable_beforeAssetSerializationPlugins } = {}) { | ||
@@ -134,0 +158,0 @@ const { getDefaultConfig: getDefaultMetroConfig, mergeConfig } = (0, metro_config_1.importMetroConfig)(projectRoot); |
@@ -53,6 +53,21 @@ "use strict"; | ||
function createDefaultExportCustomSerializer(config, configOptions = {}) { | ||
return async (entryPoint, preModules, graph, options) => { | ||
return async (entryPoint, preModules, graph, inputOptions) => { | ||
const isPossiblyDev = graph.transformOptions.hot; | ||
// TODO: This is a temporary solution until we've converged on using the new serializer everywhere. | ||
const enableDebugId = options.inlineSourceMap !== true && !isPossiblyDev; | ||
const enableDebugId = inputOptions.inlineSourceMap !== true && !isPossiblyDev; | ||
const context = { | ||
platform: graph.transformOptions?.platform, | ||
environment: graph.transformOptions?.customTransformOptions?.environment ?? 'client', | ||
}; | ||
const options = { | ||
...inputOptions, | ||
createModuleId: (moduleId, ...props) => { | ||
if (props.length > 0) { | ||
return inputOptions.createModuleId(moduleId, ...props); | ||
} | ||
return inputOptions.createModuleId(moduleId, | ||
// @ts-expect-error: context is added by Expo and not part of the upstream Metro implementation. | ||
context); | ||
}, | ||
}; | ||
let debugId; | ||
@@ -155,5 +170,19 @@ const loadDebugId = () => { | ||
const defaultSerializer = fallbackSerializer ?? createDefaultExportCustomSerializer(config, configOptions); | ||
return async (...props) => { | ||
const [, , , options] = props; | ||
const customSerializerOptions = options.serializerOptions; | ||
return async (entryPoint, preModules, graph, inputOptions) => { | ||
const context = { | ||
platform: graph.transformOptions?.platform, | ||
environment: graph.transformOptions?.customTransformOptions?.environment ?? 'client', | ||
}; | ||
const options = { | ||
...inputOptions, | ||
createModuleId: (moduleId, ...props) => { | ||
if (props.length > 0) { | ||
return inputOptions.createModuleId(moduleId, ...props); | ||
} | ||
return inputOptions.createModuleId(moduleId, | ||
// @ts-expect-error: context is added by Expo and not part of the upstream Metro implementation. | ||
context); | ||
}, | ||
}; | ||
const customSerializerOptions = inputOptions.serializerOptions; | ||
// Custom options can only be passed outside of the dev server, meaning | ||
@@ -186,3 +215,3 @@ // we don't need to stringify the results at the end, i.e. this is `npx expo export` or `npx expo export:embed`. | ||
if (serializerOptions?.outputMode !== 'static') { | ||
return defaultSerializer(...props); | ||
return defaultSerializer(entryPoint, preModules, graph, options); | ||
} | ||
@@ -198,3 +227,3 @@ // Mutate the serializer options with the parsed options. | ||
...configOptions, | ||
}, ...props); | ||
}, entryPoint, preModules, graph, options); | ||
if (supportsNonSerialReturn) { | ||
@@ -201,0 +230,0 @@ // @ts-expect-error: this is future proofing for adding assets to the output as well. |
{ | ||
"name": "@expo/metro-config", | ||
"version": "0.19.1", | ||
"version": "0.19.2", | ||
"description": "A Metro config for running React Native projects with the Metro bundler", | ||
@@ -65,3 +65,3 @@ "main": "build/ExpoMetroConfig.js", | ||
}, | ||
"gitHead": "68c2c4f5a536c4eb7db9551188c7f667d9fa53c8" | ||
"gitHead": "2c50bd7f0abaefb6fabcfd6d3935066724990b33" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
463020
6534