metro-transform-plugins
Advanced tools
Comparing version 0.80.5 to 0.80.6
{ | ||
"name": "metro-transform-plugins", | ||
"version": "0.80.5", | ||
"version": "0.80.6", | ||
"description": "🚇 Transform plugins for Metro.", | ||
@@ -29,3 +29,3 @@ "main": "src/index.js", | ||
"babel-plugin-tester": "^6.0.1", | ||
"metro": "0.80.5" | ||
"metro": "0.80.6" | ||
}, | ||
@@ -32,0 +32,0 @@ "engines": { |
@@ -1,20 +0,3 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
/** | ||
* Simple way of adding additional parameters to the end of the define calls. | ||
* | ||
* This is used to add extra information to the generaic compiled modules (like | ||
* the dependencyMap object or the list of inverse dependencies). | ||
*/ | ||
function addParamsToDefineCall(code, ...paramsToAdd) { | ||
@@ -21,0 +4,0 @@ const index = code.lastIndexOf(")"); |
@@ -1,17 +0,3 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
// This is only a typeof import, no runtime dependency exists | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
function constantFoldingPlugin(context) { | ||
@@ -32,8 +18,2 @@ const t = context.types; | ||
CallExpression: unsafe, | ||
/** | ||
* This will mark `foo?.()` as unsafe, so it is not replaced with `undefined` down the line. | ||
* | ||
* We saw this case in the wild, where the unary expression `void foo?.()` was replaced with `undefined` | ||
* resulting in the expression call being skipped. | ||
*/ | ||
OptionalCallExpression: unsafe, | ||
@@ -72,45 +52,38 @@ }, | ||
}; | ||
const FunctionExpression = | ||
// $FlowFixMe[incompatible-type] | ||
{ | ||
exit(path, state) { | ||
const parentPath = path.parentPath; | ||
const parentNode = parentPath?.node; | ||
if (isVariableDeclarator(parentNode) && parentNode.id.name != null) { | ||
const binding = parentPath?.scope.getBinding(parentNode.id.name); | ||
if (binding && !binding.referenced) { | ||
state.stripped = true; | ||
parentPath?.remove(); | ||
} | ||
} | ||
}, | ||
}; | ||
const Conditional = | ||
// $FlowFixMe[incompatible-type] | ||
{ | ||
exit(path, state) { | ||
const node = path.node; | ||
const result = evaluate(path.get("test")); | ||
if (result.confident) { | ||
const FunctionExpression = { | ||
exit(path, state) { | ||
const parentPath = path.parentPath; | ||
const parentNode = parentPath?.node; | ||
if (isVariableDeclarator(parentNode) && parentNode.id.name != null) { | ||
const binding = parentPath?.scope.getBinding(parentNode.id.name); | ||
if (binding && !binding.referenced) { | ||
state.stripped = true; | ||
if (result.value || node.alternate) { | ||
// $FlowFixMe Flow error uncovered by typing Babel more strictly | ||
path.replaceWith(result.value ? node.consequent : node.alternate); | ||
} else if (!result.value) { | ||
path.remove(); | ||
} | ||
parentPath?.remove(); | ||
} | ||
}, | ||
}; | ||
const Expression = | ||
// $FlowFixMe[incompatible-type] | ||
{ | ||
exit(path) { | ||
const result = evaluate(path); | ||
if (result.confident) { | ||
path.replaceWith(t.valueToNode(result.value)); | ||
path.skip(); | ||
} | ||
}, | ||
}; | ||
const Conditional = { | ||
exit(path, state) { | ||
const node = path.node; | ||
const result = evaluate(path.get("test")); | ||
if (result.confident) { | ||
state.stripped = true; | ||
if (result.value || node.alternate) { | ||
path.replaceWith(result.value ? node.consequent : node.alternate); | ||
} else if (!result.value) { | ||
path.remove(); | ||
} | ||
}, | ||
}; | ||
} | ||
}, | ||
}; | ||
const Expression = { | ||
exit(path) { | ||
const result = evaluate(path); | ||
if (result.confident) { | ||
path.replaceWith(t.valueToNode(result.value)); | ||
path.skip(); | ||
} | ||
}, | ||
}; | ||
const LogicalExpression = { | ||
@@ -145,3 +118,2 @@ exit(path) { | ||
ConditionalExpression: Conditional, | ||
// $FlowFixMe[incompatible-call] | ||
FunctionDeclaration, | ||
@@ -156,5 +128,2 @@ FunctionExpression, | ||
path.scope.crawl(); | ||
// Re-traverse all program, if we removed any blocks. Manually re-call | ||
// enter and exit, because traversing a Program node won't call them. | ||
Program.enter(path, state); | ||
@@ -170,3 +139,2 @@ path.traverse(visitor, { | ||
BinaryExpression: Expression, | ||
// $FlowFixMe[incompatible-type] | ||
LogicalExpression, | ||
@@ -176,3 +144,2 @@ Program: { | ||
}, | ||
// Babel mutates objects passed. | ||
UnaryExpression: Expression, | ||
@@ -179,0 +146,0 @@ }; |
@@ -1,48 +0,14 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
// Type only dependency. This is not a runtime dependency | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const template = require("@babel/template").default; | ||
const nullthrows = require("nullthrows"); | ||
/** | ||
* Produces a Babel template that transforms an "import * as x from ..." or an | ||
* "import x from ..." call into a "const x = importAll(...)" call with the | ||
* corresponding id in it. | ||
*/ | ||
const importTemplate = template.statement(` | ||
var LOCAL = IMPORT(FILE); | ||
`); | ||
/** | ||
* Produces a Babel template that transforms an "import {x as y} from ..." into | ||
* "const y = require(...).x" call with the corresponding id in it. | ||
*/ | ||
const importNamedTemplate = template.statement(` | ||
var LOCAL = require(FILE).REMOTE; | ||
`); | ||
/** | ||
* Produces a Babel template that transforms an "import ..." into | ||
* "require(...)", which is considered a side-effect call. | ||
*/ | ||
const importSideEffectTemplate = template.statement(` | ||
require(FILE); | ||
`); | ||
/** | ||
* Produces an "export all" template that traverses all exported symbols and | ||
* re-exposes them. | ||
*/ | ||
const exportAllTemplate = template.statements(` | ||
@@ -55,29 +21,11 @@ var REQUIRED = require(FILE); | ||
`); | ||
/** | ||
* Produces a "named export" or "default export" template to export a single | ||
* symbol. | ||
*/ | ||
const exportTemplate = template.statement(` | ||
exports.REMOTE = LOCAL; | ||
`); | ||
/** | ||
* Flags the exported module as a transpiled ES module. Needs to be kept in 1:1 | ||
* compatibility with Babel. | ||
*/ | ||
const esModuleExportTemplate = template.statement(` | ||
Object.defineProperty(exports, '__esModule', {value: true}); | ||
`); | ||
/** | ||
* Resolution template in case it is requested. | ||
*/ | ||
const resolveTemplate = template.expression(` | ||
require.resolve(NODE) | ||
`); | ||
/** | ||
* Enforces the resolution of a path to a fully-qualified one, if set. | ||
*/ | ||
function resolvePath(node, resolve) { | ||
@@ -91,5 +39,2 @@ if (!resolve) { | ||
} | ||
// eslint-disable-next-line no-redeclare | ||
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's | ||
* LTI update could not be added via codemod */ | ||
function withLocation(node, loc) { | ||
@@ -122,4 +67,2 @@ if (Array.isArray(node)) { | ||
declaration.id || path.scope.generateUidIdentifier("default"); | ||
// $FlowFixMe Flow error uncovered by typing Babel more strictly | ||
declaration.id = id; | ||
@@ -159,5 +102,3 @@ const loc = path.node.loc; | ||
properties.forEach((p) => { | ||
// $FlowFixMe Flow error uncovered by typing Babel more strictly | ||
const name = p.key.name; | ||
// $FlowFixMe[incompatible-call] | ||
state.exportNamed.push({ | ||
@@ -175,5 +116,3 @@ local: name, | ||
elements.forEach((e) => { | ||
// $FlowFixMe Flow error uncovered by typing Babel more strictly | ||
const name = e.name; | ||
// $FlowFixMe[incompatible-call] | ||
state.exportNamed.push({ | ||
@@ -190,3 +129,2 @@ local: name, | ||
const name = d.id.name; | ||
// $FlowFixMe[incompatible-call] | ||
state.exportNamed.push({ | ||
@@ -204,6 +142,3 @@ local: name, | ||
const name = id.name; | ||
// $FlowFixMe Flow error uncovered by typing Babel more strictly | ||
declaration.id = id; | ||
// $FlowFixMe[incompatible-call] | ||
state.exportNamed.push({ | ||
@@ -223,3 +158,2 @@ local: name, | ||
if (remote.type === "StringLiteral") { | ||
// https://babeljs.io/docs/en/babel-plugin-syntax-module-string-names | ||
throw path.buildCodeFrameError( | ||
@@ -230,6 +164,3 @@ "Module string names are not supported" | ||
if (path.node.source) { | ||
// $FlowFixMe[incompatible-use] | ||
const temp = path.scope.generateUidIdentifier(local.name); | ||
// $FlowFixMe[incompatible-type] | ||
if (local.name === "default") { | ||
@@ -294,3 +225,2 @@ path.insertBefore( | ||
if (remote.name === "default") { | ||
// $FlowFixMe[incompatible-use] | ||
state.exportDefault.push({ | ||
@@ -302,3 +232,2 @@ local: local.name, | ||
state.exportNamed.push({ | ||
// $FlowFixMe[incompatible-use] | ||
local: local.name, | ||
@@ -387,3 +316,2 @@ remote: remote.name, | ||
case "ImportSpecifier": | ||
// $FlowFixMe[incompatible-type] | ||
if (imported.name === "default") { | ||
@@ -410,3 +338,2 @@ state.imports.push({ | ||
t.cloneNode(sharedModuleImport), | ||
// $FlowFixMe[incompatible-call] | ||
t.cloneNode(imported) | ||
@@ -452,6 +379,3 @@ ) | ||
const body = path.node.body; | ||
// state.imports = [node1, node2, node3, ...nodeN] | ||
state.imports.reverse().forEach((e) => { | ||
// import nodes are added to the top of the program body | ||
body.unshift(e.node); | ||
@@ -472,3 +396,2 @@ }); | ||
body.push( | ||
// $FlowFixMe[incompatible-call] | ||
...withLocation( | ||
@@ -475,0 +398,0 @@ exportAllTemplate({ |
@@ -1,39 +0,19 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
// TODO: Type this properly | ||
module.exports = { | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get addParamsToDefineCall() { | ||
return require("./addParamsToDefineCall"); | ||
}, | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get constantFoldingPlugin() { | ||
return require("./constant-folding-plugin"); | ||
}, | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get importExportPlugin() { | ||
return require("./import-export-plugin"); | ||
}, | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get inlinePlugin() { | ||
return require("./inline-plugin"); | ||
}, | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get inlineRequiresPlugin() { | ||
// $FlowFixMe[untyped-import] | ||
return require("./inline-requires-plugin"); | ||
}, | ||
// $FlowIgnore[unsafe-getters-setters] | ||
get normalizePseudoGlobals() { | ||
@@ -40,0 +20,0 @@ return require("./normalizePseudoGlobals"); |
@@ -1,17 +0,3 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
// type only import. No runtime dependency | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const createInlinePlatformChecks = require("./utils/createInlinePlatformChecks"); | ||
@@ -45,4 +31,2 @@ const env = { | ||
); | ||
// $FlowFixMe[deprecated-type] | ||
function isGlobal(binding) { | ||
@@ -52,4 +36,2 @@ return !binding; | ||
const isFlowDeclared = (binding) => t.isDeclareVariable(binding.path); | ||
// $FlowFixMe[deprecated-type] | ||
function isGlobalOrFlowDeclared(binding) { | ||
@@ -56,0 +38,0 @@ return isGlobal(binding) || isFlowDeclared(binding); |
@@ -1,39 +0,3 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @format | ||
*/ | ||
"use strict"; | ||
/** | ||
* This transform inlines top-level require(...) aliases with to enable lazy | ||
* loading of dependencies. It is able to inline both single references and | ||
* child property references. | ||
* | ||
* For instance: | ||
* var Foo = require('foo'); | ||
* f(Foo); | ||
* | ||
* Will be transformed into: | ||
* f(require('foo')); | ||
* | ||
* When the assigment expression has a property access, it will be inlined too, | ||
* keeping the property. For instance: | ||
* var Bar = require('foo').bar; | ||
* g(Bar); | ||
* | ||
* Will be transformed into: | ||
* g(require('foo').bar); | ||
* | ||
* Destructuring also works the same way. For instance: | ||
* const {Baz} = require('foo'); | ||
* h(Baz); | ||
* | ||
* Is also successfully inlined into: | ||
* g(require('foo').Baz); | ||
*/ | ||
module.exports = (babel) => ({ | ||
@@ -99,5 +63,2 @@ name: "inline-requires", | ||
} | ||
// If a replacement failed (e.g. replacing a type annotation), | ||
// avoid removing the initial require just to be safe. | ||
if (!thrown) { | ||
@@ -211,4 +172,2 @@ declarationPath.remove(); | ||
} | ||
// require('foo'); | ||
let moduleName = | ||
@@ -218,4 +177,2 @@ node["arguments"][0].type === "StringLiteral" | ||
: null; | ||
// require(require.resolve('foo')); | ||
if (moduleName == null) { | ||
@@ -234,4 +191,2 @@ moduleName = | ||
} | ||
// Check if require is in any parent scope | ||
const fnName = node.callee.name; | ||
@@ -238,0 +193,0 @@ const isRequireInScope = path.scope.getBinding(fnName) != null; |
@@ -1,12 +0,1 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
@@ -29,3 +18,2 @@ | ||
.map((path) => path.node.name) | ||
// $FlowFixMe[incompatible-call] Flow error uncovered by typing Babel more strictly | ||
.filter((name) => !reservedNames.has(name)); | ||
@@ -54,5 +42,2 @@ const usedShortNames = new Set(); | ||
function getShortName(fullName, usedNames) { | ||
// Try finding letters that are semantically relatable to the name | ||
// of the variable given. For instance, in XMLHttpRequest, it will | ||
// first match "X", then "H", then "R". | ||
const regexp = /^[^A-Za-z]*([A-Za-z])|([A-Z])[a-z]|([A-Z])[A-Z]+$/g; | ||
@@ -80,6 +65,2 @@ let match; | ||
let unusedName = shortName; | ||
// `generateUid` generates a name of the form name_ even if there was no conflict which we don't want. | ||
// Check if the desired name was never used and in that case proceed and only use `generateUid` if there's a | ||
// name clash. | ||
if ( | ||
@@ -86,0 +67,0 @@ scope.hasLabel(shortName) || |
@@ -1,17 +0,3 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* | ||
* @format | ||
* @oncall react_native | ||
*/ | ||
"use strict"; | ||
// Type only import. No runtime dependency | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const importMap = new Map([["ReactNative", "react-native"]]); | ||
@@ -55,3 +41,2 @@ function createInlinePlatformChecks(t, requireName = "require") { | ||
isImportOrGlobal( | ||
// $FlowFixMe[incompatible-call] | ||
node.object.object, | ||
@@ -75,3 +60,2 @@ scope, | ||
isImportOrGlobal( | ||
// $FlowFixMe[incompatible-call] | ||
node.callee.object, | ||
@@ -96,4 +80,2 @@ scope, | ||
isImportOrGlobal( | ||
// $FlowFixMe[incompatible-call] | ||
// $FlowFixMe[incompatible-use] | ||
node.callee.object.object, | ||
@@ -111,4 +93,2 @@ scope, | ||
); | ||
// $FlowFixMe[deprecated-type] | ||
function isGlobal(binding) { | ||
@@ -115,0 +95,0 @@ return !binding; |
75912
1141