Skip to content

Commit

Permalink
Skip file removal on HMR interface
Browse files Browse the repository at this point in the history
Summary:
public

We're not planning to accept file removals in the short term on the HMR interface so lets bail when a file is removed (before this this we were throwing when trying to get the shallow dependencies).

Reviewed By: yungsters

Differential Revision: D2810534

fb-gh-sync-id: f2733382f4a2619e22bdf1163aa4180694fff9f8
  • Loading branch information
martinbigio authored and facebook-github-bot-3 committed Jan 7, 2016
1 parent a452199 commit 2b09614
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 66 deletions.
135 changes: 70 additions & 65 deletions local-cli/server/util/attachHMRServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,80 +106,85 @@ function attachHMRServer({httpServer, path, packagerServer}) {
shallowDependencies,
};

packagerServer.setHMRFileChangeListener(filename => {
packagerServer.setHMRFileChangeListener((filename, stat) => {
if (!client) {
return;
}

return packagerServer.getShallowDependencies(filename)
.then(deps => {
if (!client) {
return [];
}

// if the file dependencies have change we need to invalidate the
// dependencies caches because the list of files we need to send
// to the client may have changed
const oldDependencies = client.shallowDependencies[filename];
if (arrayEquals(deps, oldDependencies)) {
return [packagerServer.getModuleForPath(filename)];
}

// if there're new dependencies compare the full list of
// dependencies we used to have with the one we now have
return getDependencies(client.platform, client.bundleEntry)
.then(({
dependenciesCache,
dependenciesModulesCache,
shallowDependencies,
}) => {
if (!client) {
return [];
}

// build list of modules for which we'll send HMR updates
const modulesToUpdate = [];
Object.keys(dependenciesModulesCache).forEach(module => {
if (!client.dependenciesModulesCache[module]) {
modulesToUpdate.push(dependenciesModulesCache[module]);
stat.then(() => {
return packagerServer.getShallowDependencies(filename)
.then(deps => {
if (!client) {
return [];
}

// if the file dependencies have change we need to invalidate the
// dependencies caches because the list of files we need to send
// to the client may have changed
const oldDependencies = client.shallowDependencies[filename];
if (arrayEquals(deps, oldDependencies)) {
return [packagerServer.getModuleForPath(filename)];
}

// if there're new dependencies compare the full list of
// dependencies we used to have with the one we now have
return getDependencies(client.platform, client.bundleEntry)
.then(({
dependenciesCache,
dependenciesModulesCache,
shallowDependencies,
}) => {
if (!client) {
return [];
}
});

// invalidate caches
client.dependenciesCache = dependenciesCache;
client.dependenciesModulesCache = dependenciesModulesCache;
client.shallowDependencies = shallowDependencies;
// build list of modules for which we'll send HMR updates
const modulesToUpdate = [];
Object.keys(dependenciesModulesCache).forEach(module => {
if (!client.dependenciesModulesCache[module]) {
modulesToUpdate.push(dependenciesModulesCache[module]);
}
});

return modulesToUpdate;
// invalidate caches
client.dependenciesCache = dependenciesCache;
client.dependenciesModulesCache = dependenciesModulesCache;
client.shallowDependencies = shallowDependencies;

return modulesToUpdate;
});
})
.then(modulesToUpdate => {
if (!client) {
return;
}

// make sure the file was modified is part of the bundle
if (!client.shallowDependencies[filename]) {
return;
}

return packagerServer.buildBundleForHMR({
entryFile: client.bundleEntry,
platform: client.platform,
modules: modulesToUpdate,
});
})
.then(modulesToUpdate => {
if (!client) {
return;
}

// make sure the file was modified is part of the bundle
if (!client.shallowDependencies[filename]) {
return;
}

return packagerServer.buildBundleForHMR({
entryFile: client.bundleEntry,
platform: client.platform,
modules: modulesToUpdate,
})
.then(bundle => {
if (!client) {
return;
}

// check we actually want to send an HMR update
if (bundle) {
client.ws.send(bundle);
}
});
})
.then(bundle => {
if (!client) {
return;
}

// check we actually want to send an HMR update
if (bundle) {
client.ws.send(bundle);
}
})
.done();
},
() => {
// do nothing, file was removed
},
).done();
});

client.ws.on('error', e => {
Expand Down
4 changes: 4 additions & 0 deletions packager/react-packager/src/Bundler/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ class Bundler {
return this._resolver.getShallowDependencies(entryFile);
}

stat(filePath) {
return this._resolver.stat(filePath);
}

getModuleForPath(entryFile) {
return this._resolver.getModuleForPath(entryFile);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ class DependencyGraph {
return this._moduleCache.getModule(entryPath).getDependencies();
}

stat(filePath) {
return this._fastfs.stat(filePath);
}

/**
* Returns the module object for the given path.
*/
Expand Down
4 changes: 4 additions & 0 deletions packager/react-packager/src/Resolver/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ class Resolver {
return this._depGraph.getShallowDependencies(entryFile);
}

stat(filePath) {
return this._depGraph.stat(filePath);
}

getModuleForPath(entryFile) {
return this._depGraph.getModuleForPath(entryFile);
}
Expand Down
2 changes: 1 addition & 1 deletion packager/react-packager/src/Server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class Server {
// updates. Instead, send the HMR updates right away and once that
// finishes, invoke any other file change listener.
if (this._hmrFileChangeListener) {
this._hmrFileChangeListener(filePath);
this._hmrFileChangeListener(filePath, this._bundler.stat(filePath));
return;
}

Expand Down

0 comments on commit 2b09614

Please sign in to comment.