@expo/cli
Version:
173 lines (172 loc) • 6.71 kB
JavaScript
/**
* Copyright © 2022 650 Industries.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/ "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, {
cachedSourceMaps: function() {
return cachedSourceMaps;
},
createMetroEndpointAsync: function() {
return createMetroEndpointAsync;
},
evalMetroAndWrapFunctions: function() {
return evalMetroAndWrapFunctions;
},
evalMetroNoHandling: function() {
return evalMetroNoHandling;
}
});
function _paths() {
const data = require("@expo/config/paths");
_paths = function() {
return data;
};
return data;
}
function _fs() {
const data = /*#__PURE__*/ _interop_require_default(require("fs"));
_fs = function() {
return data;
};
return data;
}
function _path() {
const data = /*#__PURE__*/ _interop_require_default(require("path"));
_path = function() {
return data;
};
return data;
}
function _requirefromstring() {
const data = /*#__PURE__*/ _interop_require_default(require("require-from-string"));
_requirefromstring = function() {
return data;
};
return data;
}
const _metroErrorInterface = require("./metro/metroErrorInterface");
const _metroOptions = require("./middleware/metroOptions");
const _serverLogLikeMetro = require("./serverLogLikeMetro");
const _delay = require("../../utils/delay");
const _errors = require("../../utils/errors");
const _filePath = require("../../utils/filePath");
const _profile = require("../../utils/profile");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const debug = require('debug')('expo:start:server:getStaticRenderFunctions');
const cachedSourceMaps = new Map();
// Support unhandled rejections
// Detect if running in Bun
// @ts-expect-error: This is a global variable that is set by Bun.
if (!process.isBun) {
require('source-map-support').install({
retrieveSourceMap (source) {
if (cachedSourceMaps.has(source)) {
return cachedSourceMaps.get(source);
}
return null;
}
});
}
async function ensureFileInRootDirectory(projectRoot, otherFile) {
// Cannot be accessed using Metro's server API, we need to move the file
// into the project root and try again.
if (!_path().default.relative(projectRoot, otherFile).startsWith('..' + _path().default.sep)) {
return otherFile;
}
// Copy the file into the project to ensure it works in monorepos.
// This means the file cannot have any relative imports.
const tempDir = _path().default.join(projectRoot, '.expo/static-tmp');
await _fs().default.promises.mkdir(tempDir, {
recursive: true
});
const moduleId = _path().default.join(tempDir, _path().default.basename(otherFile));
await _fs().default.promises.writeFile(moduleId, await _fs().default.promises.readFile(otherFile, 'utf8'));
// Sleep to give watchman time to register the file.
await (0, _delay.delayAsync)(50);
return moduleId;
}
async function createMetroEndpointAsync(projectRoot, devServerUrl, absoluteFilePath, props) {
const root = (0, _paths().getMetroServerRoot)(projectRoot);
const safeOtherFile = await ensureFileInRootDirectory(projectRoot, absoluteFilePath);
const serverPath = _path().default.relative(root, safeOtherFile).replace(/\.[jt]sx?$/, '');
const urlFragment = (0, _metroOptions.createBundleUrlPath)({
mainModuleName: serverPath,
lazy: false,
asyncRoutes: false,
inlineSourceMap: false,
engine: 'hermes',
minify: false,
bytecode: false,
...props
});
let url;
if (devServerUrl) {
url = new URL(urlFragment.replace(/^\//, ''), devServerUrl).toString();
} else {
url = '/' + urlFragment.replace(/^\/+/, '');
}
return url;
}
function evalMetroAndWrapFunctions(projectRoot, script, filename, isExporting) {
// TODO: Add back stack trace logic that hides traces from metro-runtime and other internal modules.
const contents = evalMetroNoHandling(projectRoot, script, filename);
if (!contents) {
// This can happen if ErrorUtils isn't working correctly on web and failing to throw an error when a module throws.
// This is unexpected behavior and should not be pretty formatted, therefore we're avoiding CommandError.
throw new Error('[Expo SSR] Module returned undefined, this could be due to a misconfiguration in Metro error handling');
}
// wrap each function with a try/catch that uses Metro's error formatter
return Object.keys(contents).reduce((acc, key)=>{
const fn = contents[key];
if (typeof fn !== 'function') {
return {
...acc,
[key]: fn
};
}
acc[key] = async function(...props) {
try {
return await fn.apply(this, props);
} catch (error) {
await (0, _metroErrorInterface.logMetroError)(projectRoot, {
error
});
if (isExporting || error[_metroErrorInterface.IS_METRO_BUNDLE_ERROR_SYMBOL]) {
throw error;
} else {
// TODO: When does this happen?
throw new _errors.SilentError(error);
}
}
};
return acc;
}, {});
}
function evalMetroNoHandling(projectRoot, src, filename) {
(0, _serverLogLikeMetro.augmentLogs)(projectRoot);
// NOTE(@kitten): `require-from-string` derives a base path from the filename we pass it,
// but doesn't validate that the filename exists. These debug messages should help identify
// these problems, if they occur in user projects without reproductions
if (!_fs().default.existsSync(_path().default.dirname(filename))) {
debug(`evalMetroNoHandling received filename in a directory that does not exist: ${filename}`);
} else if (!(0, _filePath.toPosixPath)(_path().default.dirname(filename)).startsWith((0, _filePath.toPosixPath)(projectRoot))) {
debug(`evalMetroNoHandling received filename outside of the project root: ${filename}`);
}
return (0, _profile.profile)(_requirefromstring().default, 'eval-metro-bundle')(src, filename);
}
//# sourceMappingURL=getStaticRenderFunctions.js.map