mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Fix hot code push client-side reloads.
We were overwriting the server directory when a client-side file changed, which made all process calls fail, such as process.cwd() and fs.*. We abstracted out some of the builder code so that only the client targets are "rebuilt" when a client side file changes.
This commit is contained in:
123
tools/bundler.js
123
tools/bundler.js
@@ -1452,6 +1452,27 @@ var writeFile = function (file, builder) {
|
||||
builder.write(file.targetPath, { data: file.contents() });
|
||||
};
|
||||
|
||||
// Writes a target a path in 'programs'
|
||||
var writeTargetToPath = function (name, target, outputPath, options) {
|
||||
var builder = new Builder({
|
||||
outputPath: path.join(outputPath, 'programs', name),
|
||||
symlink: options.includeNodeModulesSymlink
|
||||
});
|
||||
|
||||
var relControlFilePath =
|
||||
target.write(builder, {
|
||||
includeNodeModulesSymlink: options.includeNodeModulesSymlink,
|
||||
getRelativeTargetPath: options.getRelativeTargetPath });
|
||||
|
||||
builder.complete();
|
||||
|
||||
return {
|
||||
name: name,
|
||||
arch: target.mostCompatibleArch(),
|
||||
path: path.join('programs', name, relControlFilePath)
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// writeSiteArchive
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1495,51 +1516,6 @@ var writeSiteArchive = function (targets, outputPath, options) {
|
||||
meteorRelease: options.releaseName
|
||||
};
|
||||
|
||||
// Pick a path in the bundle for each target
|
||||
var paths = {};
|
||||
_.each(targets, function (target, name) {
|
||||
var p = path.join('programs', name);
|
||||
builder.reserve(p, { directory: true });
|
||||
paths[name] = p;
|
||||
});
|
||||
|
||||
// Hack to let servers find relative paths to clients. Should find
|
||||
// another solution eventually (probably some kind of mount
|
||||
// directive that mounts the client bundle in the server at runtime)
|
||||
var getRelativeTargetPath = function (options) {
|
||||
var pathForTarget = function (target) {
|
||||
var name;
|
||||
_.each(targets, function (t, n) {
|
||||
if (t === target)
|
||||
name = n;
|
||||
});
|
||||
if (! name)
|
||||
throw new Error("missing target?");
|
||||
|
||||
if (! (name in paths))
|
||||
throw new Error("missing target path?");
|
||||
|
||||
return paths[name];
|
||||
};
|
||||
|
||||
return path.relative(pathForTarget(options.relativeTo),
|
||||
pathForTarget(options.forTarget));
|
||||
};
|
||||
|
||||
// Write out each target
|
||||
_.each(targets, function (target, name) {
|
||||
var relControlFilePath =
|
||||
target.write(builder.enter(paths[name]), {
|
||||
includeNodeModulesSymlink: options.includeNodeModulesSymlink,
|
||||
getRelativeTargetPath: getRelativeTargetPath });
|
||||
|
||||
json.programs.push({
|
||||
name: name,
|
||||
arch: target.mostCompatibleArch(),
|
||||
path: path.join(paths[name], relControlFilePath)
|
||||
});
|
||||
});
|
||||
|
||||
// Tell Galaxy what version of the dependency kit we're using, so
|
||||
// it can load the right modules. (Include this even if we copied
|
||||
// or symlinked a node_modules, since that's probably enough for
|
||||
@@ -1589,6 +1565,10 @@ var writeSiteArchive = function (targets, outputPath, options) {
|
||||
}
|
||||
});
|
||||
|
||||
_.each(targets, function (target, name) {
|
||||
json.programs.push(writeTargetToPath(name, target, builder.buildPath, options));
|
||||
});
|
||||
|
||||
// We did it!
|
||||
builder.complete();
|
||||
|
||||
@@ -1750,9 +1730,11 @@ exports.bundle = function (options) {
|
||||
targets.client = client;
|
||||
|
||||
// Server
|
||||
var server = options.cachedServerTarget || makeServerTarget(app, client);
|
||||
server.clientTarget = client;
|
||||
targets.server = server;
|
||||
if (! options.hasCachedBundle) {
|
||||
var server = makeServerTarget(app, client);
|
||||
server.clientTarget = client;
|
||||
targets.server = server;
|
||||
}
|
||||
}
|
||||
|
||||
// Pick up any additional targets in /programs
|
||||
@@ -1902,15 +1884,47 @@ exports.bundle = function (options) {
|
||||
if (! (controlProgram in targets))
|
||||
controlProgram = undefined;
|
||||
|
||||
|
||||
// Hack to let servers find relative paths to clients. Should find
|
||||
// another solution eventually (probably some kind of mount
|
||||
// directive that mounts the client bundle in the server at runtime)
|
||||
var getRelativeTargetPath = function (options) {
|
||||
var pathForTarget = function (target) {
|
||||
var name;
|
||||
_.each(targets, function (t, n) {
|
||||
if (t === target)
|
||||
name = n;
|
||||
});
|
||||
if (! name)
|
||||
throw new Error("missing target?");
|
||||
return path.join('programs', name);
|
||||
};
|
||||
|
||||
return path.relative(pathForTarget(options.relativeTo),
|
||||
pathForTarget(options.forTarget));
|
||||
};
|
||||
|
||||
// Write to disk
|
||||
starResult = writeSiteArchive(targets, outputPath, {
|
||||
var writeOptions = {
|
||||
includeNodeModulesSymlink: includeNodeModulesSymlink,
|
||||
builtBy: builtBy,
|
||||
controlProgram: controlProgram,
|
||||
releaseName: releaseName
|
||||
});
|
||||
serverWatchSet.merge(starResult.serverWatchSet);
|
||||
clientWatchSet.merge(starResult.clientWatchSet);
|
||||
releaseName: releaseName,
|
||||
getRelativeTargetPath: getRelativeTargetPath
|
||||
};
|
||||
|
||||
if (options.hasCachedBundle) {
|
||||
// XXX If we already have a cached bundle, just recreate the new targets.
|
||||
// This might make the contents of "star.json" out of date.
|
||||
_.each(targets, function (target, name) {
|
||||
writeTargetToPath(name, target, outputPath, options);
|
||||
clientWatchSet.merge(target.getWatchSet());
|
||||
});
|
||||
} else {
|
||||
starResult = writeSiteArchive(targets, outputPath, writeOptions);
|
||||
serverWatchSet.merge(starResult.serverWatchSet);
|
||||
clientWatchSet.merge(starResult.clientWatchSet);
|
||||
}
|
||||
|
||||
success = true;
|
||||
});
|
||||
@@ -1922,8 +1936,7 @@ exports.bundle = function (options) {
|
||||
errors: success ? false : messages,
|
||||
serverWatchSet: serverWatchSet,
|
||||
clientWatchSet: clientWatchSet,
|
||||
starManifest: starResult && starResult.starManifest,
|
||||
serverTarget: targets.server
|
||||
starManifest: starResult && starResult.starManifest
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ _.extend(AppRunner.prototype, {
|
||||
|
||||
// Cache the server target because the server will not change inside
|
||||
// a single invocation of _runOnce().
|
||||
var cachedServerTarget = null;
|
||||
var cachedBundle;
|
||||
var bundleApp = function () {
|
||||
if (! self.firstRun)
|
||||
packageCache.packageCache.refresh(true); // pick up changes to packages
|
||||
@@ -432,10 +432,17 @@ _.extend(AppRunner.prototype, {
|
||||
outputPath: bundlePath,
|
||||
includeNodeModulesSymlink: true,
|
||||
buildOptions: self.buildOptions,
|
||||
cachedServerTarget: cachedServerTarget
|
||||
hasCachedBundle: !! cachedBundle
|
||||
});
|
||||
|
||||
cachedServerTarget = bundle.serverTarget;
|
||||
// Overwrite the null elements in the new bundle with the elements from
|
||||
// the cached bundle. However, we make sure to keep the serverWatchSet
|
||||
// from the original cached bundle.
|
||||
if (cachedBundle) {
|
||||
bundle.serverWatchSet = cachedBundle.serverWatchSet;
|
||||
}
|
||||
cachedBundle = _.defaults(bundle, cachedBundle);
|
||||
|
||||
return bundle;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ if (Meteor.isServer) {
|
||||
|
||||
Meteor.methods({
|
||||
clientLoad: function (jsVar) {
|
||||
// Make sure that the process still has the correct working directories.
|
||||
process.cwd();
|
||||
console.log("client connected: " + clientConnections++);
|
||||
console.log("jsVar: " + jsVar);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user