Skip to content

Commit 73fc439

Browse files
davidaureliofacebook-github-bot
authored andcommitted
Stronger typing for transformers
Reviewed By: jeanlauliac Differential Revision: D5006679 fbshipit-source-id: 795c60db363fb53bc74697e4befe50995e9b97a7
1 parent 3dfed2e commit 73fc439

File tree

12 files changed

+102
-61
lines changed

12 files changed

+102
-61
lines changed

flow/babel.js.flow

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ type GeneratorOptions = {
5151
};
5252

5353
type InlinePlugin = string | {} | () => {};
54+
type _Plugins = Array<string | Object | [InlinePlugin] | [InlinePlugin, mixed]>;
5455

5556
// based on https://babeljs.io/docs/usage/options/ -- 2016-11-11
5657
type __TransformOptions = {
5758
filename?: string,
5859
filenameRelative?: string,
5960
presets?: Array<string | Object>,
60-
plugins?: Array<string | Object | [InlinePlugin] | [InlinePlugin, mixed]>,
61+
plugins?: _Plugins,
6162
parserOpts?: BabylonOptions,
6263
generatorOpts?: GeneratorOptions,
6364
highlightCode?: boolean,
@@ -92,11 +93,13 @@ declare class _Ast {}
9293
type TransformResult = {
9394
ast: _Ast,
9495
code: ?string,
96+
ignored: boolean,
9597
map: ?_SourceMap,
9698
};
9799
type VisitFn = <State>(path: Object, state: State) => any;
98100

99101
declare module 'babel-core' {
102+
declare type Plugins = _Plugins;
100103
declare type SourceMap = _SourceMap;
101104
declare type Ast = _Ast;
102105
declare type TransformOptions = _TransformOptions;

jest/preprocessor.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* This source code is licensed under the BSD-style license found in the
66
* LICENSE file in the root directory of this source tree. An additional grant
77
* of patent rights can be found in the PATENTS file in the same directory.
8+
*
9+
* @flow
810
*/
911
'use strict';
1012

@@ -24,15 +26,20 @@ babelRegisterOnly([]);
2426
const transformer = require('../packager/transformer.js');
2527

2628
module.exports = {
27-
process(src, file) {
29+
process(src/*: string*/, file/*: string*/) {
2830
if (nodeFiles.test(file)) { // node specific transforms only
2931
return babel.transform(
3032
src,
3133
Object.assign({filename: file}, nodeOptions)
3234
).code;
3335
}
3436

35-
return transformer.transform(src, file, {inlineRequires: true}).code;
37+
return transformer.transform(src, file, {
38+
dev: true,
39+
inlineRequires: true,
40+
platform: '',
41+
projectRoot: '',
42+
}).code;
3643
},
3744

3845
getCacheKey: createCacheKeyFunction([

packager/src/Bundler/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ type Options = {|
138138
+watch: boolean,
139139
|};
140140

141+
const {hasOwnProperty} = Object;
142+
141143
class Bundler {
142144

143145
_opts: Options;
@@ -673,7 +675,7 @@ class Bundler {
673675
const preloaded =
674676
module.path === entryFilePath ||
675677
isPolyfill ||
676-
preloadedModules && preloadedModules.hasOwnProperty(module.path);
678+
preloadedModules && hasOwnProperty.call(preloadedModules, module.path);
677679

678680
return new ModuleTransport({
679681
name,

packager/src/JSTransformer/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const path = require('path');
2020
const util = require('util');
2121
const workerFarm = require('../worker-farm');
2222

23-
import type {Data as TransformData, Options as TransformOptions} from './worker/worker';
23+
import type {Data as TransformData, Options as WorkerOptions} from './worker/worker';
2424
import type {MappingsMap} from '../lib/SourceMap';
2525

2626
// Avoid memory leaks caused in workers. This number seems to be a good enough number
@@ -63,7 +63,7 @@ class Transformer {
6363
transform: string,
6464
filename: string,
6565
sourceCode: string,
66-
options: ?TransformOptions,
66+
options: ?WorkerOptions,
6767
) => Promise<TransformData>;
6868
minify: (
6969
filename: string,
@@ -97,7 +97,7 @@ class Transformer {
9797
this._workers && workerFarm.end(this._workers);
9898
}
9999

100-
transformFile(fileName: string, code: string, options: TransformOptions) {
100+
transformFile(fileName: string, code: string, options: WorkerOptions) {
101101
if (!this._transform) {
102102
return Promise.reject(new Error('No transform module'));
103103
}

packager/src/JSTransformer/worker/worker.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
'use strict';
1313

14+
const babelRegisterOnly = require('../../../babelRegisterOnly');
1415
const constantFolding = require('./constant-folding');
1516
const extractDependencies = require('./extract-dependencies');
1617
const inline = require('./inline');
1718
const invariant = require('fbjs/lib/invariant');
1819
const minify = require('./minify');
1920

2021
import type {LogEntry} from '../../Logger/Types';
21-
import type {Ast, SourceMap as MappingsMap} from 'babel-core';
22+
import type {Ast, Plugins as BabelPlugins, SourceMap as MappingsMap} from 'babel-core';
2223

2324
export type TransformedCode = {
2425
code: string,
@@ -27,15 +28,18 @@ export type TransformedCode = {
2728
map?: ?MappingsMap,
2829
};
2930

30-
type Transformer = {
31+
export type Transformer<ExtraOptions: {} = {}> = {
3132
transform: (
3233
filename: string,
3334
sourceCode: string,
34-
options: ?{},
35-
) => {ast: ?Ast, code: string, map: ?MappingsMap}
35+
options: ExtraOptions & TransformOptions,
36+
plugins?: BabelPlugins,
37+
) => {ast: ?Ast, code: string, map: ?MappingsMap},
38+
getCacheKey: TransformOptionsStrict => string,
3639
};
3740

38-
export type TransformOptions = {|
41+
42+
export type TransformOptionsStrict = {|
3943
+dev: boolean,
4044
+generateSourceMaps: boolean,
4145
+hot: boolean,
@@ -44,11 +48,20 @@ export type TransformOptions = {|
4448
+projectRoot: string,
4549
|};
4650

51+
export type TransformOptions = {
52+
+dev?: boolean,
53+
+generateSourceMaps?: boolean,
54+
+hot?: boolean,
55+
+inlineRequires?: {+blacklist: {[string]: true}} | boolean,
56+
+platform: string,
57+
+projectRoot: string,
58+
};
59+
4760
export type Options = {|
4861
+dev: boolean,
4962
+minify: boolean,
5063
+platform: string,
51-
+transform: TransformOptions,
64+
+transform: TransformOptionsStrict,
5265
|};
5366

5467
export type Data = {
@@ -63,7 +76,7 @@ type Callback = (
6376
) => mixed;
6477

6578
function transformCode(
66-
transformer: Transformer,
79+
transformer: Transformer<*>,
6780
filename: string,
6881
sourceCode: string,
6982
options: Options,
@@ -144,8 +157,9 @@ exports.transformAndExtractDependencies = (
144157
options: Options,
145158
callback: Callback,
146159
) => {
160+
babelRegisterOnly([transform]);
147161
/* $FlowFixMe: impossible to type a dynamic require */
148-
const transformModule = require(transform);
162+
const transformModule: Transformer<*> = require(transform);
149163
transformCode(transformModule, filename, sourceCode, options, callback);
150164
};
151165

packager/src/ModuleGraph/types.flow.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import type {MappingsMap, SourceMap} from '../lib/SourceMap';
1414
import type {Ast} from 'babel-core';
1515
import type {Console} from 'console';
16+
export type {Transformer} from '../JSTransformer/worker/worker.js';
1617

1718
export type Callback<A = void, B = void>
1819
= (Error => void)
@@ -105,15 +106,6 @@ export type TransformerResult = {|
105106
map: ?MappingsMap,
106107
|};
107108

108-
export type Transformer = {
109-
transform: (
110-
sourceCode: string,
111-
filename: string,
112-
options: ?{},
113-
plugins?: Array<string | Object | [string | Object, any]>,
114-
) => {ast: ?Ast, code: string, map: ?MappingsMap}
115-
};
116-
117109
export type TransformResult = {|
118110
code: string,
119111
dependencies: Array<string>,

packager/src/ModuleGraph/worker/__tests__/transform-module-test.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,25 @@ describe('transforming JS modules:', () => {
8080
});
8181
});
8282

83+
const defaults = {
84+
dev: false,
85+
generateSourceMaps: true,
86+
hot: false,
87+
inlineRequires: false,
88+
platform: '',
89+
projectRoot: '',
90+
};
91+
8392
it('calls the passed-in transform function with code, file name, and options ' +
8493
'for all passed in variants',
8594
done => {
8695
const variants = {dev: {dev: true}, prod: {dev: false}};
8796

8897
transformModule(sourceCode, options(variants), () => {
8998
expect(transformer.transform)
90-
.toBeCalledWith(sourceCode, filename, variants.dev);
99+
.toBeCalledWith(sourceCode, filename, {...defaults, ...variants.dev});
91100
expect(transformer.transform)
92-
.toBeCalledWith(sourceCode, filename, variants.prod);
101+
.toBeCalledWith(sourceCode, filename, {...defaults, ...variants.prod});
93102
done();
94103
});
95104
},

packager/src/ModuleGraph/worker/transform-module.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
const JsFileWrapping = require('./JsFileWrapping');
1414

15+
const asyncify = require('async/asyncify');
1516
const collectDependencies = require('./collect-dependencies');
1617
const defaults = require('../../../defaults');
1718
const docblock = require('../../node-haste/DependencyGraph/docblock');
@@ -34,10 +35,18 @@ import type {
3435
export type TransformOptions = {|
3536
filename: string,
3637
polyfill?: boolean,
37-
transformer: Transformer,
38+
transformer: Transformer<*>,
3839
variants?: TransformVariants,
3940
|};
4041

42+
const defaultTransformOptions = {
43+
dev: true,
44+
generateSourceMaps: true,
45+
hot: false,
46+
inlineRequires: false,
47+
platform: '',
48+
projectRoot: '',
49+
};
4150
const defaultVariants = {default: {}};
4251

4352
const ASSET_EXTENSIONS = new Set(defaults.assetExts);
@@ -61,17 +70,12 @@ function transformModule(
6170
const {filename, transformer, variants = defaultVariants} = options;
6271
const tasks = {};
6372
Object.keys(variants).forEach(name => {
64-
tasks[name] = cb => {
65-
try {
66-
cb(null, transformer.transform(
67-
code,
68-
filename,
69-
variants[name],
70-
));
71-
} catch (error) {
72-
cb(error, null);
73-
}
74-
};
73+
tasks[name] = asyncify(() => transformer.transform(
74+
code,
75+
filename,
76+
{...defaultTransformOptions, ...variants[name]},
77+
)
78+
);
7579
});
7680

7781
series(tasks, (error, results: {[key: string]: TransformerResult}) => {

packager/src/lib/GlobalTransformCache.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const throat = require('throat');
2424

2525
import type {
2626
Options as TransformWorkerOptions,
27-
TransformOptions,
27+
TransformOptionsStrict,
2828
} from '../JSTransformer/worker/worker';
2929
import type {CachedResult, GetTransformCacheKey} from './TransformCache';
3030

@@ -381,7 +381,7 @@ class OptionsHasher {
381381
* of the cache key as they should not affect the transformation of a single
382382
* particular file.
383383
*/
384-
hashTransformOptions(hash: crypto$Hash, options: TransformOptions): crypto$Hash {
384+
hashTransformOptions(hash: crypto$Hash, options: TransformOptionsStrict): crypto$Hash {
385385
const {
386386
generateSourceMaps, dev, hot, inlineRequires, platform, projectRoot,
387387
...unknowns,

packager/src/lib/TransformCache.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const rimraf = require('rimraf');
2020
const terminal = require('../lib/terminal');
2121
const writeFileAtomicSync = require('write-file-atomic').sync;
2222

23-
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
23+
import type {Options as WorkerOptions} from '../JSTransformer/worker/worker';
2424
import type {MappingsMap} from './SourceMap';
2525
import type {Reporter} from './reporting';
2626

@@ -58,7 +58,7 @@ function hashSourceCode(props: {
5858
filePath: string,
5959
sourceCode: string,
6060
getTransformCacheKey: GetTransformCacheKey,
61-
transformOptions: TransformOptions,
61+
transformOptions: WorkerOptions,
6262
transformOptionsKey: string,
6363
}): string {
6464
return crypto.createHash('sha1')
@@ -134,7 +134,7 @@ function writeSync(props: {
134134
filePath: string,
135135
sourceCode: string,
136136
getTransformCacheKey: GetTransformCacheKey,
137-
transformOptions: TransformOptions,
137+
transformOptions: WorkerOptions,
138138
transformOptionsKey: string,
139139
result: CachedResult,
140140
}): void {
@@ -326,7 +326,7 @@ function readMetadataFileSync(
326326
export type ReadTransformProps = {
327327
filePath: string,
328328
sourceCode: string,
329-
transformOptions: TransformOptions,
329+
transformOptions: WorkerOptions,
330330
transformOptionsKey: string,
331331
getTransformCacheKey: GetTransformCacheKey,
332332
cacheOptions: CacheOptions,

0 commit comments

Comments
 (0)