diff --git a/packages/modules-runtime/client.js b/packages/modules-runtime/client.js new file mode 100644 index 0000000000..d902671864 --- /dev/null +++ b/packages/modules-runtime/client.js @@ -0,0 +1,5 @@ +// On the client, make package resolution prefer the "browser" field of +// package.json files to the "main" field. +makeInstallerOptions.browser = true; + +meteorInstall = makeInstaller(makeInstallerOptions); diff --git a/packages/modules-runtime/modules-runtime.js b/packages/modules-runtime/modules-runtime.js deleted file mode 100644 index da38e75648..0000000000 --- a/packages/modules-runtime/modules-runtime.js +++ /dev/null @@ -1,86 +0,0 @@ -var options = {}; -var hasOwn = options.hasOwnProperty; - -// RegExp matching strings that don't start with a `.` or a `/`. -var topLevelIdPattern = /^[^./]/; - -if (typeof Profile === "function" && - process.env.METEOR_PROFILE) { - options.wrapRequire = function (require) { - return Profile(function (id) { - return "require(" + JSON.stringify(id) + ")"; - }, require); - }; -} - -// On the client, make package resolution prefer the "browser" field of -// package.json files to the "main" field. -options.browser = Meteor.isClient; - -// This function will be called whenever a module identifier that hasn't -// been installed is required. For backwards compatibility, and so that we -// can require binary dependencies on the server, we implement the -// fallback in terms of Npm.require. -options.fallback = function (id, parentId, error) { - // For simplicity, we honor only top-level module identifiers here. - // We could try to honor relative and absolute module identifiers by - // somehow combining `id` with `dir`, but we'd have to be really careful - // that the resulting modules were located in a known directory (not - // some arbitrary location on the file system), and we only really need - // the fallback for dependencies installed in node_modules directories. - if (topLevelIdPattern.test(id)) { - if (typeof Npm === "object" && - typeof Npm.require === "function") { - return Npm.require(id); - } - } - - throw error; -}; - -options.fallback.resolve = function (id, parentId, error) { - if (Meteor.isServer && - topLevelIdPattern.test(id)) { - // Allow any top-level identifier to resolve to itself on the server, - // so that options.fallback can have a chance to handle it. - return id; - } - - throw error; -}; - -meteorInstall = makeInstaller(options); -var Mp = meteorInstall.Module.prototype; - -if (Meteor.isServer) { - Mp.useNode = function () { - if (typeof npmRequire !== "function") { - // Can't use Node if npmRequire is not defined. - return false; - } - - var parts = this.id.split("/"); - var start = 0; - if (parts[start] === "") ++start; - if (parts[start] === "node_modules" && - parts[start + 1] === "meteor") { - start += 2; - } - - if (parts.indexOf("node_modules", start) < 0) { - // Don't try to use Node for modules that aren't in node_modules - // directories. - return false; - } - - try { - npmRequire.resolve(this.id); - } catch (e) { - return false; - } - - this.exports = npmRequire(this.id); - - return true; - }; -} diff --git a/packages/modules-runtime/options.js b/packages/modules-runtime/options.js new file mode 100644 index 0000000000..200b878613 --- /dev/null +++ b/packages/modules-runtime/options.js @@ -0,0 +1,10 @@ +makeInstallerOptions = {}; + +if (typeof Profile === "function" && + process.env.METEOR_PROFILE) { + makeInstallerOptions.wrapRequire = function (require) { + return Profile(function (id) { + return "require(" + JSON.stringify(id) + ")"; + }, require); + }; +} diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 5aff025d47..6d0735fcab 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -18,7 +18,10 @@ Package.onUse(function(api) { bare: true }); - api.addFiles("modules-runtime.js"); + api.addFiles("options.js"); + api.addFiles("client.js", "client"); + api.addFiles("server.js", "server"); + api.export("meteorInstall"); }); diff --git a/packages/modules-runtime/server.js b/packages/modules-runtime/server.js new file mode 100644 index 0000000000..367a60c769 --- /dev/null +++ b/packages/modules-runtime/server.js @@ -0,0 +1,67 @@ +// RegExp matching strings that don't start with a `.` or a `/`. +var topLevelIdPattern = /^[^./]/; + +// This function will be called whenever a module identifier that hasn't +// been installed is required. For backwards compatibility, and so that we +// can require binary dependencies on the server, we implement the +// fallback in terms of Npm.require. +makeInstallerOptions.fallback = function (id, parentId, error) { + // For simplicity, we honor only top-level module identifiers here. + // We could try to honor relative and absolute module identifiers by + // somehow combining `id` with `dir`, but we'd have to be really careful + // that the resulting modules were located in a known directory (not + // some arbitrary location on the file system), and we only really need + // the fallback for dependencies installed in node_modules directories. + if (topLevelIdPattern.test(id)) { + if (typeof Npm === "object" && + typeof Npm.require === "function") { + return Npm.require(id); + } + } + + throw error; +}; + +makeInstallerOptions.fallback.resolve = function (id, parentId, error) { + if (topLevelIdPattern.test(id)) { + // Allow any top-level identifier to resolve to itself on the server, + // so that makeInstallerOptions.fallback has a chance to handle it. + return id; + } + + throw error; +}; + +meteorInstall = makeInstaller(makeInstallerOptions); +var Module = meteorInstall.Module; + +Module.prototype.useNode = function () { + if (typeof npmRequire !== "function") { + // Can't use Node if npmRequire is not defined. + return false; + } + + var parts = this.id.split("/"); + var start = 0; + if (parts[start] === "") ++start; + if (parts[start] === "node_modules" && + parts[start + 1] === "meteor") { + start += 2; + } + + if (parts.indexOf("node_modules", start) < 0) { + // Don't try to use Node for modules that aren't in node_modules + // directories. + return false; + } + + try { + npmRequire.resolve(this.id); + } catch (e) { + return false; + } + + this.exports = npmRequire(this.id); + + return true; +};