diff --git a/tools/bundler.js b/tools/bundler.js index 8bbb9bb180..4433e62aca 100644 --- a/tools/bundler.js +++ b/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 }; }; diff --git a/tools/run-app.js b/tools/run-app.js index 0a52320191..51838dd87e 100644 --- a/tools/run-app.js +++ b/tools/run-app.js @@ -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; }; diff --git a/tools/tests/apps/hot-code-push-test/hot-code-push-test.js b/tools/tests/apps/hot-code-push-test/hot-code-push-test.js index 3b37107e9c..c1f89ef574 100644 --- a/tools/tests/apps/hot-code-push-test/hot-code-push-test.js +++ b/tools/tests/apps/hot-code-push-test/hot-code-push-test.js @@ -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); }