Return the inverseDependencies from the Delta Bundler to support HMR

Reviewed By: jeanlauliac

Differential Revision: D5763905

fbshipit-source-id: 6b95c8dfded5fc30ec2e7a558ab25550d9a1c333
This commit is contained in:
Rafael Oleza 2017-09-05 07:10:40 -07:00 committed by Facebook Github Bot
parent d4a93eb2fa
commit 8b6d69b645
3 changed files with 67 additions and 21 deletions

View File

@ -17,14 +17,15 @@ const DeltaCalculator = require('./DeltaCalculator');
import type Bundler from '../Bundler';
import type {Options as JSTransformerOptions} from '../JSTransformer/worker';
import type Resolver from '../Resolver';
import type {BundleOptions} from '../Server';
import type {MappingsMap} from '../lib/SourceMap';
import type Module from '../node-haste/Module';
import type {Options as BundleOptions} from './';
export type DeltaTransformResponse = {
+pre: ?string,
+post: ?string,
+delta: {[key: string]: ?string},
+inverseDependencies: {[key: string]: $ReadOnlyArray<string>},
};
type Options = {|
@ -159,10 +160,16 @@ class DeltaTransformer {
)
: null;
// Inverse dependencies are needed for HMR.
const inverseDependencies = this._getInverseDependencies(
this._deltaCalculator.getInverseDependencies(),
);
return {
pre: prependSources,
post: appendSources,
delta: {...modifiedDelta, ...deletedDelta},
inverseDependencies,
reset,
};
}
@ -237,6 +244,23 @@ class DeltaTransformer {
return sources.join('\n');
}
/**
* Converts the paths in the inverse dependendencies to module ids.
*/
_getInverseDependencies(
inverseDependencies: Map<string, Set<string>>,
): {[key: string]: $ReadOnlyArray<string>} {
const output = Object.create(null);
for (const [key, dependencies] of inverseDependencies) {
output[this._getModuleId({path: key})] = Array.from(
dependencies,
).map(dep => this._getModuleId({path: dep}));
}
return output;
}
async _transformModules(
modules: Map<string, Module>,
resolver: Resolver,
@ -275,17 +299,27 @@ class DeltaTransformer {
const dependencyPairsForModule = dependencyPairs.get(module.path) || [];
const wrapped = await resolver.wrapModule({
module,
getModuleId: this._getModuleId,
dependencyPairs: dependencyPairsForModule,
dependencyOffsets: metadata.dependencyOffsets || [],
name,
code: metadata.code,
map: metadata.map,
minify: this._bundleOptions.minify,
dev: this._bundleOptions.dev,
});
const wrapped = this._bundleOptions.wrapModules
? await resolver.wrapModule({
module,
getModuleId: this._getModuleId,
dependencyPairs: dependencyPairsForModule,
dependencyOffsets: metadata.dependencyOffsets || [],
name,
code: metadata.code,
map: metadata.map,
minify: this._bundleOptions.minify,
dev: this._bundleOptions.dev,
})
: {
code: resolver.resolveRequires(
module,
this._getModuleId,
metadata.code,
dependencyPairsForModule,
metadata.dependencyOffsets || [],
),
};
return [this._getModuleId(module), wrapped.code];
}

View File

@ -23,6 +23,7 @@ export type DeltaBundle = {
pre: ?string,
post: ?string,
delta: {[key: string]: ?string},
inverseDependencies: {[key: string]: $ReadOnlyArray<string>},
};
type MainOptions = {|
@ -30,7 +31,13 @@ type MainOptions = {|
polyfillModuleNames: $ReadOnlyArray<string>,
|};
type Options = BundleOptions & {+deltaBundleId: ?string};
type FullBuildOptions = BundleOptions & {
+deltaBundleId: ?string,
};
export type Options = FullBuildOptions & {
+wrapModules: boolean,
};
/**
* `DeltaBundler` uses the `DeltaTransformer` to build bundle deltas. This
@ -84,8 +91,11 @@ class DeltaBundler {
};
}
async buildFullBundle(options: Options): Promise<string> {
const deltaBundle = await this.build(options);
async buildFullBundle(options: FullBuildOptions): Promise<string> {
const deltaBundle = await this.build({
...options,
wrapModules: true,
});
let deltaPatcher = this._deltaPatchers.get(deltaBundle.id);

View File

@ -291,12 +291,10 @@ class Server {
this._symbolicateInWorker = symbolicate.createWorker();
this._nextBundleBuildID = 1;
if (this._opts.useDeltaBundler) {
this._deltaBundler = new DeltaBundler(this._bundler, {
getPolyfills: this._opts.getPolyfills,
polyfillModuleNames: this._opts.polyfillModuleNames,
});
}
this._deltaBundler = new DeltaBundler(this._bundler, {
getPolyfills: this._opts.getPolyfills,
polyfillModuleNames: this._opts.polyfillModuleNames,
});
}
end(): mixed {
@ -315,6 +313,10 @@ class Server {
}
}
getDeltaBundler(): DeltaBundler {
return this._deltaBundler;
}
async buildBundle(options: BundleOptions): Promise<Bundle> {
const bundle = await this._bundler.bundle(options);
const modules = bundle.getModules();