@expo/cli
Version:
365 lines (364 loc) • 14.6 kB
JavaScript
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, {
convertPathToModuleSpecifier: function() {
return convertPathToModuleSpecifier;
},
createBundleOsPath: function() {
return createBundleOsPath;
},
createBundleUrlPath: function() {
return createBundleUrlPath;
},
createBundleUrlPathFromExpoConfig: function() {
return createBundleUrlPathFromExpoConfig;
},
createBundleUrlSearchParams: function() {
return createBundleUrlSearchParams;
},
getAsyncRoutesFromExpoConfig: function() {
return getAsyncRoutesFromExpoConfig;
},
getBaseUrlFromExpoConfig: function() {
return getBaseUrlFromExpoConfig;
},
getMetroDirectBundleOptions: function() {
return getMetroDirectBundleOptions;
},
getMetroDirectBundleOptionsForExpoConfig: function() {
return getMetroDirectBundleOptionsForExpoConfig;
},
getMetroOptionsFromUrl: function() {
return getMetroOptionsFromUrl;
},
isServerEnvironment: function() {
return isServerEnvironment;
},
shouldEnableAsyncImports: function() {
return shouldEnableAsyncImports;
}
});
function _resolvefrom() {
const data = /*#__PURE__*/ _interop_require_default(require("resolve-from"));
_resolvefrom = function() {
return data;
};
return data;
}
const _env = require("../../../utils/env");
const _errors = require("../../../utils/errors");
const _filePath = require("../../../utils/filePath");
const _router = require("../metro/router");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const debug = require('debug')('expo:metro:options');
function isServerEnvironment(environment) {
return environment === 'node' || environment === 'react-server';
}
function shouldEnableAsyncImports(projectRoot) {
if (_env.env.EXPO_NO_METRO_LAZY) {
return false;
}
// `@expo/metro-runtime` includes support for the fetch + eval runtime code required
// to support async imports. If it's not installed, we can't support async imports.
// If it is installed, the user MUST import it somewhere in their project.
// Expo Router automatically pulls this in, so we can check for it.
return _resolvefrom().default.silent(projectRoot, '@expo/metro-runtime/package.json') != null;
}
function withDefaults({ mode = 'development', minify = mode === 'production', preserveEnvVars = mode !== 'development' && _env.env.EXPO_NO_CLIENT_ENV_VARS, lazy, environment, ...props }) {
if (props.bytecode) {
if (props.platform === 'web') {
throw new _errors.CommandError('Cannot use bytecode with the web platform');
}
if (props.engine !== 'hermes') {
throw new _errors.CommandError('Bytecode is only supported with the Hermes engine');
}
}
const optimize = props.optimize ?? (environment !== 'node' && mode === 'production' && _env.env.EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH);
return {
mode,
minify,
preserveEnvVars,
optimize,
usedExports: optimize && _env.env.EXPO_UNSTABLE_TREE_SHAKING,
lazy: !props.isExporting && lazy,
environment: environment === 'client' ? undefined : environment,
...props
};
}
function getBaseUrlFromExpoConfig(exp) {
var _exp_experiments_baseUrl, _exp_experiments;
return ((_exp_experiments = exp.experiments) == null ? void 0 : (_exp_experiments_baseUrl = _exp_experiments.baseUrl) == null ? void 0 : _exp_experiments_baseUrl.trim().replace(/\/+$/, '')) ?? '';
}
function getAsyncRoutesFromExpoConfig(exp, mode, platform) {
var _exp_extra_router, _exp_extra;
let asyncRoutesSetting;
if ((_exp_extra = exp.extra) == null ? void 0 : (_exp_extra_router = _exp_extra.router) == null ? void 0 : _exp_extra_router.asyncRoutes) {
var _exp_extra_router1, _exp_extra1;
const asyncRoutes = (_exp_extra1 = exp.extra) == null ? void 0 : (_exp_extra_router1 = _exp_extra1.router) == null ? void 0 : _exp_extra_router1.asyncRoutes;
if ([
'boolean',
'string'
].includes(typeof asyncRoutes)) {
asyncRoutesSetting = asyncRoutes;
} else if (typeof asyncRoutes === 'object') {
asyncRoutesSetting = asyncRoutes[platform] ?? asyncRoutes.default;
}
}
return [
mode,
true
].includes(asyncRoutesSetting);
}
function getMetroDirectBundleOptionsForExpoConfig(projectRoot, exp, options) {
var _exp_experiments;
return getMetroDirectBundleOptions({
...options,
reactCompiler: !!((_exp_experiments = exp.experiments) == null ? void 0 : _exp_experiments.reactCompiler),
baseUrl: getBaseUrlFromExpoConfig(exp),
routerRoot: (0, _router.getRouterDirectoryModuleIdWithManifest)(projectRoot, exp),
asyncRoutes: getAsyncRoutesFromExpoConfig(exp, options.mode, options.platform)
});
}
function getMetroDirectBundleOptions(options) {
const { mainModuleName, platform, mode, minify, environment, serializerOutput, serializerIncludeMaps, bytecode, lazy, engine, preserveEnvVars, asyncRoutes, baseUrl, routerRoot, isExporting, inlineSourceMap, splitChunks, usedExports, reactCompiler, optimize, domRoot, clientBoundaries, runModule, modulesOnly, useMd5Filename } = withDefaults(options);
const dev = mode !== 'production';
const isHermes = engine === 'hermes';
if (isExporting) {
debug('Disabling lazy bundling for export build');
options.lazy = false;
}
let fakeSourceUrl;
let fakeSourceMapUrl;
// TODO: Upstream support to Metro for passing custom serializer options.
if (serializerIncludeMaps != null || serializerOutput != null) {
fakeSourceUrl = new URL(createBundleUrlPath(options).replace(/^\//, ''), 'http://localhost:8081').toString();
if (serializerIncludeMaps) {
fakeSourceMapUrl = fakeSourceUrl.replace('.bundle?', '.map?');
}
}
const customTransformOptions = {
__proto__: null,
optimize: optimize || undefined,
engine,
clientBoundaries,
preserveEnvVars: preserveEnvVars || undefined,
// Use string to match the query param behavior.
asyncRoutes: asyncRoutes ? String(asyncRoutes) : undefined,
environment,
baseUrl: baseUrl || undefined,
routerRoot,
bytecode: bytecode ? '1' : undefined,
reactCompiler: reactCompiler ? String(reactCompiler) : undefined,
dom: domRoot,
useMd5Filename: useMd5Filename || undefined
};
// Iterate and delete undefined values
for(const key in customTransformOptions){
if (customTransformOptions[key] === undefined) {
delete customTransformOptions[key];
}
}
const bundleOptions = {
platform,
entryFile: mainModuleName,
dev,
minify: minify ?? !dev,
inlineSourceMap: inlineSourceMap ?? false,
lazy: !isExporting && lazy || undefined,
unstable_transformProfile: isHermes ? 'hermes-stable' : 'default',
customTransformOptions,
runModule,
modulesOnly,
customResolverOptions: {
__proto__: null,
environment,
exporting: isExporting || undefined
},
sourceMapUrl: fakeSourceMapUrl,
sourceUrl: fakeSourceUrl,
serializerOptions: {
splitChunks,
usedExports: usedExports || undefined,
output: serializerOutput,
includeSourceMaps: serializerIncludeMaps,
exporting: isExporting || undefined
}
};
return bundleOptions;
}
function createBundleUrlPathFromExpoConfig(projectRoot, exp, options) {
var _exp_experiments;
return createBundleUrlPath({
...options,
reactCompiler: !!((_exp_experiments = exp.experiments) == null ? void 0 : _exp_experiments.reactCompiler),
baseUrl: getBaseUrlFromExpoConfig(exp),
routerRoot: (0, _router.getRouterDirectoryModuleIdWithManifest)(projectRoot, exp)
});
}
function createBundleUrlPath(options) {
const queryParams = createBundleUrlSearchParams(options);
return `/${encodeURI(options.mainModuleName.replace(/^\/+/, ''))}.bundle?${queryParams.toString()}`;
}
function createBundleOsPath(options) {
const queryParams = createBundleUrlSearchParams(options);
const mainModuleName = (0, _filePath.toPosixPath)(options.mainModuleName);
return `${mainModuleName}.bundle?${queryParams.toString()}`;
}
function createBundleUrlSearchParams(options) {
const { platform, mode, minify, environment, serializerOutput, serializerIncludeMaps, lazy, bytecode, engine, preserveEnvVars, asyncRoutes, baseUrl, routerRoot, reactCompiler, inlineSourceMap, isExporting, clientBoundaries, splitChunks, usedExports, optimize, domRoot, modulesOnly, runModule } = withDefaults(options);
const dev = String(mode !== 'production');
const queryParams = new URLSearchParams({
platform: encodeURIComponent(platform),
dev,
// TODO: Is this still needed?
hot: String(false)
});
// Lazy bundling must be disabled for bundle splitting to work.
if (!isExporting && lazy) {
queryParams.append('lazy', String(lazy));
}
if (inlineSourceMap) {
queryParams.append('inlineSourceMap', String(inlineSourceMap));
}
if (minify) {
queryParams.append('minify', String(minify));
}
// We split bytecode from the engine since you could technically use Hermes without bytecode.
// Hermes indicates the type of language features you want to transform out of the JS, whereas bytecode
// indicates whether you want to use the Hermes bytecode format.
if (engine) {
queryParams.append('transform.engine', engine);
}
if (bytecode) {
queryParams.append('transform.bytecode', '1');
}
if (asyncRoutes) {
queryParams.append('transform.asyncRoutes', String(asyncRoutes));
}
if (preserveEnvVars) {
queryParams.append('transform.preserveEnvVars', String(preserveEnvVars));
}
if (baseUrl) {
queryParams.append('transform.baseUrl', baseUrl);
}
if (clientBoundaries == null ? void 0 : clientBoundaries.length) {
queryParams.append('transform.clientBoundaries', JSON.stringify(clientBoundaries));
}
if (routerRoot != null) {
queryParams.append('transform.routerRoot', routerRoot);
}
if (reactCompiler) {
queryParams.append('transform.reactCompiler', String(reactCompiler));
}
if (domRoot) {
queryParams.append('transform.dom', domRoot);
}
if (environment) {
queryParams.append('resolver.environment', environment);
queryParams.append('transform.environment', environment);
}
if (isExporting) {
queryParams.append('resolver.exporting', String(isExporting));
}
if (splitChunks) {
queryParams.append('serializer.splitChunks', String(splitChunks));
}
if (usedExports) {
queryParams.append('serializer.usedExports', String(usedExports));
}
if (optimize) {
queryParams.append('transform.optimize', String(optimize));
}
if (serializerOutput) {
queryParams.append('serializer.output', serializerOutput);
}
if (serializerIncludeMaps) {
queryParams.append('serializer.map', String(serializerIncludeMaps));
}
if (engine === 'hermes') {
queryParams.append('unstable_transformProfile', 'hermes-stable');
}
if (modulesOnly != null) {
queryParams.set('modulesOnly', String(modulesOnly));
}
if (runModule != null) {
queryParams.set('runModule', String(runModule));
}
return queryParams;
}
function convertPathToModuleSpecifier(pathLike) {
return (0, _filePath.toPosixPath)(pathLike);
}
function getMetroOptionsFromUrl(urlFragment) {
const url = new URL(urlFragment, 'http://localhost:0');
const getStringParam = (key)=>{
const param = url.searchParams.get(key);
if (Array.isArray(param)) {
throw new Error(`Expected single value for ${key}`);
}
return param;
};
let pathname = url.pathname;
if (pathname.endsWith('.bundle')) {
pathname = pathname.slice(0, -'.bundle'.length);
}
const options = {
mode: isTruthy(getStringParam('dev') ?? 'true') ? 'development' : 'production',
minify: isTruthy(getStringParam('minify') ?? 'false'),
lazy: isTruthy(getStringParam('lazy') ?? 'false'),
routerRoot: getStringParam('transform.routerRoot') ?? 'app',
isExporting: isTruthy(getStringParam('resolver.exporting') ?? 'false'),
environment: assertEnvironment(getStringParam('transform.environment') ?? 'node'),
platform: url.searchParams.get('platform') ?? 'web',
bytecode: isTruthy(getStringParam('transform.bytecode') ?? 'false'),
mainModuleName: convertPathToModuleSpecifier(pathname),
reactCompiler: isTruthy(getStringParam('transform.reactCompiler') ?? 'false'),
asyncRoutes: isTruthy(getStringParam('transform.asyncRoutes') ?? 'false'),
baseUrl: getStringParam('transform.baseUrl') ?? undefined,
// clientBoundaries: JSON.parse(getStringParam('transform.clientBoundaries') ?? '[]'),
engine: assertEngine(getStringParam('transform.engine')),
runModule: isTruthy(getStringParam('runModule') ?? 'true'),
modulesOnly: isTruthy(getStringParam('modulesOnly') ?? 'false')
};
return options;
}
function isTruthy(value) {
return value === 'true' || value === '1';
}
function assertEnvironment(environment) {
if (!environment) {
return undefined;
}
if (![
'node',
'react-server',
'client'
].includes(environment)) {
throw new Error(`Expected transform.environment to be one of: node, react-server, client`);
}
return environment;
}
function assertEngine(engine) {
if (!engine) {
return undefined;
}
if (![
'hermes'
].includes(engine)) {
throw new Error(`Expected transform.engine to be one of: hermes`);
}
return engine;
}
//# sourceMappingURL=metroOptions.js.map
;