Socket
Socket
Sign inDemoInstall

@expo/metro-config

Package Overview
Dependencies
Maintainers
0
Versions
211
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expo/metro-config - npm Package Compare versions

Comparing version 0.18.7 to 0.19.0-canary-20240625-2333e70

18

build/babel-transformer.d.ts

@@ -1,1 +0,17 @@

export {};
import type { TransformOptions } from './babel-core';
export type ExpoBabelCaller = TransformOptions['caller'] & {
supportsReactCompiler?: boolean;
isReactServer?: boolean;
isHMREnabled?: boolean;
isServer?: boolean;
isNodeModule?: boolean;
preserveEnvVars?: boolean;
isDev?: boolean;
asyncRoutes?: boolean;
baseUrl?: string;
engine?: string;
bundler?: 'metro' | (string & object);
platform?: string | null;
routerRoot?: string;
projectRoot: string;
};

17

build/babel-transformer.js

@@ -9,2 +9,3 @@ "use strict";

const transformSync_1 = require("./transformSync");
const debug = require('debug')('expo:metro-config:babel-transformer');
function isCustomTruthy(value) {

@@ -26,5 +27,5 @@ return value === true || value === 'true';

const memoizeWarning = memoize((message) => {
console.warn(message);
debug(message);
});
function getBabelCaller({ filename, options }) {
function getBabelCaller({ filename, options, }) {
const isNodeModule = filename.includes('node_modules');

@@ -38,3 +39,3 @@ const isReactServer = options.customTransformOptions?.environment === 'react-server';

if (routerRoot == null) {
memoizeWarning('Missing transform.routerRoot option in Metro bundling request, falling back to `app` as routes directory.');
memoizeWarning('Warning: Missing transform.routerRoot option in Metro bundling request, falling back to `app` as routes directory. This can occur if you bundle without Expo CLI or expo/metro-config.');
}

@@ -66,3 +67,3 @@ return {

// target environment.
engine: options.customTransformOptions?.engine,
engine: stringOrUndefined(options.customTransformOptions?.engine),
// Provide the project root for accurately reading the Expo config.

@@ -74,4 +75,12 @@ projectRoot: options.projectRoot,

supportsStaticESM: options.experimentalImportSupport,
// Enable React compiler support in Babel.
// TODO: Remove this in the future when compiler is on by default.
supportsReactCompiler: isCustomTruthy(options.customTransformOptions?.reactCompiler)
? true
: undefined,
};
}
function stringOrUndefined(value) {
return typeof value === 'string' ? value : undefined;
}
const transform = ({ filename, src, options,

@@ -78,0 +87,0 @@ // `plugins` is used for `functionMapBabelPlugin` from `metro-source-map`. Could make sense to move this to `babel-preset-expo` too.

@@ -44,2 +44,4 @@ "use strict";

'/metro-runtime/.+\\.js$',
// Expo's metro-runtime require patch:
'@expo/metro-config/require/.+',
// Block all whatwg polyfills

@@ -55,2 +57,4 @@ 'node_modules/whatwg-.+\\.js$',

'/react-native-web/dist/.+\\.js$',
// React Server Components adapter (note we should probably use an Expo-Metro-specific version in the future).
'node_modules/react-server-dom-webpack/.+\\.js$',
].join('|'));

@@ -57,0 +61,0 @@ function isUrl(value) {

@@ -137,2 +137,3 @@ "use strict";

});
const serverRoot = (0, getModulesPaths_1.getServerRoot)(projectRoot);
// Merge in the default config from Metro here, even though loadConfig uses it as defaults.

@@ -173,3 +174,3 @@ // This is a convenience for getDefaultConfig use in metro.config.js, e.g. to modify assetExts.

];
const stdRuntime = resolve_from_1.default.silent(projectRoot, 'expo/build/winter');
const stdRuntime = resolve_from_1.default.silent(projectRoot, 'expo/src/winter');
if (stdRuntime) {

@@ -186,3 +187,17 @@ preModules.push(stdRuntime);

},
getPolyfills: () => require('@react-native/js-polyfills')(),
getPolyfills: ({ platform }) => {
// Do nothing for nullish platforms.
if (!platform) {
return [];
}
if (platform === 'web') {
return [
// Ensure that the error-guard polyfill is included in the web polyfills to
// make metro-runtime work correctly.
require.resolve('@react-native/js-polyfills/error-guard'),
];
}
// Native behavior.
return require('@react-native/js-polyfills')();
},
},

