mirror of https://github.com/status-im/metro.git
@format JSTransformer
Reviewed By: jeanlauliac Differential Revision: D5208868 fbshipit-source-id: 3b80197c4e879974f9129ccfc4e4a7ca7d4b4258
This commit is contained in:
parent
5e6d70d4d6
commit
802094c6f0
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -34,48 +36,68 @@ describe('Transformer', function() {
|
|||
fs.writeFileSync.mockClear();
|
||||
workerFarm.mockClear();
|
||||
workerFarm.mockImplementation((opts, path, methods) => {
|
||||
const api = workers = {};
|
||||
methods.forEach(method => {api[method] = jest.fn();});
|
||||
return {methods: api, stdout: new Readable({read() {}}), stderr: new Readable({read() {}})};
|
||||
const api = (workers = {});
|
||||
methods.forEach(method => {
|
||||
api[method] = jest.fn();
|
||||
});
|
||||
return {
|
||||
methods: api,
|
||||
stdout: new Readable({read() {}}),
|
||||
stderr: new Readable({read() {}}),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
it('passes transform module path, file path, source code' +
|
||||
' to the worker farm when transforming', () => {
|
||||
const transformOptions = {arbitrary: 'options'};
|
||||
const code = 'arbitrary(code)';
|
||||
new Transformer(transformModulePath).transformFile(fileName, localPath, code, transformOptions);
|
||||
expect(workers.transformAndExtractDependencies).toBeCalledWith(
|
||||
transformModulePath,
|
||||
fileName,
|
||||
localPath,
|
||||
code,
|
||||
transformOptions,
|
||||
any(Function),
|
||||
);
|
||||
});
|
||||
it(
|
||||
'passes transform module path, file path, source code' +
|
||||
' to the worker farm when transforming',
|
||||
() => {
|
||||
const transformOptions = {arbitrary: 'options'};
|
||||
const code = 'arbitrary(code)';
|
||||
new Transformer(transformModulePath).transformFile(
|
||||
fileName,
|
||||
localPath,
|
||||
code,
|
||||
transformOptions,
|
||||
);
|
||||
expect(workers.transformAndExtractDependencies).toBeCalledWith(
|
||||
transformModulePath,
|
||||
fileName,
|
||||
localPath,
|
||||
code,
|
||||
transformOptions,
|
||||
any(Function),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it('should add file info to parse errors', function() {
|
||||
const transformer = new Transformer(transformModulePath);
|
||||
var message = 'message';
|
||||
var snippet = 'snippet';
|
||||
|
||||
workers.transformAndExtractDependencies.mockImplementation(
|
||||
function(transformPath, filename, localPth, code, opts, callback) {
|
||||
var babelError = new SyntaxError(message);
|
||||
babelError.type = 'SyntaxError';
|
||||
babelError.description = message;
|
||||
babelError.loc = {
|
||||
line: 2,
|
||||
column: 15,
|
||||
};
|
||||
babelError.codeFrame = snippet;
|
||||
callback(babelError);
|
||||
},
|
||||
);
|
||||
workers.transformAndExtractDependencies.mockImplementation(function(
|
||||
transformPath,
|
||||
filename,
|
||||
localPth,
|
||||
code,
|
||||
opts,
|
||||
callback,
|
||||
) {
|
||||
var babelError = new SyntaxError(message);
|
||||
babelError.type = 'SyntaxError';
|
||||
babelError.description = message;
|
||||
babelError.loc = {
|
||||
line: 2,
|
||||
column: 15,
|
||||
};
|
||||
babelError.codeFrame = snippet;
|
||||
callback(babelError);
|
||||
});
|
||||
|
||||
expect.assertions(7);
|
||||
return transformer.transformFile(fileName, localPath, '', {})
|
||||
return transformer
|
||||
.transformFile(fileName, localPath, '', {})
|
||||
.catch(function(error) {
|
||||
expect(error.type).toEqual('TransformError');
|
||||
expect(error.message).toBe('SyntaxError ' + message);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -23,12 +24,18 @@ const workerFarm = require('../worker-farm');
|
|||
import type {Data as TransformData, Options as WorkerOptions} from './worker';
|
||||
import type {LocalPath} from '../node-haste/lib/toLocalPath';
|
||||
import type {MappingsMap} from '../lib/SourceMap';
|
||||
import typeof {minify as Minify, transformAndExtractDependencies as TransformAndExtractDependencies} from './worker';
|
||||
import typeof {
|
||||
minify as Minify,
|
||||
transformAndExtractDependencies as TransformAndExtractDependencies,
|
||||
} from './worker';
|
||||
|
||||
type CB<T> = (?Error, ?T) => mixed;
|
||||
type Denodeify =
|
||||
& (<A, B, C, T>((A, B, C, CB<T>) => void) => (A, B, C) => Promise<T>)
|
||||
& (<A, B, C, D, E, T>((A, B, C, D, E, CB<T>) => void) => (A, B, C, D, E) => Promise<T>);
|
||||
type Denodeify = (<A, B, C, T>(
|
||||
(A, B, C, CB<T>) => void,
|
||||
) => (A, B, C) => Promise<T>) &
|
||||
(<A, B, C, D, E, T>(
|
||||
(A, B, C, D, E, CB<T>) => void,
|
||||
) => (A, B, C, D, E) => Promise<T>);
|
||||
|
||||
// Avoid memory leaks caused in workers. This number seems to be a good enough number
|
||||
// to avoid any memory leak while not slowing down initial builds.
|
||||
|
@ -63,7 +70,6 @@ type Reporters = {
|
|||
};
|
||||
|
||||
class Transformer {
|
||||
|
||||
_workers: {[name: string]: Function};
|
||||
_transformModulePath: string;
|
||||
_transform: (
|
||||
|
@ -85,7 +91,10 @@ class Transformer {
|
|||
reporters: Reporters,
|
||||
workerPath: ?string,
|
||||
) {
|
||||
invariant(path.isAbsolute(transformModulePath), 'transform module path should be absolute');
|
||||
invariant(
|
||||
path.isAbsolute(transformModulePath),
|
||||
'transform module path should be absolute',
|
||||
);
|
||||
this._transformModulePath = transformModulePath;
|
||||
|
||||
const farm = makeFarm(
|
||||
|
@ -102,7 +111,10 @@ class Transformer {
|
|||
});
|
||||
|
||||
this._workers = farm.methods;
|
||||
this._transform = denodeify((this._workers.transformAndExtractDependencies: TransformAndExtractDependencies));
|
||||
this._transform = denodeify(
|
||||
(this._workers
|
||||
.transformAndExtractDependencies: TransformAndExtractDependencies),
|
||||
);
|
||||
this.minify = denodeify((this._workers.minify: Minify));
|
||||
}
|
||||
|
||||
|
@ -114,19 +126,19 @@ class Transformer {
|
|||
fileName: string,
|
||||
localPath: LocalPath,
|
||||
code: string,
|
||||
options: WorkerOptions) {
|
||||
options: WorkerOptions,
|
||||
) {
|
||||
if (!this._transform) {
|
||||
return Promise.reject(new Error('No transform module'));
|
||||
}
|
||||
debug('transforming file', fileName);
|
||||
return this
|
||||
._transform(
|
||||
this._transformModulePath,
|
||||
fileName,
|
||||
localPath,
|
||||
code,
|
||||
options,
|
||||
)
|
||||
return this._transform(
|
||||
this._transformModulePath,
|
||||
fileName,
|
||||
localPath,
|
||||
code,
|
||||
options,
|
||||
)
|
||||
.then(data => {
|
||||
Logger.log(data.transformFileStartLogEntry);
|
||||
Logger.log(data.transformFileEndLogEntry);
|
||||
|
@ -137,8 +149,8 @@ class Transformer {
|
|||
if (error.type === 'TimeoutError') {
|
||||
const timeoutErr = new Error(
|
||||
`TimeoutError: transforming ${fileName} took longer than ` +
|
||||
`${TRANSFORM_TIMEOUT_INTERVAL / 1000} seconds.\n` +
|
||||
'You can adjust timeout via the \'transformTimeoutInterval\' option'
|
||||
`${TRANSFORM_TIMEOUT_INTERVAL / 1000} seconds.\n` +
|
||||
"You can adjust timeout via the 'transformTimeoutInterval' option",
|
||||
);
|
||||
/* $FlowFixMe: monkey-patch Error */
|
||||
timeoutErr.type = 'TimeoutError';
|
||||
|
@ -146,7 +158,7 @@ class Transformer {
|
|||
} else if (error.type === 'ProcessTerminatedError') {
|
||||
const uncaughtError = new Error(
|
||||
'Uncaught error in the transformer worker: ' +
|
||||
this._transformModulePath
|
||||
this._transformModulePath,
|
||||
);
|
||||
/* $FlowFixMe: monkey-patch Error */
|
||||
uncaughtError.type = 'ProcessTerminatedError';
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -38,18 +40,19 @@ describe('constant expressions', () => {
|
|||
'foo'==='bar' ? b : c,
|
||||
f() ? g() : h()
|
||||
);`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('a(true,true,2,true,{},{a:1},c,f()?g():h());');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
'a(true,true,2,true,{},{a:1},c,f()?g():h());',
|
||||
);
|
||||
});
|
||||
|
||||
it('can optimize ternary expressions with constant conditions', () => {
|
||||
const code =
|
||||
`var a = true ? 1 : 2;
|
||||
const code = `var a = true ? 1 : 2;
|
||||
var b = 'android' == 'android'
|
||||
? ('production' != 'production' ? 'a' : 'A')
|
||||
: 'i';`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('var a=1;var b=\'A\';');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
"var a=1;var b='A';",
|
||||
);
|
||||
});
|
||||
|
||||
it('can optimize logical operator expressions with constant conditions', () => {
|
||||
|
@ -57,8 +60,9 @@ describe('constant expressions', () => {
|
|||
var a = true || 1;
|
||||
var b = 'android' == 'android' &&
|
||||
'production' != 'production' || null || "A";`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('var a=true;var b="A";');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
'var a=true;var b="A";',
|
||||
);
|
||||
});
|
||||
|
||||
it('can optimize logical operators with partly constant operands', () => {
|
||||
|
@ -69,8 +73,9 @@ describe('constant expressions', () => {
|
|||
var d = null || z();
|
||||
var e = !1 && z();
|
||||
`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('var a="truthy";var b=z();var c=null;var d=z();var e=false;');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
'var a="truthy";var b=z();var c=null;var d=z();var e=false;',
|
||||
);
|
||||
});
|
||||
|
||||
it('can remode an if statement with a falsy constant test', () => {
|
||||
|
@ -79,8 +84,7 @@ describe('constant expressions', () => {
|
|||
var a = 1;
|
||||
}
|
||||
`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual('');
|
||||
});
|
||||
|
||||
it('can optimize if-else-branches with constant conditions', () => {
|
||||
|
@ -95,8 +99,9 @@ describe('constant expressions', () => {
|
|||
var a = 'b';
|
||||
}
|
||||
`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('{var a=3;var b=a+4;}');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
'{var a=3;var b=a+4;}',
|
||||
);
|
||||
});
|
||||
|
||||
it('can optimize nested if-else constructs', () => {
|
||||
|
@ -115,7 +120,8 @@ describe('constant expressions', () => {
|
|||
}
|
||||
}
|
||||
`;
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code))))
|
||||
.toEqual('{{require(\'c\');}}');
|
||||
expect(normalize(constantFolding('arbitrary.js', parse(code)))).toEqual(
|
||||
"{{require('c');}}",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -22,8 +24,7 @@ describe('Dependency extraction:', () => {
|
|||
require
|
||||
('more');`;
|
||||
const {dependencies, dependencyOffsets} = extractDependencies(code);
|
||||
expect(dependencies)
|
||||
.toEqual(['foo/bar', 'React', 'Component', 'more']);
|
||||
expect(dependencies).toEqual(['foo/bar', 'React', 'Component', 'more']);
|
||||
expect(dependencyOffsets).toEqual([8, 46, 147, 203]);
|
||||
});
|
||||
|
||||
|
@ -76,7 +77,7 @@ describe('Dependency extraction:', () => {
|
|||
});
|
||||
|
||||
it('does not extract calls to function with names that start with "require"', () => {
|
||||
const code = 'arbitraryrequire(\'foo\');';
|
||||
const code = "arbitraryrequire('foo');";
|
||||
|
||||
const {dependencies, dependencyOffsets} = extractDependencies(code);
|
||||
expect(dependencies).toEqual([]);
|
||||
|
@ -84,7 +85,7 @@ describe('Dependency extraction:', () => {
|
|||
});
|
||||
|
||||
it('does not extract calls to require with non-static arguments', () => {
|
||||
const code = 'require(\'foo/\' + bar)';
|
||||
const code = "require('foo/' + bar)";
|
||||
|
||||
const {dependencies, dependencyOffsets} = extractDependencies(code);
|
||||
expect(dependencies).toEqual([]);
|
||||
|
@ -101,7 +102,7 @@ describe('Dependency extraction:', () => {
|
|||
});
|
||||
|
||||
it('can handle regular expressions', () => {
|
||||
const code = 'require(\'a\'); /["\']/.test(\'foo\'); require("b");';
|
||||
const code = "require('a'); /[\"']/.test('foo'); require(\"b\");";
|
||||
|
||||
const {dependencies, dependencyOffsets} = extractDependencies(code);
|
||||
expect(dependencies).toEqual(['a', 'b']);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -47,7 +49,9 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces Platform.OS in the code if Platform is a top level import', () => {
|
||||
|
@ -58,7 +62,9 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces Platform.OS in the code if Platform is a top level import from react-native', () => {
|
||||
|
@ -69,7 +75,9 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces require("Platform").OS in the code', () => {
|
||||
|
@ -79,7 +87,8 @@ describe('inline constants', () => {
|
|||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\('Platform'\)\.OS/, '"android"')));
|
||||
normalize(code.replace(/require\('Platform'\)\.OS/, '"android"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces React.Platform.OS in the code if React is a global', () => {
|
||||
|
@ -88,7 +97,9 @@ describe('inline constants', () => {
|
|||
var b = a.React.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/React\.Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/React\.Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces ReactNative.Platform.OS in the code if ReactNative is a global', () => {
|
||||
|
@ -97,7 +108,9 @@ describe('inline constants', () => {
|
|||
var b = a.ReactNative.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/ReactNative\.Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/ReactNative\.Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces React.Platform.OS in the code if React is a top level import', () => {
|
||||
|
@ -108,7 +121,9 @@ describe('inline constants', () => {
|
|||
var b = a.React.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/React.Platform\.OS/, '"ios"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/React.Platform\.OS/, '"ios"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces require("React").Platform.OS in the code', () => {
|
||||
|
@ -118,7 +133,8 @@ describe('inline constants', () => {
|
|||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\('React'\)\.Platform\.OS/, '"android"')));
|
||||
normalize(code.replace(/require\('React'\)\.Platform\.OS/, '"android"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces ReactNative.Platform.OS in the code if ReactNative is a top level import', () => {
|
||||
|
@ -129,7 +145,9 @@ describe('inline constants', () => {
|
|||
var b = a.ReactNative.Platform.OS;
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/ReactNative.Platform\.OS/, '"android"')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/ReactNative.Platform\.OS/, '"android"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces require("react-native").Platform.OS in the code', () => {
|
||||
|
@ -139,7 +157,10 @@ describe('inline constants', () => {
|
|||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\('react-native'\)\.Platform\.OS/, '"android"')));
|
||||
normalize(
|
||||
code.replace(/require\('react-native'\)\.Platform\.OS/, '"android"'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('inlines Platform.select in the code if Platform is a global and the argument is an object literal', () => {
|
||||
|
@ -148,16 +169,20 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.select({ios: 1, android: 2});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.select[^;]+/, '1')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, '1')),
|
||||
);
|
||||
});
|
||||
|
||||
it('inlines Platform.select in the code if Platform is a global and the argument doesn\'t have target platform in it\'s keys', () => {
|
||||
it("inlines Platform.select in the code if Platform is a global and the argument doesn't have target platform in it's keys", () => {
|
||||
const code = `function a() {
|
||||
var a = Platform.select({ios: 1, default: 2});
|
||||
var b = a.Platform.select({ios: 1, default: 2});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.select[^;]+/, '2')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, '2')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces Platform.select in the code if Platform is a top level import', () => {
|
||||
|
@ -168,7 +193,9 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.select({});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.select[^;]+/, '2')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, '2')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces Platform.select in the code if Platform is a top level import from react-native', () => {
|
||||
|
@ -179,7 +206,9 @@ describe('inline constants', () => {
|
|||
var b = a.Platform.select({});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.select[^;]+/, '1')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, '1')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces require("Platform").select in the code', () => {
|
||||
|
@ -188,7 +217,9 @@ describe('inline constants', () => {
|
|||
var b = a.require('Platform').select({});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/Platform\.select[^;]+/, '2')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, '2')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces React.Platform.select in the code if React is a global', () => {
|
||||
|
@ -197,7 +228,9 @@ describe('inline constants', () => {
|
|||
var b = a.React.Platform.select({});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/React\.Platform\.select[^;]+/, '1')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/React\.Platform\.select[^;]+/, '1')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces ReactNative.Platform.select in the code if ReactNative is a global', () => {
|
||||
|
@ -219,7 +252,9 @@ describe('inline constants', () => {
|
|||
var b = a.React.Platform.select({});
|
||||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'ios'});
|
||||
expect(toString(ast)).toEqual(normalize(code.replace(/React\.Platform\.select[^;]+/, '1')));
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/React\.Platform\.select[^;]+/, '1')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces require("React").Platform.select in the code', () => {
|
||||
|
@ -229,7 +264,8 @@ describe('inline constants', () => {
|
|||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\('React'\)\.Platform\.select[^;]+/, '2')));
|
||||
normalize(code.replace(/require\('React'\)\.Platform\.select[^;]+/, '2')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces ReactNative.Platform.select in the code if ReactNative is a top level import', () => {
|
||||
|
@ -252,14 +288,18 @@ describe('inline constants', () => {
|
|||
`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'android'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\('react-native'\)\.Platform\.select[^;]+/, '2')));
|
||||
normalize(
|
||||
code.replace(/require\('react-native'\)\.Platform\.select[^;]+/, '2'),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces non-existing properties with `undefined`', () => {
|
||||
const code = 'var a = Platform.select({ios: 1, android: 2})';
|
||||
const {ast} = inline('arbitrary.js', {code}, {platform: 'doesnotexist'});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/Platform\.select[^;]+/, 'undefined')));
|
||||
normalize(code.replace(/Platform\.select[^;]+/, 'undefined')),
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces process.env.NODE_ENV in the code', () => {
|
||||
|
@ -271,7 +311,8 @@ describe('inline constants', () => {
|
|||
}`;
|
||||
const {ast} = inline('arbitrary.js', {code}, {dev: false});
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/process\.env\.NODE_ENV/, '"production"')));
|
||||
normalize(code.replace(/process\.env\.NODE_ENV/, '"production"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts an AST as input', function() {
|
||||
|
@ -286,13 +327,16 @@ describe('inline constants', () => {
|
|||
var a = Platform.OS, b = Platform.select({android: 1, ios: 2});
|
||||
});`;
|
||||
const {ast} = inline(
|
||||
'arbitrary', {code}, {dev: true, platform: 'android', isWrapped: true});
|
||||
'arbitrary',
|
||||
{code},
|
||||
{dev: true, platform: 'android', isWrapped: true},
|
||||
);
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(
|
||||
code
|
||||
.replace(/Platform\.OS/, '"android"')
|
||||
.replace(/Platform\.select[^)]+\)/, 1)
|
||||
)
|
||||
.replace(/Platform\.select[^)]+\)/, 1),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -301,9 +345,13 @@ describe('inline constants', () => {
|
|||
var a = require(arbitraryMapName[123], 'react-native').Platform.OS;
|
||||
});`;
|
||||
const {ast} = inline(
|
||||
'arbitrary', {code}, {dev: true, platform: 'android', isWrapped: true});
|
||||
'arbitrary',
|
||||
{code},
|
||||
{dev: true, platform: 'android', isWrapped: true},
|
||||
);
|
||||
expect(toString(ast)).toEqual(
|
||||
normalize(code.replace(/require\([^)]+\)\.Platform\.OS/, '"android"')));
|
||||
normalize(code.replace(/require\([^)]+\)\.Platform\.OS/, '"android"')),
|
||||
);
|
||||
});
|
||||
|
||||
it('works with flow-declared variables', () => {
|
||||
|
@ -311,10 +359,10 @@ describe('inline constants', () => {
|
|||
const code = `declare var __DEV__;
|
||||
const a: boolean = __DEV__;`;
|
||||
|
||||
const transformed = transform(
|
||||
code,
|
||||
{...babelOptions, plugins: [stripFlow, [inline.plugin, {dev: false}]]},
|
||||
).code;
|
||||
const transformed = transform(code, {
|
||||
...babelOptions,
|
||||
plugins: [stripFlow, [inline.plugin, {dev: false}]],
|
||||
}).code;
|
||||
|
||||
expect(transformed).toEqual('const a=false;');
|
||||
});
|
||||
|
@ -326,10 +374,10 @@ describe('inline constants', () => {
|
|||
const a: boolean = __DEV__;
|
||||
});`;
|
||||
|
||||
const transformed = transform(
|
||||
code,
|
||||
{...babelOptions, plugins: [stripFlow, [inline.plugin, {dev: true}]]},
|
||||
).code;
|
||||
const transformed = transform(code, {
|
||||
...babelOptions,
|
||||
plugins: [stripFlow, [inline.plugin, {dev: true}]],
|
||||
}).code;
|
||||
|
||||
expect(transformed).toEqual('__d(()=>{const a=true;});');
|
||||
});
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -35,11 +37,14 @@ describe('Minification:', () => {
|
|||
|
||||
it('passes file name, code, and source map to `uglify`', () => {
|
||||
minify(filename, code, map);
|
||||
expect(uglify.minify).toBeCalledWith(code, objectContaining({
|
||||
fromString: true,
|
||||
inSourceMap: map,
|
||||
outSourceMap: true,
|
||||
}));
|
||||
expect(uglify.minify).toBeCalledWith(
|
||||
code,
|
||||
objectContaining({
|
||||
fromString: true,
|
||||
inSourceMap: map,
|
||||
outSourceMap: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the code provided by uglify', () => {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
|
@ -22,8 +24,9 @@ describe('code transformation worker:', () => {
|
|||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
({transformCode} = require('..'));
|
||||
extractDependencies =
|
||||
require('../extract-dependencies').mockReturnValue({});
|
||||
extractDependencies = require('../extract-dependencies').mockReturnValue(
|
||||
{},
|
||||
);
|
||||
transformer = {
|
||||
transform: jest.fn(({filename, options, src}) => ({
|
||||
code: src,
|
||||
|
@ -37,7 +40,14 @@ describe('code transformation worker:', () => {
|
|||
const localPath = `local/${filename}`;
|
||||
const sourceCode = 'arbitrary(code)';
|
||||
const transformOptions = {arbitrary: 'options'};
|
||||
transformCode(transformer, filename, localPath, sourceCode, {transform: transformOptions}, () => {});
|
||||
transformCode(
|
||||
transformer,
|
||||
filename,
|
||||
localPath,
|
||||
sourceCode,
|
||||
{transform: transformOptions},
|
||||
() => {},
|
||||
);
|
||||
expect(transformer.transform).toBeCalledWith({
|
||||
filename,
|
||||
localPath,
|
||||
|
@ -65,26 +75,39 @@ describe('code transformation worker:', () => {
|
|||
map: {},
|
||||
};
|
||||
|
||||
transformCode(transformer, 'filename', 'local/filename', result.code, {}, (error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result).toEqual(objectContaining(result));
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
'filename',
|
||||
'local/filename',
|
||||
result.code,
|
||||
{},
|
||||
(error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result).toEqual(objectContaining(result));
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'removes the leading assignment to `module.exports` before passing ' +
|
||||
'on the result if the file is a JSON file, even if minified',
|
||||
'on the result if the file is a JSON file, even if minified',
|
||||
done => {
|
||||
const code = '{a:1,b:2}';
|
||||
const filePath = 'arbitrary/file.json';
|
||||
transformCode(transformer, filePath, filePath, code, {}, (error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result.code).toEqual(code);
|
||||
done();
|
||||
},
|
||||
transformCode(
|
||||
transformer,
|
||||
filePath,
|
||||
filePath,
|
||||
code,
|
||||
{},
|
||||
(error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result.code).toEqual(code);
|
||||
done();
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it('removes shebang when present', done => {
|
||||
|
@ -93,13 +116,20 @@ describe('code transformation worker:', () => {
|
|||
code: `${shebang} \n arbitrary(code)`,
|
||||
};
|
||||
const filePath = 'arbitrary/file.js';
|
||||
transformCode(transformer, filePath, filePath, result.code, {}, (error, data) => {
|
||||
expect(error).toBeNull();
|
||||
const {code} = data.result;
|
||||
expect(code).not.toContain(shebang);
|
||||
expect(code.split('\n').length).toEqual(result.code.split('\n').length);
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
filePath,
|
||||
filePath,
|
||||
result.code,
|
||||
{},
|
||||
(error, data) => {
|
||||
expect(error).toBeNull();
|
||||
const {code} = data.result;
|
||||
expect(code).not.toContain(shebang);
|
||||
expect(code.split('\n').length).toEqual(result.code.split('\n').length);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('calls back with any error yielded by the transform', done => {
|
||||
|
@ -108,51 +138,78 @@ describe('code transformation worker:', () => {
|
|||
throw new Error(message);
|
||||
});
|
||||
|
||||
transformCode(transformer, 'filename', 'local/filename', 'code', {}, error => {
|
||||
expect(error.message).toBe(message);
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
'filename',
|
||||
'local/filename',
|
||||
'code',
|
||||
{},
|
||||
error => {
|
||||
expect(error.message).toBe(message);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('dependency extraction', () => {
|
||||
it('passes the transformed code the `extractDependencies`', done => {
|
||||
const code = 'arbitrary(code)';
|
||||
|
||||
transformCode(transformer, 'filename', 'local/filename', code, {}, error => {
|
||||
expect(error).toBeNull();
|
||||
expect(extractDependencies).toBeCalledWith(code);
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
'filename',
|
||||
'local/filename',
|
||||
code,
|
||||
{},
|
||||
error => {
|
||||
expect(error).toBeNull();
|
||||
expect(extractDependencies).toBeCalledWith(code);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'uses `dependencies` and `dependencyOffsets` ' +
|
||||
'provided by `extractDependencies` for the result',
|
||||
'provided by `extractDependencies` for the result',
|
||||
done => {
|
||||
const dependencyData = {
|
||||
dependencies: ['arbitrary', 'list', 'of', 'dependencies'],
|
||||
dependencyOffsets: [12, 119, 185, 328, 471],
|
||||
dependencyOffsets: [12, 119, 185, 328, 471],
|
||||
};
|
||||
extractDependencies.mockReturnValue(dependencyData);
|
||||
|
||||
transformCode(transformer, 'filename', 'local/filename', 'code', {}, (error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result).toEqual(objectContaining(dependencyData));
|
||||
done();
|
||||
});
|
||||
}
|
||||
transformCode(
|
||||
transformer,
|
||||
'filename',
|
||||
'local/filename',
|
||||
'code',
|
||||
{},
|
||||
(error, data) => {
|
||||
expect(error).toBeNull();
|
||||
expect(data.result).toEqual(objectContaining(dependencyData));
|
||||
done();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it('does not extract requires of JSON files', done => {
|
||||
const jsonStr = '{"arbitrary":"json"}';
|
||||
transformCode(transformer, 'arbitrary.json', 'local/arbitrary.json', jsonStr, {}, (error, data) => {
|
||||
expect(error).toBeNull();
|
||||
const {dependencies, dependencyOffsets} = data.result;
|
||||
expect(extractDependencies).not.toBeCalled();
|
||||
expect(dependencies).toEqual([]);
|
||||
expect(dependencyOffsets).toEqual([]);
|
||||
done();
|
||||
}
|
||||
transformCode(
|
||||
transformer,
|
||||
'arbitrary.json',
|
||||
'local/arbitrary.json',
|
||||
jsonStr,
|
||||
{},
|
||||
(error, data) => {
|
||||
expect(error).toBeNull();
|
||||
const {dependencies, dependencyOffsets} = data.result;
|
||||
expect(extractDependencies).not.toBeCalled();
|
||||
expect(dependencies).toEqual([]);
|
||||
expect(dependencyOffsets).toEqual([]);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -165,8 +222,10 @@ describe('code transformation worker:', () => {
|
|||
const foldedMap = {version: 3, sources: ['fold.js']};
|
||||
|
||||
beforeEach(() => {
|
||||
constantFolding = require('../constant-folding')
|
||||
.mockReturnValue({code: foldedCode, map: foldedMap});
|
||||
constantFolding = require('../constant-folding').mockReturnValue({
|
||||
code: foldedCode,
|
||||
map: foldedMap,
|
||||
});
|
||||
extractDependencies = require('../extract-dependencies');
|
||||
inline = require('../inline');
|
||||
|
||||
|
@ -177,9 +236,12 @@ describe('code transformation worker:', () => {
|
|||
};
|
||||
|
||||
extractDependencies.mockImplementation(
|
||||
code => code === foldedCode ? dependencyData : {});
|
||||
code => (code === foldedCode ? dependencyData : {}),
|
||||
);
|
||||
|
||||
transformer.transform.mockImplementation((src, fileName, _) => transformResult);
|
||||
transformer.transform.mockImplementation(
|
||||
(src, fileName, _) => transformResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('passes the transform result to `inline` for constant inlining', done => {
|
||||
|
@ -207,19 +269,34 @@ describe('code transformation worker:', () => {
|
|||
});
|
||||
|
||||
it('uses the dependencies obtained from the optimized result', done => {
|
||||
transformCode(transformer, filename, filename, 'code', options, (_, data) => {
|
||||
const result = data.result;
|
||||
expect(result.dependencies).toEqual(dependencyData.dependencies);
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
filename,
|
||||
filename,
|
||||
'code',
|
||||
options,
|
||||
(_, data) => {
|
||||
const result = data.result;
|
||||
expect(result.dependencies).toEqual(dependencyData.dependencies);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('uses data produced by `constant-folding` for the result', done => {
|
||||
transformCode(transformer, 'filename', 'local/filename', 'code', options, (_, data) => {
|
||||
expect(data.result)
|
||||
.toEqual(objectContaining({code: foldedCode, map: foldedMap}));
|
||||
done();
|
||||
});
|
||||
transformCode(
|
||||
transformer,
|
||||
'filename',
|
||||
'local/filename',
|
||||
'code',
|
||||
options,
|
||||
(_, data) => {
|
||||
expect(data.result).toEqual(
|
||||
objectContaining({code: foldedCode, map: foldedMap}),
|
||||
);
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -70,11 +71,14 @@ const plugin = {
|
|||
},
|
||||
};
|
||||
|
||||
function constantFolding(filename: string, transformResult: {
|
||||
ast: Ast,
|
||||
code?: ?string,
|
||||
map: ?MappingsMap,
|
||||
}) {
|
||||
function constantFolding(
|
||||
filename: string,
|
||||
transformResult: {
|
||||
ast: Ast,
|
||||
code?: ?string,
|
||||
map: ?MappingsMap,
|
||||
},
|
||||
) {
|
||||
return babel.transformFromAst(transformResult.ast, transformResult.code, {
|
||||
filename,
|
||||
plugins: [plugin],
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -41,7 +42,6 @@ export type Transformer<ExtraOptions: {} = {}> = {
|
|||
getCacheKey: () => string,
|
||||
};
|
||||
|
||||
|
||||
export type TransformOptionsStrict = {|
|
||||
+dev: boolean,
|
||||
+generateSourceMaps: boolean,
|
||||
|
@ -73,10 +73,7 @@ export type Data = {
|
|||
transformFileEndLogEntry: LogEntry,
|
||||
};
|
||||
|
||||
type Callback<T> = (
|
||||
error: ?Error,
|
||||
data: ?T,
|
||||
) => mixed;
|
||||
type Callback<T> = (error: ?Error, data: ?T) => mixed;
|
||||
|
||||
function transformCode(
|
||||
transformer: Transformer<*>,
|
||||
|
@ -124,8 +121,10 @@ function transformCode(
|
|||
|
||||
var code, map;
|
||||
if (options.minify) {
|
||||
({code, map} =
|
||||
constantFolding(filename, inline(filename, transformed, options)));
|
||||
({code, map} = constantFolding(
|
||||
filename,
|
||||
inline(filename, transformed, options),
|
||||
));
|
||||
invariant(code != null, 'Missing code from constant-folding transform.');
|
||||
} else {
|
||||
({code, map} = transformed);
|
||||
|
@ -170,7 +169,14 @@ exports.transformAndExtractDependencies = (
|
|||
babelRegisterOnly([transform]);
|
||||
/* $FlowFixMe: impossible to type a dynamic require */
|
||||
const transformModule: Transformer<*> = require(transform);
|
||||
transformCode(transformModule, filename, localPath, sourceCode, options, callback);
|
||||
transformCode(
|
||||
transformModule,
|
||||
filename,
|
||||
localPath,
|
||||
sourceCode,
|
||||
options,
|
||||
callback,
|
||||
);
|
||||
};
|
||||
|
||||
exports.minify = (
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
@ -34,8 +35,7 @@ const importMap = new Map([['ReactNative', 'react-native']]);
|
|||
|
||||
const isGlobal = binding => !binding;
|
||||
|
||||
const isFlowDeclared = binding =>
|
||||
t.isDeclareVariable(binding.path);
|
||||
const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
||||
|
||||
const isGlobalOrFlowDeclared = binding =>
|
||||
isGlobal(binding) || isFlowDeclared(binding);
|
||||
|
@ -43,7 +43,7 @@ const isGlobalOrFlowDeclared = binding =>
|
|||
const isToplevelBinding = (binding, isWrappedModule) =>
|
||||
isGlobal(binding) ||
|
||||
!binding.scope.parent ||
|
||||
isWrappedModule && !binding.scope.parent.parent;
|
||||
(isWrappedModule && !binding.scope.parent.parent);
|
||||
|
||||
const isRequireCall = (node, dependencyId, scope) =>
|
||||
t.isCallExpression(node) &&
|
||||
|
@ -59,8 +59,8 @@ const isImport = (node, scope, patterns) =>
|
|||
function isImportOrGlobal(node, scope, patterns, isWrappedModule) {
|
||||
const identifier = patterns.find(pattern => t.isIdentifier(node, pattern));
|
||||
return (
|
||||
identifier &&
|
||||
isToplevelBinding(scope.getBinding(identifier.name), isWrappedModule) ||
|
||||
(identifier &&
|
||||
isToplevelBinding(scope.getBinding(identifier.name), isWrappedModule)) ||
|
||||
isImport(node, scope, patterns)
|
||||
);
|
||||
}
|
||||
|
@ -74,7 +74,11 @@ const isReactPlatformOS = (node, scope, isWrappedModule) =>
|
|||
t.isMemberExpression(node.object) &&
|
||||
t.isIdentifier(node.object.property, platform) &&
|
||||
isImportOrGlobal(
|
||||
node.object.object, scope, [React, ReactNative], isWrappedModule);
|
||||
node.object.object,
|
||||
scope,
|
||||
[React, ReactNative],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isProcessEnvNodeEnv = (node, scope) =>
|
||||
t.isIdentifier(node.property, nodeEnv) &&
|
||||
|
@ -95,12 +99,16 @@ const isReactPlatformSelect = (node, scope, isWrappedModule) =>
|
|||
t.isMemberExpression(node.callee.object) &&
|
||||
t.isIdentifier(node.callee.object.property, platform) &&
|
||||
isImportOrGlobal(
|
||||
node.callee.object.object, scope, [React, ReactNative], isWrappedModule);
|
||||
node.callee.object.object,
|
||||
scope,
|
||||
[React, ReactNative],
|
||||
isWrappedModule,
|
||||
);
|
||||
|
||||
const isDev = (node, parent, scope) =>
|
||||
t.isIdentifier(node, dev) &&
|
||||
isGlobalOrFlowDeclared(scope.getBinding(dev.name)) &&
|
||||
!(t.isMemberExpression(parent));
|
||||
!t.isMemberExpression(parent);
|
||||
|
||||
function findProperty(objectExpression, key, fallback) {
|
||||
const property = objectExpression.properties.find(p => p.key.name === key);
|
||||
|
@ -126,7 +134,8 @@ const inlinePlugin = {
|
|||
path.replaceWith(t.stringLiteral(opts.platform));
|
||||
} else if (isProcessEnvNodeEnv(node, scope)) {
|
||||
path.replaceWith(
|
||||
t.stringLiteral(opts.dev ? 'development' : 'production'));
|
||||
t.stringLiteral(opts.dev ? 'development' : 'production'),
|
||||
);
|
||||
}
|
||||
},
|
||||
CallExpression(path, state) {
|
||||
|
@ -155,10 +164,12 @@ const plugin = () => inlinePlugin;
|
|||
|
||||
function 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);
|
||||
return (
|
||||
t.isStringLiteral(args[0], pattern) ||
|
||||
(t.isMemberExpression(args[0]) &&
|
||||
t.isNumericLiteral(args[0].property) &&
|
||||
t.isStringLiteral(args[1], pattern))
|
||||
);
|
||||
}
|
||||
|
||||
type AstResult = {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
|
Loading…
Reference in New Issue