diff --git a/scripts/dev-bundle-server-package.js b/scripts/dev-bundle-server-package.js index 4a13da2523c..a10dfe61fd0 100644 --- a/scripts/dev-bundle-server-package.js +++ b/scripts/dev-bundle-server-package.js @@ -19,6 +19,9 @@ var packageJson = { name: "meteor-dev-bundle", // Version is not important but is needed to prevent warnings. version: "0.0.0", + scripts: { + install: "node npm-rebuild.js" + }, dependencies: { fibers: fibersVersion, "meteor-promise": "0.5.1", diff --git a/tools/isobuild/bundler.js b/tools/isobuild/bundler.js index 7c3bca8b7a1..add1b6fe00f 100644 --- a/tools/isobuild/bundler.js +++ b/tools/isobuild/bundler.js @@ -1817,8 +1817,8 @@ class JsImage { load.push(loadItem); }); - const setupScriptPieces = []; const rebuildDirs = Object.create(null); + // node_modules resources from the packages. Due to appropriate // builder configuration, 'meteor bundle' and 'meteor deploy' copy // them, and 'meteor run' symlinks them. If these contain @@ -1842,18 +1842,15 @@ class JsImage { } }); - _.each(rebuildDirs, dir => { - setupScriptPieces.push("(cd ", dir, " && npm rebuild)\n"); + // This JSON file will be read by npm-rebuild.js, which is executed to + // trigger rebuilds for all non-portable npm packages. + builder.write("npm-rebuilds.json", { + data: new Buffer( + JSON.stringify(Object.keys(rebuildDirs), null, 2) + "\n", + "utf8" + ) }); - if (setupScriptPieces.length) { - setupScriptPieces.unshift('#!/usr/bin/env bash\n', 'set -e\n\n'); - builder.write('setup.sh', { - data: new Buffer(setupScriptPieces.join(''), 'utf8'), - executable: true - }); - } - // Control file builder.writeJson('program.json', { format: "javascript-image-pre1", @@ -2062,6 +2059,7 @@ class ServerTarget extends JsImageTarget { "server-json.js", "mini-files.js", "npm-require.js", + "npm-rebuild.js", ], function (filename) { builder.write(filename, { file: files.pathJoin( diff --git a/tools/static-assets/server/npm-rebuild.js b/tools/static-assets/server/npm-rebuild.js new file mode 100644 index 00000000000..415ab9e32df --- /dev/null +++ b/tools/static-assets/server/npm-rebuild.js @@ -0,0 +1,47 @@ +var path = require("path"); +var spawn = require("child_process").spawn; + +try { + // This JSON file gets written in meteor/tools/isobuild/bundler.js. + var rebuilds = require("./npm-rebuilds.json"); +} catch (e) { + if (e.code !== "MODULE_NOT_FOUND") { + throw e; + } + // If npm-rebuilds.json was not written, assume there is nothing that + // needs to be rebuilt. +} + +// Make sure the npm finds this exact version of node in its $PATH. +var PATH = path.dirname(process.execPath) + ":" + process.env.PATH; +var env = Object.create(process.env, { + PATH: { value: PATH } +}); + +function rebuild(i) { + var dir = rebuilds && rebuilds[i]; + + if (! dir) { + // Print Node/V8/etc. versions for diagnostic purposes. + spawn("npm", ["version", "--json"], { + stdio: "inherit", + env: env + }); + + return; + } + + spawn("npm", ["rebuild"], { + cwd: path.join(__dirname, dir), + stdio: "inherit", + env: env + }).on("exit", function (code) { + if (code !== 0) { + process.exit(code); + } else { + rebuild(i + 1); + } + }); +} + +rebuild(0);