@@ -194,3 +209,3 @@ server: {

// This enables proper monorepo support for web.
unstable_serverRoot: (0, getModulesPaths_1.getServerRoot)(projectRoot),
unstable_serverRoot: serverRoot,
},

@@ -204,2 +219,3 @@ symbolicator: {

// @ts-expect-error: not on type.
unstable_renameRequire: false,
postcssHash: (0, postcss_1.getPostcssConfigHash)(projectRoot),

@@ -212,2 +228,4 @@ browserslistHash: pkg.browserslist

reanimatedVersion,
// Ensure invalidation when using identical projects in monorepos
_expoRelativeProjectRoot: path_1.default.relative(serverRoot, projectRoot),
// `require.context` support

@@ -214,0 +232,0 @@ unstable_allowRequireContext: true,

@@ -36,3 +36,4 @@ "use strict";

.map((glob) => {
return (0, glob_1.sync)(path_1.default.join(glob, 'package.json').replace(/\\/g, '/'), {
// Globs should only contain `/` as separator, even on Windows.
return (0, glob_1.globSync)(path_1.default.posix.join(glob, 'package.json').replace(/\\/g, '/'), {
cwd: workspaceProjectRoot,

@@ -39,0 +40,0 @@ absolute: true,

@@ -71,2 +71,5 @@ "use strict";

}
if (!ensured.searchParams.has('transform.reactCompiler') && exp.experiments?.reactCompiler) {
ensured.searchParams.set('transform.reactCompiler', String(!!exp.experiments?.reactCompiler));
}
if (!ensured.searchParams.has('transform.engine')) {

@@ -73,0 +76,0 @@ const isHermesEnabled = isEnableHermesManaged(exp, platform);

@@ -17,2 +17,3 @@ /**

pre: string;
paths: Record<string, Record<string, string>>;
};

@@ -19,0 +20,0 @@ export type ExpoSerializerOptions = SerializerOptions & {

@@ -100,4 +100,4 @@ "use strict";

// multiple files. It's usually used for things like TypeScript where you want the file name to appear with a
// different extension. Since it's unclear to me (Bacon) how it is used on native, I'm only disabling in web.
sourceUrl: options.platform === 'web' ? undefined : options.sourceUrl,
// different extension. Since it's unclear to me (Bacon) how it is used on native, I'm only disabling in web and native in production.
sourceUrl: options.platform === 'web' ? undefined : !options.dev ? undefined : options.sourceUrl,
});

@@ -140,2 +140,3 @@ // If the `debugId` annotation is available and we aren't inlining the source map, add it to the bundle.

]),
paths: Object.fromEntries(mods.filter(([id, code]) => typeof code !== 'number' && Object.keys(code.paths).length).map(([id, code]) => [id, code.paths])),
};

@@ -142,0 +143,0 @@ }

@@ -122,3 +122,6 @@ "use strict";

}));
return { artifacts: [...jsAssets, ...cssDeps], assets: metroAssets };
return {
artifacts: [...jsAssets, ...cssDeps],
assets: metroAssets,
};
}

@@ -171,3 +174,3 @@ exports.graphToSerialAssetsAsync = graphToSerialAssetsAsync;

debugId: undefined,
});
}).code;
}

@@ -194,3 +197,3 @@ getFilenameForConfig(serializerConfig) {

});
return (0, bundleToString_1.default)(jsSplitBundle).code;
return { code: (0, bundleToString_1.default)(jsSplitBundle).code, paths: jsSplitBundle.paths };
}

@@ -236,3 +239,4 @@ hasAbsolutePath(absolutePath) {

}
const isAbsolute = this.getPlatform() !== 'web';
const platform = this.getPlatform();
const isAbsolute = platform !== 'web';
const baseUrl = (0, baseJSBundle_1.getBaseUrlOption)(this.graph, this.options);

@@ -258,2 +262,6 @@ const filename = this.getFilenameForConfig(serializerConfig);

catch (error) {
// NOTE: export:embed that don't use baseUrl will use file paths instead of URLs.
if (!this.options.dev && isAbsolute) {
return adjustedSourceMapUrl;
}
console.error(`Failed to link source maps because the source map URL "${this.options.sourceMapUrl}" is corrupt:`, error);

@@ -299,4 +307,18 @@ return null;

modulePaths: [...this.deps].map((module) => module.path),
paths: jsCode.paths,
reactClientReferences: [
...new Set([...this.deps]
.map((module) => {
return module.output.map((output) => {
if ('reactClientReference' in output.data &&
typeof output.data.reactClientReference === 'string') {
return output.data.reactClientReference;
}
return undefined;
});
})
.flat()),
].filter((value) => typeof value === 'string'),
},
source: jsCode,
source: jsCode.code,
};

@@ -303,0 +325,0 @@ const assets = [jsAsset];

@@ -5,7 +5,11 @@ export type SerialAsset = {

source: string;
type: 'css' | 'js' | 'map';
type: 'css' | 'js' | 'map' | 'json';
metadata: {
hmrId?: string;
isAsync?: boolean;
modulePaths?: string[];
} & Record<string, boolean | string | string[]>;
paths?: Record<string, Record<string, string>>;
reactClientReferences?: string[];
requires?: string[];
};
};
import { BabelTransformerArgs } from 'metro-babel-transformer';
export declare function transform({ filename, options }: BabelTransformerArgs, assetRegistryPath: string, assetDataPlugins: readonly string[]): Promise<{
ast: import("@babel/parser").ParseResult<import("@babel/types").File>;
export declare function transform({ filename, options, }: {
filename: string;
options: Pick<BabelTransformerArgs['options'], 'platform' | 'projectRoot' | 'customTransformOptions' | 'publicPath'>;
}, assetRegistryPath: string, assetDataPlugins: readonly string[]): Promise<{
ast: import('@babel/core').ParseResult;
reactClientReference?: string;
}>;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -17,13 +40,30 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

*/
const template_1 = __importDefault(require("@babel/template"));
const t = __importStar(require("@babel/types"));
const util_1 = require("metro/src/Bundler/util");
const node_path_1 = __importDefault(require("node:path"));
const node_url_1 = __importDefault(require("node:url"));
const getAssets_1 = require("./getAssets");
async function transform({ filename, options }, assetRegistryPath, assetDataPlugins) {
// Register client components for assets in server component environments.
const buildClientReferenceRequire = template_1.default.statement(`module.exports = require('react-server-dom-webpack/server').createClientModuleProxy(FILE_PATH);`);
async function transform({ filename, options, }, assetRegistryPath, assetDataPlugins) {
options ??= options || {
platform: '',
projectRoot: '',
inlineRequires: false,
minify: false,
};
const absolutePath = node_path_1.default.resolve(options.projectRoot, filename);
if (options.customTransformOptions?.environment === 'react-server') {
const clientReference = node_url_1.default.pathToFileURL(absolutePath).href;
return {
ast: {
...t.file(t.program([
buildClientReferenceRequire({
FILE_PATH: JSON.stringify(clientReference),
}),
])),
errors: [],
},
reactClientReference: clientReference,
};
}
const data = await (0, getAssets_1.getUniversalAssetData)(absolutePath, filename, assetDataPlugins, options.platform, options.publicPath);

@@ -30,0 +70,0 @@ return {

@@ -8,5 +8,10 @@ /// <reference types="node" />

readonly dependencies: readonly TransformResultDependency[];
readonly output: readonly JsOutput[];
readonly output: readonly ExpoJsOutput[];
}
export type ExpoJsOutput = Pick<JsOutput, 'type'> & {
readonly data: JsOutput['data'] & {
readonly reactClientReference?: string;
};
};
export declare function transform(config: JsTransformerConfig, projectRoot: string, filename: string, data: Buffer, options: JsTransformOptions): Promise<TransformResponse>;
export declare function getCacheKey(config: JsTransformerConfig): string;

@@ -121,2 +121,4 @@ "use strict";

async function transformJS(file, { config, options, projectRoot }) {
// const targetEnv = options.customTransformOptions?.environment;
// const isServerEnv = targetEnv === 'node' || targetEnv === 'react-server';
// Transformers can output null ASTs (if they ignore the file). In that case

@@ -247,2 +249,5 @@ // we need to parse the module source code to get their AST.

unstable_allowRequireContext: config.unstable_allowRequireContext,
// NOTE(EvanBacon): Allow arbitrary imports in server environments.
// This requires a patch to Metro collectDeps.
// allowArbitraryImport: isServerEnv,
};

@@ -262,3 +267,8 @@ ({ ast, dependencies, dependencyMapName } = (0, collectDependencies_1.default)(ast, opts));

// TODO: Replace this with a cheaper transform that doesn't require AST.
({ ast: wrappedAst } = JsFileWrapping_1.default.wrapModule(ast, importDefault, importAll, dependencyMapName, config.globalPrefix));
({ ast: wrappedAst } = JsFileWrapping_1.default.wrapModule(ast, importDefault, importAll, dependencyMapName, config.globalPrefix,
// TODO: This config is optional to allow its introduction in a minor
// release. It should be made non-optional in ConfigT or removed in
// future.
// @ts-expect-error: Not on types yet (Metro 0.80.9).
config.unstable_renameRequire === false));
}

@@ -300,2 +310,3 @@ }

functionMap: file.functionMap,
reactClientReference: file.reactClientReference,
},

@@ -320,2 +331,3 @@ type: file.type,

functionMap: null,
reactClientReference: result.reactClientReference,
};

@@ -331,2 +343,12 @@ return transformJS(jsFile, context);

const transformer = require(babelTransformerPath);
// HACK: React Compiler injects import statements and exits the Babel process which leaves the code in
// a malformed state. For now, we'll enable the experimental import support which compiles import statements
// outside of the standard Babel process.
if (!context.options.experimentalImportSupport) {
const reactCompilerFlag = context.options.customTransformOptions?.reactCompiler;
if (reactCompilerFlag === true || reactCompilerFlag === 'true') {
// @ts-expect-error: readonly.
context.options.experimentalImportSupport = true;
}
}
const transformResult = await transformer.transform(

@@ -342,2 +364,3 @@ // functionMapBabelPlugin populates metadata.metro.functionMap

null,
reactClientReference: transformResult.metadata?.reactClientReference,
};

@@ -344,0 +367,0 @@ return await transformJS(jsFile, context);

{
"name": "@expo/metro-config",
"version": "0.18.7",
"version": "0.19.0-canary-20240625-2333e70",
"description": "A Metro config for running React Native projects with the Metro bundler",

@@ -40,5 +40,5 @@ "main": "build/ExpoMetroConfig.js",

"@babel/types": "^7.20.0",
"@expo/config": "~9.0.0-beta.0",
"@expo/env": "~0.3.0",
"@expo/json-file": "~8.3.0",
"@expo/config": "9.0.3-canary-20240625-2333e70",
"@expo/env": "0.3.1-canary-20240625-2333e70",
"@expo/json-file": "8.3.4-canary-20240625-2333e70",
"@expo/spawn-async": "^1.7.2",

@@ -50,3 +50,3 @@ "chalk": "^4.1.0",

"getenv": "^1.0.0",
"glob": "^7.2.3",
"glob": "^10.4.2",
"jsc-safe-url": "^0.2.4",

@@ -59,3 +59,3 @@ "lightningcss": "~1.19.0",

"@jridgewell/trace-mapping": "^0.3.20",
"expo-module-scripts": "^3.3.0",
"expo-module-scripts": "3.6.0-canary-20240625-2333e70",
"sass": "^1.60.0"

@@ -66,3 +66,3 @@ },

},
"gitHead": "6f609a05a2d4dac7fd281bcc502575440c5af7c9"
"gitHead": "2333e70a4bd3ac91895402dac77ae8ae0ed25995"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc