mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
93 lines
3.2 KiB
JavaScript
93 lines
3.2 KiB
JavaScript
|
|
/**
|
||
|
|
* 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.
|
||
|
|
*/
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
// Most of our tests call jest.resetModules in a beforeEach and the
|
||
|
|
// re-require all the React modules. However, the JSX runtime is injected by
|
||
|
|
// the compiler, so those bindings don't get updated. This causes warnings
|
||
|
|
// logged by the JSX runtime to not have a component stack, because component
|
||
|
|
// stack relies on the the secret internals object that lives on the React
|
||
|
|
// module, which because of the resetModules call is longer the same one.
|
||
|
|
//
|
||
|
|
// To workaround this issue, use a transform that calls require() again before
|
||
|
|
// every JSX invocation.
|
||
|
|
//
|
||
|
|
// Longer term we should migrate all our tests away from using require() and
|
||
|
|
// resetModules, and use import syntax instead so this kind of thing doesn't
|
||
|
|
// happen.
|
||
|
|
|
||
|
|
module.exports = function replaceJSXImportWithLazy(babel) {
|
||
|
|
const {types: t} = babel;
|
||
|
|
|
||
|
|
function getInlineRequire(moduleName) {
|
||
|
|
return t.callExpression(t.identifier('require'), [
|
||
|
|
t.stringLiteral(moduleName),
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
visitor: {
|
||
|
|
CallExpression: function (path, pass) {
|
||
|
|
let callee = path.node.callee;
|
||
|
|
if (callee.type === 'SequenceExpression') {
|
||
|
|
callee = callee.expressions[callee.expressions.length - 1];
|
||
|
|
}
|
||
|
|
if (callee.type === 'Identifier') {
|
||
|
|
// Sometimes we seem to hit this before the imports are transformed
|
||
|
|
// into requires and so we hit this case.
|
||
|
|
switch (callee.name) {
|
||
|
|
case '_jsxDEV':
|
||
|
|
path.node.callee = t.memberExpression(
|
||
|
|
getInlineRequire('react/jsx-dev-runtime'),
|
||
|
|
t.identifier('jsxDEV')
|
||
|
|
);
|
||
|
|
return;
|
||
|
|
case '_jsx':
|
||
|
|
path.node.callee = t.memberExpression(
|
||
|
|
getInlineRequire('react/jsx-runtime'),
|
||
|
|
t.identifier('jsx')
|
||
|
|
);
|
||
|
|
return;
|
||
|
|
case '_jsxs':
|
||
|
|
path.node.callee = t.memberExpression(
|
||
|
|
getInlineRequire('react/jsx-runtime'),
|
||
|
|
t.identifier('jsxs')
|
||
|
|
);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (callee.type !== 'MemberExpression') {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (callee.property.type !== 'Identifier') {
|
||
|
|
// Needs to be jsx, jsxs, jsxDEV.
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (callee.object.type !== 'Identifier') {
|
||
|
|
// Needs to be _reactJsxDevRuntime or _reactJsxRuntime.
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
// Replace the cached identifier with a new require call.
|
||
|
|
// Relying on the identifier name is a little flaky. Should ideally pick
|
||
|
|
// this from the import. For some reason it sometimes has the react prefix
|
||
|
|
// and other times it doesn't.
|
||
|
|
switch (callee.object.name) {
|
||
|
|
case '_reactJsxDevRuntime':
|
||
|
|
case '_jsxDevRuntime':
|
||
|
|
callee.object = getInlineRequire('react/jsx-dev-runtime');
|
||
|
|
return;
|
||
|
|
case '_reactJsxRuntime':
|
||
|
|
case '_jsxRuntime':
|
||
|
|
callee.object = getInlineRequire('react/jsx-runtime');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
};
|