mirror of
https://github.com/status-im/metro.git
synced 2025-03-02 11:40:55 +00:00
Use Graph traversal logic for building polyfills
Reviewed By: mjesun Differential Revision: D7240946 fbshipit-source-id: 5af729878cdf31831b15867c296cf89025ab6f58
This commit is contained in:
parent
6be6b0805d
commit
d8eed45c37
@ -42,6 +42,7 @@ export type Options = {
|
|||||||
+minify: boolean,
|
+minify: boolean,
|
||||||
+onProgress: ?(doneCont: number, totalCount: number) => mixed,
|
+onProgress: ?(doneCont: number, totalCount: number) => mixed,
|
||||||
+platform: ?string,
|
+platform: ?string,
|
||||||
|
+type: 'module' | 'script',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,6 +200,17 @@ class DeltaCalculator extends EventEmitter {
|
|||||||
projectRoot,
|
projectRoot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When we're processing scripts, we don't need to calculate any
|
||||||
|
// inlineRequires information, since scripts by definition don't have
|
||||||
|
// requires().
|
||||||
|
if (this._options.type === 'script') {
|
||||||
|
// $FlowIssue #23854098 - Object.assign() loses the strictness of an object in flow
|
||||||
|
return {
|
||||||
|
...transformOptionsForBlacklist,
|
||||||
|
inlineRequires: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
inlineRequires,
|
inlineRequires,
|
||||||
} = await this._bundler.getTransformOptionsForEntryFiles(
|
} = await this._bundler.getTransformOptionsForEntryFiles(
|
||||||
@ -211,14 +223,14 @@ class DeltaCalculator extends EventEmitter {
|
|||||||
entryPoints: [path],
|
entryPoints: [path],
|
||||||
},
|
},
|
||||||
this._dependencyGraph,
|
this._dependencyGraph,
|
||||||
transformOptionsForBlacklist,
|
{...transformOptionsForBlacklist, type: this._options.type},
|
||||||
);
|
);
|
||||||
|
|
||||||
return Array.from(added.keys());
|
return Array.from(added.keys());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// $FlowFixMe flow does not recognize well Object.assign() return types.
|
// $FlowIssue #23854098 - Object.assign() loses the strictness of an object in flow
|
||||||
return {
|
return {
|
||||||
...transformOptionsForBlacklist,
|
...transformOptionsForBlacklist,
|
||||||
inlineRequires: inlineRequires || false,
|
inlineRequires: inlineRequires || false,
|
||||||
@ -267,7 +279,10 @@ class DeltaCalculator extends EventEmitter {
|
|||||||
modifiedFiles: Set<string>,
|
modifiedFiles: Set<string>,
|
||||||
deletedFiles: Set<string>,
|
deletedFiles: Set<string>,
|
||||||
): Promise<DeltaResult> {
|
): Promise<DeltaResult> {
|
||||||
const transformerOptions = await this.getTransformerOptions();
|
const transformerOptions = {
|
||||||
|
...(await this.getTransformerOptions()),
|
||||||
|
type: this._options.type,
|
||||||
|
};
|
||||||
|
|
||||||
if (!this._graph.dependencies.size) {
|
if (!this._graph.dependencies.size) {
|
||||||
const {added} = await initialTraverseDependencies(
|
const {added} = await initialTraverseDependencies(
|
||||||
|
@ -126,6 +126,7 @@ class DeltaTransformer extends EventEmitter {
|
|||||||
const deltaCalculator = new DeltaCalculator(bundler, dependencyGraph, {
|
const deltaCalculator = new DeltaCalculator(bundler, dependencyGraph, {
|
||||||
...bundleOptions,
|
...bundleOptions,
|
||||||
entryPoints: [bundleOptions.entryFile],
|
entryPoints: [bundleOptions.entryFile],
|
||||||
|
type: 'module',
|
||||||
});
|
});
|
||||||
|
|
||||||
return new DeltaTransformer(
|
return new DeltaTransformer(
|
||||||
|
@ -52,6 +52,11 @@ type Delta = {
|
|||||||
deleted: Set<string>,
|
deleted: Set<string>,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TransformOptions = {|
|
||||||
|
...JSTransformerOptions,
|
||||||
|
type: 'module' | 'script',
|
||||||
|
|};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dependency Traversal logic for the Delta Bundler. This method calculates
|
* Dependency Traversal logic for the Delta Bundler. This method calculates
|
||||||
* the modules that should be included in the bundle by traversing the
|
* the modules that should be included in the bundle by traversing the
|
||||||
@ -69,7 +74,7 @@ type Delta = {
|
|||||||
async function traverseDependencies(
|
async function traverseDependencies(
|
||||||
paths: $ReadOnlyArray<string>,
|
paths: $ReadOnlyArray<string>,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
||||||
): Promise<Result> {
|
): Promise<Result> {
|
||||||
@ -136,11 +141,17 @@ async function traverseDependencies(
|
|||||||
async function initialTraverseDependencies(
|
async function initialTraverseDependencies(
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
||||||
): Promise<Result> {
|
): Promise<Result> {
|
||||||
graph.entryPoints.forEach(entryPoint =>
|
graph.entryPoints.forEach(entryPoint =>
|
||||||
createEdge(dependencyGraph.getModuleForPath(entryPoint), graph),
|
createEdge(
|
||||||
|
dependencyGraph.getModuleForPath(
|
||||||
|
entryPoint,
|
||||||
|
transformOptions.type === 'script',
|
||||||
|
),
|
||||||
|
graph,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
await traverseDependencies(
|
await traverseDependencies(
|
||||||
@ -162,7 +173,7 @@ async function initialTraverseDependencies(
|
|||||||
async function traverseDependenciesForSingleFile(
|
async function traverseDependenciesForSingleFile(
|
||||||
edge: DependencyEdge,
|
edge: DependencyEdge,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
delta: Delta,
|
delta: Delta,
|
||||||
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
onProgress?: (numProcessed: number, total: number) => mixed = () => {},
|
||||||
@ -194,7 +205,7 @@ async function traverseDependenciesForSingleFile(
|
|||||||
async function processEdge(
|
async function processEdge(
|
||||||
edge: DependencyEdge,
|
edge: DependencyEdge,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
delta: Delta,
|
delta: Delta,
|
||||||
onDependencyAdd: () => mixed,
|
onDependencyAdd: () => mixed,
|
||||||
@ -202,11 +213,12 @@ async function processEdge(
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const previousDependencies = edge.dependencies;
|
const previousDependencies = edge.dependencies;
|
||||||
|
|
||||||
const result = await dependencyGraph
|
const {type, ...workerTransformOptions} = transformOptions;
|
||||||
.getModuleForPath(edge.path)
|
|
||||||
.read(
|
const module = dependencyGraph.getModuleForPath(edge.path, type === 'script');
|
||||||
removeInlineRequiresBlacklistFromOptions(edge.path, transformOptions),
|
const result = await module.read(
|
||||||
);
|
removeInlineRequiresBlacklistFromOptions(edge.path, workerTransformOptions),
|
||||||
|
);
|
||||||
|
|
||||||
// Get the absolute path of all sub-dependencies (some of them could have been
|
// Get the absolute path of all sub-dependencies (some of them could have been
|
||||||
// moved but maintain the same relative path).
|
// moved but maintain the same relative path).
|
||||||
@ -262,7 +274,7 @@ async function addDependency(
|
|||||||
parentEdge: DependencyEdge,
|
parentEdge: DependencyEdge,
|
||||||
path: string,
|
path: string,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
delta: Delta,
|
delta: Delta,
|
||||||
onDependencyAdd: () => mixed,
|
onDependencyAdd: () => mixed,
|
||||||
@ -277,7 +289,10 @@ async function addDependency(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const edge = createEdge(dependencyGraph.getModuleForPath(path), graph);
|
const edge = createEdge(
|
||||||
|
dependencyGraph.getModuleForPath(path, transformOptions.type === 'script'),
|
||||||
|
graph,
|
||||||
|
);
|
||||||
|
|
||||||
edge.inverseDependencies.add(parentEdge.path);
|
edge.inverseDependencies.add(parentEdge.path);
|
||||||
delta.added.set(edge.path, edge);
|
delta.added.set(edge.path, edge);
|
||||||
@ -365,11 +380,14 @@ function destroyEdge(edge: DependencyEdge, graph: Graph) {
|
|||||||
|
|
||||||
function resolveDependencies(
|
function resolveDependencies(
|
||||||
parentPath,
|
parentPath,
|
||||||
dependencies: Array<string>,
|
dependencies: $ReadOnlyArray<string>,
|
||||||
dependencyGraph: DependencyGraph,
|
dependencyGraph: DependencyGraph,
|
||||||
transformOptions: JSTransformerOptions,
|
transformOptions: TransformOptions,
|
||||||
): Map<string, string> {
|
): Map<string, string> {
|
||||||
const parentModule = dependencyGraph.getModuleForPath(parentPath);
|
const parentModule = dependencyGraph.getModuleForPath(
|
||||||
|
parentPath,
|
||||||
|
transformOptions.type === 'string',
|
||||||
|
);
|
||||||
|
|
||||||
return new Map(
|
return new Map(
|
||||||
dependencies.map(relativePath => [
|
dependencies.map(relativePath => [
|
||||||
|
@ -466,6 +466,7 @@ describe('processRequest', () => {
|
|||||||
minify: false,
|
minify: false,
|
||||||
onProgress: null,
|
onProgress: null,
|
||||||
platform: undefined,
|
platform: undefined,
|
||||||
|
type: 'module',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -245,7 +245,7 @@ class Server {
|
|||||||
this._opts.projectRoots,
|
this._opts.projectRoots,
|
||||||
);
|
);
|
||||||
|
|
||||||
let graph = await this._deltaBundler.buildGraph({
|
const crawlingOptions = {
|
||||||
assetPlugins: options.assetPlugins,
|
assetPlugins: options.assetPlugins,
|
||||||
customTransformOptions: options.customTransformOptions,
|
customTransformOptions: options.customTransformOptions,
|
||||||
dev: options.dev,
|
dev: options.dev,
|
||||||
@ -254,11 +254,14 @@ class Server {
|
|||||||
minify: options.minify,
|
minify: options.minify,
|
||||||
onProgress: options.onProgress,
|
onProgress: options.onProgress,
|
||||||
platform: options.platform,
|
platform: options.platform,
|
||||||
});
|
type: 'module',
|
||||||
|
};
|
||||||
|
|
||||||
|
let graph = await this._deltaBundler.buildGraph(crawlingOptions);
|
||||||
let prependScripts = await getPrependedScripts(
|
let prependScripts = await getPrependedScripts(
|
||||||
this._opts,
|
this._opts,
|
||||||
options,
|
crawlingOptions,
|
||||||
this._bundler,
|
this._deltaBundler,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (options.minify) {
|
if (options.minify) {
|
||||||
@ -973,6 +976,7 @@ class Server {
|
|||||||
runBeforeMainModule: [],
|
runBeforeMainModule: [],
|
||||||
runModule: true,
|
runModule: true,
|
||||||
sourceMapUrl: null,
|
sourceMapUrl: null,
|
||||||
|
type: 'script',
|
||||||
unbundle: false,
|
unbundle: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ async function getTransformOptions(): Promise<JSTransformerOptions> {
|
|||||||
hot: true,
|
hot: true,
|
||||||
minify: false,
|
minify: false,
|
||||||
platform: 'ios',
|
platform: 'ios',
|
||||||
|
type: 'module',
|
||||||
};
|
};
|
||||||
|
|
||||||
const deltaCalculator = new DeltaCalculator(
|
const deltaCalculator = new DeltaCalculator(
|
||||||
|
@ -13,27 +13,27 @@
|
|||||||
const defaults = require('../defaults');
|
const defaults = require('../defaults');
|
||||||
const getPreludeCode = require('./getPreludeCode');
|
const getPreludeCode = require('./getPreludeCode');
|
||||||
|
|
||||||
import type Bundler from '../Bundler';
|
|
||||||
import type {DependencyEdge} from '../DeltaBundler/traverseDependencies';
|
import type {DependencyEdge} from '../DeltaBundler/traverseDependencies';
|
||||||
import type Module from '../node-haste/Module';
|
import type DeltaBundler from '../DeltaBundler';
|
||||||
|
import type {CustomTransformOptions} from '../JSTransformer/worker';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
enableBabelRCLookup: boolean,
|
|
||||||
getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>,
|
getPolyfills: ({platform: ?string}) => $ReadOnlyArray<string>,
|
||||||
polyfillModuleNames: Array<string>,
|
polyfillModuleNames: Array<string>,
|
||||||
projectRoots: $ReadOnlyArray<string>,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type BundleOptions = {
|
type BundleOptions = {
|
||||||
|
customTransformOptions: CustomTransformOptions,
|
||||||
+dev: boolean,
|
+dev: boolean,
|
||||||
+hot: boolean,
|
+hot: boolean,
|
||||||
|
+minify: boolean,
|
||||||
+platform: ?string,
|
+platform: ?string,
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getPrependedScripts(
|
async function getPrependedScripts(
|
||||||
options: Options,
|
options: Options,
|
||||||
bundleOptions: BundleOptions,
|
bundleOptions: BundleOptions,
|
||||||
bundler: Bundler,
|
deltaBundler: DeltaBundler,
|
||||||
): Promise<Array<DependencyEdge>> {
|
): Promise<Array<DependencyEdge>> {
|
||||||
// Get all the polyfills from the relevant option params (the
|
// Get all the polyfills from the relevant option params (the
|
||||||
// `getPolyfills()` method and the `polyfillModuleNames` variable).
|
// `getPolyfills()` method and the `polyfillModuleNames` variable).
|
||||||
@ -43,32 +43,22 @@ async function getPrependedScripts(
|
|||||||
})
|
})
|
||||||
.concat(options.polyfillModuleNames);
|
.concat(options.polyfillModuleNames);
|
||||||
|
|
||||||
const dependencyGraph = await bundler.getDependencyGraph();
|
const graph = await deltaBundler.buildGraph({
|
||||||
|
assetPlugins: [],
|
||||||
// Build the module system dependencies (scripts that need to
|
customTransformOptions: bundleOptions.customTransformOptions,
|
||||||
// be included at the very beginning of the bundle) + any polifyll.
|
|
||||||
const modules = [defaults.moduleSystem]
|
|
||||||
.concat(polyfillModuleNames)
|
|
||||||
.map(polyfillModuleName =>
|
|
||||||
dependencyGraph.createPolyfill({
|
|
||||||
file: polyfillModuleName,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const transformOptions = {
|
|
||||||
dev: bundleOptions.dev,
|
dev: bundleOptions.dev,
|
||||||
enableBabelRCLookup: options.enableBabelRCLookup,
|
entryPoints: [defaults.moduleSystem, ...polyfillModuleNames],
|
||||||
hot: bundleOptions.hot,
|
hot: bundleOptions.hot,
|
||||||
projectRoot: options.projectRoots[0],
|
minify: bundleOptions.minify,
|
||||||
};
|
onProgress: null,
|
||||||
|
platform: bundleOptions.platform,
|
||||||
|
type: 'script',
|
||||||
|
});
|
||||||
|
|
||||||
const out = await Promise.all(
|
return [
|
||||||
modules.map(module => _createEdgeFromScript(module, transformOptions)),
|
_getPrelude({dev: bundleOptions.dev}),
|
||||||
);
|
...graph.dependencies.values(),
|
||||||
|
];
|
||||||
out.unshift(_getPrelude({dev: bundleOptions.dev}));
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getPrelude({dev}: {dev: boolean}): DependencyEdge {
|
function _getPrelude({dev}: {dev: boolean}): DependencyEdge {
|
||||||
@ -88,38 +78,4 @@ function _getPrelude({dev}: {dev: boolean}): DependencyEdge {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _createEdgeFromScript(
|
|
||||||
module: Module,
|
|
||||||
options: {
|
|
||||||
dev: boolean,
|
|
||||||
enableBabelRCLookup: boolean,
|
|
||||||
hot: boolean,
|
|
||||||
projectRoot: string,
|
|
||||||
},
|
|
||||||
): Promise<DependencyEdge> {
|
|
||||||
const result = await module.read({
|
|
||||||
assetDataPlugins: [],
|
|
||||||
customTransformOptions: {},
|
|
||||||
dev: options.dev,
|
|
||||||
enableBabelRCLookup: options.enableBabelRCLookup,
|
|
||||||
hot: options.hot,
|
|
||||||
inlineRequires: false,
|
|
||||||
minify: false,
|
|
||||||
platform: undefined,
|
|
||||||
projectRoot: options.projectRoot,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
dependencies: new Map(),
|
|
||||||
inverseDependencies: new Set(),
|
|
||||||
path: module.path,
|
|
||||||
output: {
|
|
||||||
code: result.code,
|
|
||||||
map: result.map,
|
|
||||||
source: result.source,
|
|
||||||
type: 'script',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = getPrependedScripts;
|
module.exports = getPrependedScripts;
|
||||||
|
@ -238,7 +238,11 @@ class DependencyGraph extends EventEmitter {
|
|||||||
this._haste.end();
|
this._haste.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
getModuleForPath(entryFile: string) {
|
getModuleForPath(entryFile: string, isPolyfill: boolean): Module {
|
||||||
|
if (isPolyfill) {
|
||||||
|
return this._moduleCache.getPolyfillModule(entryFile);
|
||||||
|
}
|
||||||
|
|
||||||
if (this._helpers.isAssetFile(entryFile)) {
|
if (this._helpers.isAssetFile(entryFile)) {
|
||||||
return this._moduleCache.getAssetModule(entryFile);
|
return this._moduleCache.getAssetModule(entryFile);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ class ModuleCache {
|
|||||||
this._roots = roots;
|
this._roots = roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
getModule(filePath: string): Module {
|
getModule(filePath: string) {
|
||||||
if (!this._moduleCache[filePath]) {
|
if (!this._moduleCache[filePath]) {
|
||||||
this._moduleCache[filePath] = new Module({
|
this._moduleCache[filePath] = new Module({
|
||||||
depGraphHelpers: this._depGraphHelpers,
|
depGraphHelpers: this._depGraphHelpers,
|
||||||
@ -129,6 +129,14 @@ class ModuleCache {
|
|||||||
return this._moduleCache[filePath];
|
return this._moduleCache[filePath];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPolyfillModule(filePath: string) {
|
||||||
|
if (!this._moduleCache[filePath]) {
|
||||||
|
this._moduleCache[filePath] = this.createPolyfill({file: filePath});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._moduleCache[filePath];
|
||||||
|
}
|
||||||
|
|
||||||
getPackage(filePath: string): Package {
|
getPackage(filePath: string): Package {
|
||||||
if (!this._packageCache[filePath]) {
|
if (!this._packageCache[filePath]) {
|
||||||
this._packageCache[filePath] = new Package({
|
this._packageCache[filePath] = new Package({
|
||||||
|
@ -119,14 +119,6 @@ type Params = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function transform({filename, options, src, plugins}: Params) {
|
function transform({filename, options, src, plugins}: Params) {
|
||||||
options = options || {
|
|
||||||
assetDataPlugins: [],
|
|
||||||
platform: '',
|
|
||||||
projectRoot: '',
|
|
||||||
inlineRequires: false,
|
|
||||||
minify: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const OLD_BABEL_ENV = process.env.BABEL_ENV;
|
const OLD_BABEL_ENV = process.env.BABEL_ENV;
|
||||||
process.env.BABEL_ENV = options.dev ? 'development' : 'production';
|
process.env.BABEL_ENV = options.dev ? 'development' : 'production';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user