mirror of https://github.com/status-im/metro.git
Let the inline plugin use the babel types from arg
Summary: Before the inline plugin was explicitly requiring babel itself. With the babel upgrade path that's a problem since it will try to pull in babel 6 even when we want babel 7 (because it's a different package name). To remedy this the plugin is now a function which will use the `types` api from the given context rather than the required global. I also moved out the `inline` function that only seems to be used in tests. They're now just living in the tests. Had to add some flow annotations to generic objects since Flow was complaining about missing types and that would require adding the full babel api which is outside of the scope of this task. Reviewed By: jeanlauliac Differential Revision: D7083815 fbshipit-source-id: 59b8365d8c3c3dc00b23a3735037dcc9483c0b2c
This commit is contained in:
parent
8292958c00
commit
56e7aed7cb
|
@ -9,18 +9,52 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const inline = require('../inline');
|
||||
const inlinePlugin = require('../inline-plugin');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
const {transformSync} = require('../../../babel-bridge');
|
||||
const {transformFromAstSync} = require('../../../babel-bridge');
|
||||
|
||||
import type {TransformResult} from '@babel/core';
|
||||
import type {Ast} from 'babel-core';
|
||||
import type {BabelSourceMap} from 'babel-core';
|
||||
|
||||
const babelOptions = {
|
||||
babelrc: false,
|
||||
compact: true,
|
||||
};
|
||||
|
||||
type AstResult = {
|
||||
ast: Ast,
|
||||
code: ?string,
|
||||
map: ?BabelSourceMap,
|
||||
};
|
||||
|
||||
function inline(
|
||||
filename: string,
|
||||
transformResult: {ast?: ?Ast, code: string, map: ?BabelSourceMap},
|
||||
options: {+dev: boolean, +platform: ?string},
|
||||
): AstResult {
|
||||
const code = transformResult.code;
|
||||
const babelOptions = {
|
||||
filename,
|
||||
plugins: [[inlinePlugin, options]],
|
||||
inputSourceMap: transformResult.map,
|
||||
sourceMaps: true,
|
||||
sourceFileName: filename,
|
||||
code: false,
|
||||
babelrc: false,
|
||||
compact: true,
|
||||
};
|
||||
|
||||
const result = transformResult.ast
|
||||
? transformFromAstSync(transformResult.ast, code, babelOptions)
|
||||
: transformSync(code, babelOptions);
|
||||
const {ast} = result;
|
||||
invariant(ast != null, 'Missing AST in babel transform results.');
|
||||
return {ast, code: result.code, map: result.map};
|
||||
}
|
||||
|
||||
function toString(ast): string {
|
||||
return normalize(transformFromAstSync(ast, babelOptions).code);
|
||||
}
|
||||
|
@ -475,7 +509,7 @@ describe('inline constants', () => {
|
|||
|
||||
const transformed = transformSync(code, {
|
||||
...babelOptions,
|
||||
plugins: [stripFlow, [inline.plugin, {dev: false}]],
|
||||
plugins: [stripFlow, [inlinePlugin, {dev: false}]],
|
||||
}).code;
|
||||
|
||||
expect(transformed).toEqual('const a=false;');
|
||||
|
@ -490,7 +524,7 @@ describe('inline constants', () => {
|
|||
|
||||
const transformed = transformSync(code, {
|
||||
...babelOptions,
|
||||
plugins: [stripFlow, [inline.plugin, {dev: true}]],
|
||||
plugins: [stripFlow, [inlinePlugin, {dev: true}]],
|
||||
}).code;
|
||||
|
||||
expect(transformed).toEqual('__d(()=>{const a=true;});');
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
jest
|
||||
.mock('../constant-folding')
|
||||
.mock('../inline')
|
||||
.mock('../inline-plugin')
|
||||
.mock('metro-minify-uglify');
|
||||
|
||||
const path = require('path');
|
||||
|
|
|
@ -16,7 +16,7 @@ const assetTransformer = require('../../assetTransformer');
|
|||
const collectDependencies = require('../../ModuleGraph/worker/collectDependencies');
|
||||
const constantFolding = require('./constant-folding');
|
||||
const getMinifier = require('../../lib/getMinifier');
|
||||
const inline = require('./inline');
|
||||
const inlinePlugin = require('./inline-plugin');
|
||||
const optimizeDependencies = require('../../ModuleGraph/worker/optimizeDependencies');
|
||||
const path = require('path');
|
||||
|
||||
|
@ -231,9 +231,9 @@ function transformCode(
|
|||
|
||||
const plugins = options.dev
|
||||
? []
|
||||
: [[inline.plugin, options], [constantFolding.plugin, options]];
|
||||
: [[inlinePlugin, options], [constantFolding.plugin, options]];
|
||||
|
||||
// $FlowFixMe: impossible to type a dynamic require.
|
||||
// $FlowFixMe TODO t26372934 Plugin system
|
||||
const transformer: Transformer<*> = require(transformerPath);
|
||||
|
||||
const transformerArgs = {
|
||||
|
|
|
@ -10,138 +10,153 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const {babelTypes: t} = require('../../babel-bridge');
|
||||
import typeof {types as BabelTypes} from 'babel-core';
|
||||
|
||||
const importMap = new Map([['ReactNative', 'react-native']]);
|
||||
|
||||
const isPlatformNode = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
isPlatformOS(node, scope, isWrappedModule) ||
|
||||
isReactPlatformOS(node, scope, isWrappedModule) ||
|
||||
isPlatformOSOS(node, scope, isWrappedModule);
|
||||
function createInlinePlatformChecks(t: BabelTypes) {
|
||||
const isPlatformNode = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
isPlatformOS(node, scope, isWrappedModule) ||
|
||||
isReactPlatformOS(node, scope, isWrappedModule) ||
|
||||
isPlatformOSOS(node, scope, isWrappedModule);
|
||||
|
||||
const isPlatformSelectNode = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
isPlatformSelect(node, scope, isWrappedModule) ||
|
||||
isReactPlatformSelect(node, scope, isWrappedModule);
|
||||
const isPlatformSelectNode = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
isPlatformSelect(node, scope, isWrappedModule) ||
|
||||
isReactPlatformSelect(node, scope, isWrappedModule);
|
||||
|
||||
const isPlatformOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
isImportOrGlobal(node.object, scope, [{name: 'Platform'}], isWrappedModule);
|
||||
const isPlatformOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
isImportOrGlobal(node.object, scope, [{name: 'Platform'}], isWrappedModule);
|
||||
|
||||
const isReactPlatformOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
t.isMemberExpression(node.object) &&
|
||||
t.isIdentifier(node.object.property, {name: 'Platform'}) &&
|
||||
isImportOrGlobal(
|
||||
node.object.object,
|
||||
scope,
|
||||
[{name: 'React'}, {name: 'ReactNative'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isPlatformOSOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
isImportOrGlobal(node.object, scope, [{name: 'PlatformOS'}], isWrappedModule);
|
||||
|
||||
const isPlatformSelect = (node, scope, isWrappedModule) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.object, {name: 'Platform'}) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object,
|
||||
scope,
|
||||
[{name: 'Platform'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isReactPlatformSelect = (node, scope, isWrappedModule) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
t.isMemberExpression(node.callee.object) &&
|
||||
t.isIdentifier(node.callee.object.property, {name: 'Platform'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object.object,
|
||||
scope,
|
||||
[{name: 'React'}, {name: 'ReactNative'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isPlatformOSSelect = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.object, {name: 'PlatformOS'}) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object,
|
||||
scope,
|
||||
[{name: 'PlatformOS'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const getReplacementForPlatformOSSelect = (node: Object, platform: string) => {
|
||||
const matchingProperty = node.arguments[0].properties.find(
|
||||
p => p.key.name === platform,
|
||||
);
|
||||
|
||||
if (!matchingProperty) {
|
||||
throw new Error(
|
||||
'No matching property was found for PlatformOS.select:\n' +
|
||||
JSON.stringify(node),
|
||||
const isReactPlatformOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
t.isMemberExpression(node.object) &&
|
||||
t.isIdentifier(node.object.property, {name: 'Platform'}) &&
|
||||
isImportOrGlobal(
|
||||
node.object.object,
|
||||
scope,
|
||||
[{name: 'React'}, {name: 'ReactNative'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
}
|
||||
return matchingProperty.value;
|
||||
};
|
||||
|
||||
const isGlobal = binding => !binding;
|
||||
const isPlatformOSOS = (node, scope, isWrappedModule) =>
|
||||
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||
isImportOrGlobal(
|
||||
node.object,
|
||||
scope,
|
||||
[{name: 'PlatformOS'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isRequireCall = (node, dependencyId, scope) =>
|
||||
t.isCallExpression(node) &&
|
||||
t.isIdentifier(node.callee, {name: 'require'}) &&
|
||||
checkRequireArgs(node.arguments, dependencyId);
|
||||
const isPlatformSelect = (node, scope, isWrappedModule) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.object, {name: 'Platform'}) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object,
|
||||
scope,
|
||||
[{name: 'Platform'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isImport = (node, scope, patterns) =>
|
||||
patterns.some(pattern => {
|
||||
const importName = importMap.get(pattern.name) || pattern.name;
|
||||
return isRequireCall(node, importName, scope);
|
||||
});
|
||||
const isReactPlatformSelect = (node, scope, isWrappedModule) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
t.isMemberExpression(node.callee.object) &&
|
||||
t.isIdentifier(node.callee.object.property, {name: 'Platform'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object.object,
|
||||
scope,
|
||||
[{name: 'React'}, {name: 'ReactNative'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isImportOrGlobal = (node, scope, patterns, isWrappedModule) => {
|
||||
const identifier = patterns.find(pattern => t.isIdentifier(node, pattern));
|
||||
return (
|
||||
(identifier &&
|
||||
isToplevelBinding(scope.getBinding(identifier.name), isWrappedModule)) ||
|
||||
isImport(node, scope, patterns)
|
||||
);
|
||||
};
|
||||
const isPlatformOSSelect = (
|
||||
node: Object,
|
||||
scope: Object,
|
||||
isWrappedModule: boolean,
|
||||
) =>
|
||||
t.isMemberExpression(node.callee) &&
|
||||
t.isIdentifier(node.callee.object, {name: 'PlatformOS'}) &&
|
||||
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object,
|
||||
scope,
|
||||
[{name: 'PlatformOS'}],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const checkRequireArgs = (args, dependencyId) => {
|
||||
const pattern = t.stringLiteral(dependencyId);
|
||||
return (
|
||||
t.isStringLiteral(args[0], pattern) ||
|
||||
(t.isMemberExpression(args[0]) &&
|
||||
t.isNumericLiteral(args[0].property) &&
|
||||
t.isStringLiteral(args[1], pattern))
|
||||
);
|
||||
};
|
||||
const getReplacementForPlatformOSSelect = (
|
||||
node: Object,
|
||||
platform: string,
|
||||
) => {
|
||||
const matchingProperty = node.arguments[0].properties.find(
|
||||
p => p.key.name === platform,
|
||||
);
|
||||
|
||||
const isToplevelBinding = (binding, isWrappedModule) =>
|
||||
isGlobal(binding) ||
|
||||
!binding.scope.parent ||
|
||||
(isWrappedModule && !binding.scope.parent.parent);
|
||||
if (!matchingProperty) {
|
||||
throw new Error(
|
||||
'No matching property was found for PlatformOS.select:\n' +
|
||||
JSON.stringify(node),
|
||||
);
|
||||
}
|
||||
return matchingProperty.value;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
isPlatformNode,
|
||||
isPlatformSelectNode,
|
||||
isPlatformOSSelect,
|
||||
getReplacementForPlatformOSSelect,
|
||||
};
|
||||
const isGlobal = binding => !binding;
|
||||
|
||||
const isRequireCall = (node, dependencyId, scope) =>
|
||||
t.isCallExpression(node) &&
|
||||
t.isIdentifier(node.callee, {name: 'require'}) &&
|
||||
checkRequireArgs(node.arguments, dependencyId);
|
||||
|
||||
const isImport = (node, scope, patterns) =>
|
||||
patterns.some(pattern => {
|
||||
const importName = importMap.get(pattern.name) || pattern.name;
|
||||
return isRequireCall(node, importName, scope);
|
||||
});
|
||||
|
||||
const isImportOrGlobal = (node, scope, patterns, isWrappedModule) => {
|
||||
const identifier = patterns.find(pattern => t.isIdentifier(node, pattern));
|
||||
return (
|
||||
(identifier &&
|
||||
isToplevelBinding(
|
||||
scope.getBinding(identifier.name),
|
||||
isWrappedModule,
|
||||
)) ||
|
||||
isImport(node, scope, patterns)
|
||||
);
|
||||
};
|
||||
|
||||
const checkRequireArgs = (args, dependencyId) => {
|
||||
const pattern = t.stringLiteral(dependencyId);
|
||||
return (
|
||||
t.isStringLiteral(args[0], pattern) ||
|
||||
(t.isMemberExpression(args[0]) &&
|
||||
t.isNumericLiteral(args[0].property) &&
|
||||
t.isStringLiteral(args[1], pattern))
|
||||
);
|
||||
};
|
||||
|
||||
const isToplevelBinding = (binding, isWrappedModule) =>
|
||||
isGlobal(binding) ||
|
||||
!binding.scope.parent ||
|
||||
(isWrappedModule && !binding.scope.parent.parent);
|
||||
|
||||
return {
|
||||
isPlatformNode,
|
||||
isPlatformSelectNode,
|
||||
isPlatformOSSelect,
|
||||
getReplacementForPlatformOSSelect,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = createInlinePlatformChecks;
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const createInlinePlatformChecks = require('./inline-platform');
|
||||
|
||||
import typeof {types as BabelTypes} from 'babel-core';
|
||||
import type {Ast} from 'babel-core';
|
||||
|
||||
type Context = {types: BabelTypes};
|
||||
|
||||
const env = {name: 'env'};
|
||||
const nodeEnv = {name: 'NODE_ENV'};
|
||||
const processId = {name: 'process'};
|
||||
|
||||
const dev = {name: '__DEV__'};
|
||||
|
||||
function inlinePlugin(context: Context) {
|
||||
const t = context.types;
|
||||
|
||||
const {
|
||||
isPlatformNode,
|
||||
isPlatformSelectNode,
|
||||
isPlatformOSSelect,
|
||||
getReplacementForPlatformOSSelect,
|
||||
} = createInlinePlatformChecks(t);
|
||||
|
||||
const isGlobal = binding => !binding;
|
||||
|
||||
const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
||||
|
||||
const isGlobalOrFlowDeclared = binding =>
|
||||
isGlobal(binding) || isFlowDeclared(binding);
|
||||
|
||||
const isLeftHandSideOfAssignmentExpression = (node: Ast, parent) =>
|
||||
t.isAssignmentExpression(parent) && parent.left === node;
|
||||
|
||||
const isProcessEnvNodeEnv = (node: Ast, scope) =>
|
||||
t.isIdentifier(node.property, nodeEnv) &&
|
||||
t.isMemberExpression(node.object) &&
|
||||
t.isIdentifier(node.object.property, env) &&
|
||||
t.isIdentifier(node.object.object, processId) &&
|
||||
isGlobal(scope.getBinding(processId.name));
|
||||
|
||||
const isDev = (node: Ast, parent, scope) =>
|
||||
t.isIdentifier(node, dev) &&
|
||||
isGlobalOrFlowDeclared(scope.getBinding(dev.name)) &&
|
||||
!t.isMemberExpression(parent);
|
||||
|
||||
function findProperty(objectExpression, key, fallback) {
|
||||
const property = objectExpression.properties.find(p => {
|
||||
if (t.isIdentifier(p.key) && p.key.name === key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isStringLiteral(p.key) && p.key.value === key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
return property ? property.value : fallback();
|
||||
}
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
Identifier(path: Object, state: Object) {
|
||||
if (isDev(path.node, path.parent, path.scope)) {
|
||||
path.replaceWith(t.booleanLiteral(state.opts.dev));
|
||||
}
|
||||
},
|
||||
MemberExpression(path: Object, state: Object) {
|
||||
const node = path.node;
|
||||
const scope = path.scope;
|
||||
const opts = state.opts;
|
||||
|
||||
if (!isLeftHandSideOfAssignmentExpression(node, path.parent)) {
|
||||
if (isPlatformNode(node, scope, opts.isWrapped)) {
|
||||
path.replaceWith(t.stringLiteral(opts.platform));
|
||||
} else if (isProcessEnvNodeEnv(node, scope)) {
|
||||
path.replaceWith(
|
||||
t.stringLiteral(opts.dev ? 'development' : 'production'),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
CallExpression(path: Object, state: Object) {
|
||||
const node = path.node;
|
||||
const scope = path.scope;
|
||||
const arg = node.arguments[0];
|
||||
const opts = state.opts;
|
||||
|
||||
if (isPlatformSelectNode(node, scope, opts.isWrapped)) {
|
||||
const fallback = () =>
|
||||
findProperty(arg, 'default', () => t.identifier('undefined'));
|
||||
const replacement = t.isObjectExpression(arg)
|
||||
? findProperty(arg, opts.platform, fallback)
|
||||
: node;
|
||||
|
||||
path.replaceWith(replacement);
|
||||
} else if (isPlatformOSSelect(node, scope, opts.isWrapped)) {
|
||||
path.replaceWith(
|
||||
getReplacementForPlatformOSSelect(node, opts.platform),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = inlinePlugin;
|
|
@ -1,147 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const inlinePlatform = require('./inline-platform');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
const {transformSync} = require('../../babel-bridge');
|
||||
const {transformFromAstSync} = require('../../babel-bridge');
|
||||
const {babelTypes: t} = require('../../babel-bridge');
|
||||
|
||||
import type {Ast} from '@babel/core';
|
||||
import type {BabelSourceMap} from '@babel/core';
|
||||
|
||||
const env = {name: 'env'};
|
||||
const nodeEnv = {name: 'NODE_ENV'};
|
||||
const processId = {name: 'process'};
|
||||
|
||||
const dev = {name: '__DEV__'};
|
||||
|
||||
const isGlobal = binding => !binding;
|
||||
|
||||
const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
||||
|
||||
const isGlobalOrFlowDeclared = binding =>
|
||||
isGlobal(binding) || isFlowDeclared(binding);
|
||||
|
||||
const isLeftHandSideOfAssignmentExpression = (node, parent) =>
|
||||
t.isAssignmentExpression(parent) && parent.left === node;
|
||||
|
||||
const isProcessEnvNodeEnv = (node, scope) =>
|
||||
t.isIdentifier(node.property, nodeEnv) &&
|
||||
t.isMemberExpression(node.object) &&
|
||||
t.isIdentifier(node.object.property, env) &&
|
||||
t.isIdentifier(node.object.object, processId) &&
|
||||
isGlobal(scope.getBinding(processId.name));
|
||||
|
||||
const isDev = (node, parent, scope) =>
|
||||
t.isIdentifier(node, dev) &&
|
||||
isGlobalOrFlowDeclared(scope.getBinding(dev.name)) &&
|
||||
!t.isMemberExpression(parent);
|
||||
|
||||
function findProperty(objectExpression, key, fallback) {
|
||||
const property = objectExpression.properties.find(p => {
|
||||
if (t.isIdentifier(p.key) && p.key.name === key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isStringLiteral(p.key) && p.key.value === key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
return property ? property.value : fallback();
|
||||
}
|
||||
|
||||
const inlinePlugin = {
|
||||
visitor: {
|
||||
Identifier(path, state) {
|
||||
if (isDev(path.node, path.parent, path.scope)) {
|
||||
path.replaceWith(t.booleanLiteral(state.opts.dev));
|
||||
}
|
||||
},
|
||||
MemberExpression(path, state) {
|
||||
const node = path.node;
|
||||
const scope = path.scope;
|
||||
const opts = state.opts;
|
||||
|
||||
if (!isLeftHandSideOfAssignmentExpression(node, path.parent)) {
|
||||
if (inlinePlatform.isPlatformNode(node, scope, opts.isWrapped)) {
|
||||
path.replaceWith(t.stringLiteral(opts.platform));
|
||||
} else if (isProcessEnvNodeEnv(node, scope)) {
|
||||
path.replaceWith(
|
||||
t.stringLiteral(opts.dev ? 'development' : 'production'),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
CallExpression(path, state) {
|
||||
const node = path.node;
|
||||
const scope = path.scope;
|
||||
const arg = node.arguments[0];
|
||||
const opts = state.opts;
|
||||
|
||||
if (inlinePlatform.isPlatformSelectNode(node, scope, opts.isWrapped)) {
|
||||
const fallback = () =>
|
||||
findProperty(arg, 'default', () => t.identifier('undefined'));
|
||||
const replacement = t.isObjectExpression(arg)
|
||||
? findProperty(arg, opts.platform, fallback)
|
||||
: node;
|
||||
|
||||
path.replaceWith(replacement);
|
||||
} else if (
|
||||
inlinePlatform.isPlatformOSSelect(node, scope, opts.isWrapped)
|
||||
) {
|
||||
path.replaceWith(
|
||||
inlinePlatform.getReplacementForPlatformOSSelect(node, opts.platform),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const plugin = () => inlinePlugin;
|
||||
|
||||
type AstResult = {
|
||||
ast: Ast,
|
||||
code: ?string,
|
||||
map: ?BabelSourceMap,
|
||||
};
|
||||
|
||||
function inline(
|
||||
filename: string,
|
||||
transformResult: {ast?: ?Ast, code: string, map: ?BabelSourceMap},
|
||||
options: {+dev: boolean, +platform: ?string},
|
||||
): AstResult {
|
||||
const code = transformResult.code;
|
||||
const babelOptions = {
|
||||
filename,
|
||||
plugins: [[plugin, options]],
|
||||
inputSourceMap: transformResult.map,
|
||||
sourceMaps: true,
|
||||
sourceFileName: filename,
|
||||
code: false,
|
||||
babelrc: false,
|
||||
compact: true,
|
||||
};
|
||||
|
||||
const result = transformResult.ast
|
||||
? transformFromAstSync(transformResult.ast, code, babelOptions)
|
||||
: transformSync(code, babelOptions);
|
||||
const {ast} = result;
|
||||
invariant(ast != null, 'Missing AST in babel transform results.');
|
||||
return {ast, code: result.code, map: result.map};
|
||||
}
|
||||
|
||||
inline.plugin = inlinePlugin;
|
||||
module.exports = inline;
|
|
@ -14,18 +14,18 @@ const constantFolding = require('../../JSTransformer/worker/constant-folding')
|
|||
.plugin;
|
||||
const generate = require('./generate');
|
||||
const getMinifier = require('../../lib/getMinifier');
|
||||
const inline = require('../../JSTransformer/worker/inline').plugin;
|
||||
const inlinePlugin = require('../../JSTransformer/worker/inline-plugin');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const optimizeDependencies = require('./optimizeDependencies');
|
||||
const sourceMap = require('source-map');
|
||||
|
||||
const {transformSync} = require('../../babel-bridge');
|
||||
|
||||
import type {PostMinifyProcess} from '../../Bundler/index.js';
|
||||
import type {TransformedSourceFile, TransformResult} from '../types.flow';
|
||||
import type {BabelSourceMap} from '@babel/core';
|
||||
import type {MetroSourceMap} from 'metro-source-map';
|
||||
import type {PostMinifyProcess} from '../../Bundler/index.js';
|
||||
import type {TransformResult as BabelTransformResult} from '@babel/core';
|
||||
import type {MetroSourceMap} from 'metro-source-map';
|
||||
|
||||
export type OptimizationOptions = {|
|
||||
dev: boolean,
|
||||
|
@ -118,7 +118,7 @@ function optimizeCode(
|
|||
return transformSync(code, {
|
||||
plugins: [
|
||||
[constantFolding],
|
||||
[inline, {...inliningOptions, isWrapped: true}],
|
||||
[inlinePlugin, {...inliningOptions, isWrapped: true}],
|
||||
],
|
||||
babelrc: false,
|
||||
code: false,
|
||||
|
|
Loading…
Reference in New Issue