react-native: attachHMRServer: make it generic
Reviewed By: cpojer Differential Revision: D5172344 fbshipit-source-id: ab8b39e1924d66d37da9734455ed9a72cf59906e
This commit is contained in:
parent
ec030d14cd
commit
a829d01bfc
|
@ -11,32 +11,73 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const getInverseDependencies = require('../../../packager/src//node-haste/lib/getInverseDependencies');
|
||||
const getInverseDependencies = require('./getInverseDependencies');
|
||||
const querystring = require('querystring');
|
||||
const url = require('url');
|
||||
|
||||
import type HMRBundle from '../../../packager/src/Bundler/HMRBundle';
|
||||
import type Server from '../../../packager/src/Server';
|
||||
import type ResolutionResponse
|
||||
from '../../../packager/src/node-haste/DependencyGraph/ResolutionResponse';
|
||||
import type Module from '../../../packager/src/node-haste/Module';
|
||||
import type {ResolutionResponse} from './getInverseDependencies';
|
||||
import type {Server as HTTPServer} from 'http';
|
||||
|
||||
const blacklist = [
|
||||
'Libraries/Utilities/HMRClient.js',
|
||||
];
|
||||
|
||||
type HMROptions = {
|
||||
type HMRBundle = {
|
||||
getModulesIdsAndCode(): Array<{id: string, code: string}>,
|
||||
getSourceMappingURLs(): Array<mixed>,
|
||||
getSourceURLs(): Array<mixed>,
|
||||
isEmpty(): boolean,
|
||||
};
|
||||
|
||||
type DependencyOptions = {|
|
||||
+dev: boolean,
|
||||
+entryFile: string,
|
||||
+hot: boolean,
|
||||
+minify: boolean,
|
||||
+platform: ?string,
|
||||
+recursive: boolean,
|
||||
|};
|
||||
|
||||
/**
|
||||
* This is a subset of the actual `metro-bundler`'s `Server` class,
|
||||
* without all the stuff we don't need to know about. This allows us to use
|
||||
* `attachHMRServer` with different versions of `metro-bundler` as long as
|
||||
* this specific contract is maintained.
|
||||
*/
|
||||
type PackagerServer<TModule> = {
|
||||
buildBundleForHMR(
|
||||
options: {platform: ?string},
|
||||
host: string,
|
||||
port: number,
|
||||
): Promise<HMRBundle>,
|
||||
getDependencies(options: DependencyOptions): Promise<ResolutionResponse<TModule>>,
|
||||
getModuleForPath(entryFile: string): Promise<TModule>,
|
||||
getShallowDependencies(options: DependencyOptions): Promise<Array<TModule>>,
|
||||
setHMRFileChangeListener(listener: ?(type: string, filePath: string) => mixed): void,
|
||||
};
|
||||
|
||||
type HMROptions<TModule> = {
|
||||
httpServer: HTTPServer,
|
||||
packagerServer: PackagerServer<TModule>,
|
||||
path: string,
|
||||
};
|
||||
|
||||
type Moduleish = {
|
||||
getName(): Promise<string>,
|
||||
isAsset(): boolean,
|
||||
isJSON(): boolean,
|
||||
path: string,
|
||||
packagerServer: Server,
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches a WebSocket based connection to the Packager to expose
|
||||
* Hot Module Replacement updates to the simulator.
|
||||
*/
|
||||
function attachHMRServer({httpServer, path, packagerServer}: HMROptions) {
|
||||
function attachHMRServer<TModule: Moduleish>(
|
||||
{httpServer, path, packagerServer}: HMROptions<TModule>,
|
||||
) {
|
||||
let client = null;
|
||||
|
||||
function disconnect() {
|
||||
|
@ -50,10 +91,10 @@ function attachHMRServer({httpServer, path, packagerServer}: HMROptions) {
|
|||
// - Inverse shallow dependencies map
|
||||
function getDependencies(platform: string, bundleEntry: string): Promise<{
|
||||
dependenciesCache: Array<string>,
|
||||
dependenciesModulesCache: {[mixed]: Module},
|
||||
shallowDependencies: {[string]: Array<Module>},
|
||||
dependenciesModulesCache: {[mixed]: TModule},
|
||||
shallowDependencies: {[string]: Array<TModule>},
|
||||
inverseDependenciesCache: mixed,
|
||||
resolutionResponse: ResolutionResponse<Module, *>,
|
||||
resolutionResponse: ResolutionResponse<TModule>,
|
||||
}> {
|
||||
return packagerServer.getDependencies({
|
||||
dev: true,
|
||||
|
@ -68,7 +109,7 @@ function attachHMRServer({httpServer, path, packagerServer}: HMROptions) {
|
|||
|
||||
// for each dependency builds the object:
|
||||
// `{path: '/a/b/c.js', deps: ['modA', 'modB', ...]}`
|
||||
return Promise.all(response.dependencies.map((dep: Module) => {
|
||||
return Promise.all(response.dependencies.map((dep: TModule) => {
|
||||
return dep.getName().then(depName => {
|
||||
if (dep.isAsset() || dep.isJSON()) {
|
||||
return Promise.resolve({path: dep.path, deps: []});
|
||||
|
@ -89,7 +130,7 @@ function attachHMRServer({httpServer, path, packagerServer}: HMROptions) {
|
|||
});
|
||||
});
|
||||
}))
|
||||
.then((deps: Array<{path: string, name?: string, deps: Array<Module>}>) => {
|
||||
.then((deps: Array<{path: string, name?: string, deps: Array<TModule>}>) => {
|
||||
// list with all the dependencies' filenames the bundle entry has
|
||||
const dependenciesCache = response.dependencies.map(dep => dep.path);
|
||||
|
||||
|
|
|
@ -12,10 +12,25 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import type ResolutionResponse from '../DependencyGraph/ResolutionResponse';
|
||||
/**
|
||||
* This is a subset of the actual `metro-bundler`'s `ResolutionResponse` class,
|
||||
* without all the stuff we don't need to know about. This allows us to use
|
||||
* `getInverseDependencies` with different versions of `metro-bundler`.
|
||||
*/
|
||||
export type ResolutionResponse<TModule> = {
|
||||
copy(data: {
|
||||
dependencies?: Array<TModule>,
|
||||
mainModuleId?: number,
|
||||
mocks?: mixed,
|
||||
}): ResolutionResponse<TModule>,
|
||||
dependencies: Array<TModule>,
|
||||
getResolvedDependencyPairs(
|
||||
module: TModule,
|
||||
): $ReadOnlyArray<[string, TModule]>,
|
||||
};
|
||||
|
||||
function resolveModuleRequires<TModule: {hash(): string}, TOptions>(
|
||||
resolutionResponse: ResolutionResponse<TModule, TOptions>,
|
||||
function resolveModuleRequires<TModule>(
|
||||
resolutionResponse: ResolutionResponse<TModule>,
|
||||
module: TModule,
|
||||
): Array<TModule> {
|
||||
const pairs = resolutionResponse.getResolvedDependencyPairs(module);
|
||||
|
@ -37,8 +52,8 @@ function getModuleDependents<TModule>(
|
|||
/**
|
||||
* Returns an object that indicates in which module each module is required.
|
||||
*/
|
||||
function getInverseDependencies<TModule: {hash(): string}, TOptions>(
|
||||
resolutionResponse: ResolutionResponse<TModule, TOptions>,
|
||||
function getInverseDependencies<TModule>(
|
||||
resolutionResponse: ResolutionResponse<TModule>,
|
||||
): Map<TModule, Set<TModule>> {
|
||||
const cache = new Map();
|
||||
|
|
@ -67,7 +67,7 @@ class HMRBundle extends BundleBase {
|
|||
return (Promise.resolve(): any);
|
||||
}
|
||||
|
||||
getModulesIdsAndCode() {
|
||||
getModulesIdsAndCode(): Array<{id: string, code: string}> {
|
||||
return this.__modules.map(module => {
|
||||
return {
|
||||
id: JSON.stringify(module.id),
|
||||
|
|
Loading…
Reference in New Issue