[Pkg-javascript-commits] [dojo] 08/21: Port Node.js loader plugin fixes from d2c

David Prévot taffit at moszumanska.debian.org
Sun Sep 14 15:39:21 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository dojo.

commit 108c3f408a42d0e289bfd298df88d61904971b6e
Author: Colin Snover <github.com at zetafleet.com>
Date:   Sat Aug 23 00:36:07 2014 +0000

    Port Node.js loader plugin fixes from d2c
    
    Fixes #18235, #18236.
    
    (cherry picked from commit c58335c35155178b316953ec07d06d1fb8b16e54)
---
 node.js | 90 ++++++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 50 insertions(+), 40 deletions(-)

diff --git a/node.js b/node.js
index f804ba9..1191699 100644
--- a/node.js
+++ b/node.js
@@ -1,64 +1,74 @@
-define(["./has"], function(has){
-	if(!has("host-node")){
-		throw new Error("node plugin failed to load because environment is not Node.js");
-	}
+define(["./_base/kernel", "./has", "require"], function(kernel, has, require){
+	var nodeRequire = kernel.global.require && kernel.global.require.nodeRequire;
 
-	var pathUtil;
-	if(require.nodeRequire){
-		pathUtil = require.nodeRequire("path");
-	}else{
-		throw new Error("node plugin failed to load because it cannot find the original Node.js require");
+	if (!nodeRequire) {
+		throw new Error("Cannot find the Node.js require");
 	}
 
+	var module = nodeRequire("module");
+
 	return {
 		// summary:
 		//		This AMD plugin module allows native Node.js modules to be loaded by AMD modules using the Dojo
-		//		loader. Note that this plugin will not work with AMD loaders other than the Dojo loader.
+		//		loader. This plugin will not work with AMD loaders that do not expose the Node.js require function
+		//		at `require.nodeRequire`.
+		//
 		// example:
 		//	|	require(["dojo/node!fs"], function(fs){
 		//	|		var fileData = fs.readFileSync("foo.txt", "utf-8");
 		//	|	});
 
-		load: function(/*string*/ id, /*Function*/ require, /*Function*/ load){
-			// summary:
-			//		Standard AMD plugin interface. See https://github.com/amdjs/amdjs-api/wiki/Loader-Plugins
-			//		for information.
+		load: function(/*string*/ id, /*Function*/ contextRequire, /*Function*/ load){
+			/*global define:true */
 
-			if(!require.nodeRequire){
-				throw new Error("Cannot find native require function");
+			// The `nodeRequire` function comes from the Node.js module of the AMD loader, so module ID resolution is
+			// relative to the loader's path, not the calling AMD module's path. This means that loading Node.js
+			// modules that exist in a higher level or sibling path to the loader will cause those modules to fail to
+			// resolve.
+			//
+			// Node.js does not expose a public API for performing module filename resolution relative to an arbitrary
+			// directory root, so we are forced to dig into the internal functions of the Node.js `module` module to
+			// use Node.js's own path resolution code instead of having to duplicate its rules ourselves.
+			//
+			// Sooner or later, probably around the time that Node.js internal code is reworked to use ES6, these
+			// methods will no longer be exposed and we will have to find another workaround if they have not exposed
+			// an API for doing this by then.
+			if(module._findPath && module._nodeModulePaths){
+				var localModulePath = module._findPath(id, module._nodeModulePaths(contextRequire.toUrl(".")));
+				if (localModulePath !== false) {
+					id = localModulePath;
+				}
 			}
 
-			load((function(id, require){
-				var oldDefine = define,
-					result;
+			var oldDefine = define,
+				result;
 
-				// Some modules may attempt to detect an AMD loader via define and define.amd.  This can cause issues
-				// when other CommonJS modules attempt to load them via the standard node require().  If define is
-				// temporarily moved into another variable, it will prevent modules from detecting AMD in this fashion.
-				define = undefined;
+			// Some modules attempt to detect an AMD loader by looking for global AMD `define`. This causes issues
+			// when other CommonJS modules attempt to load them via the standard Node.js `require`, so hide it
+			// during the load
+			define = undefined;
 
-				try{
-					result = require(id);
-				}finally{
-					define = oldDefine;
-				}
-				return result;
-			})(id, require.nodeRequire));
+			try {
+				result = nodeRequire(id);
+			}
+			finally {
+				define = oldDefine;
+			}
+
+			load(result);
 		},
 
 		normalize: function (/**string*/ id, /*Function*/ normalize){
 			// summary:
-			//		Produces a normalized id to be used by node.  Relative ids are resolved relative to the requesting
-			//		module's location in the file system and will return an id with path separators appropriate for the
-			//		local file system.
+			//		Produces a normalized CommonJS module ID to be used by Node.js `require`. Relative IDs
+			//		are resolved relative to the requesting module's location in the filesystem and will
+			//		return an ID with path separators appropriate for the local filesystem
 
-			if(id.charAt(0) === "."){
-				// dirname of the reference module - normalized to match the local file system
-				var referenceModuleDirname = require.toUrl(normalize(".")).replace("/", pathUtil.sep),
-					segments = id.split("/");
-				segments.unshift(referenceModuleDirname);
-				// this will produce an absolute path normalized to the semantics of the underlying file system.
-				id = pathUtil.join.apply(pathUtil, segments);
+			if (id.charAt(0) === ".") {
+				// absolute module IDs need to be generated based on the AMD loader's knowledge of the parent module,
+				// since Node.js will try to use the directory containing `dojo.js` as the relative root if a
+				// relative module ID is provided
+				id = require.toUrl(normalize("./" + id));
 			}
 
 			return id;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list