在使用requireJs调用的方法中使用node require

时间:2014-05-18 19:22:31

标签: javascript node.js requirejs amd commonjs

是否可以在通过require调用的文件中使用默认节点requirejs功能?

define(["require", "exports"], function(require, exports) {
  //...
  var Schema = require(DaoPublic._schemasDirectory + schemaFilename);
}

我总是得到ReferenceError: module is not defined,我也尝试使用requireJs加载架构,因为文件本身被编码为CommonJs,而不是AMD兼容。

任何解决方案?

请注意,加载的架构在CommonJS中,我需要保持这种方式,因为它被几个DAO使用,一些在AMD和其他在CommonJs中使用。 (有趣的部分)

请求的文件(架构)示例:

var userSchema = {
    /**
     * User Login, used as id to connect between all our platforms.
     */
    login: {
        type: String,
        match: /^[a-zA-Z0-9_-]+$/,
        trim: true,
        required: true,
        notEmpty: true,
        unique: true,
        check: {
            minLength: 4,
            maxLength: 16
        }
    }
};

module.exports = userSchema;

1 个答案:

答案 0 :(得分:2)

问题是您的代码已设置为RequireJS 能够自行查找CommonJS模块。但是,当RequireJS在Node中运行并且找不到模块时,它将调用Node的require函数,这就是您所需要的。所以有可能(使用RequireJS)让AMD模块使用Node require,但诀窍是让RequireJS首先看不到该模块。

概念证明

这是一个概念证明。名为test.js的主文件:

var requirejs = require("requirejs");

function myRequire(path) {
    if (path.lastIndexOf("schemas/", 0) === 0)
        path = "./" + path;
    return require(path);
}

requirejs.config({
    paths: {
        "schemas": "BOGUS"
    },
    nodeRequire: myRequire
});

requirejs(['foo'], function (foo) {
    console.log(foo);
});

文件foo.js

define(["require", "exports"], function(require, exports) {
  return require("./schemas/x") + " by way of foo";
});

文件schemas/x.js

module.exports = "x";

如果您使用node test.js运行它,您将进入控制台:

x by way of foo

解释

我称之为"概念证明"因为我没有考虑到所有可能性。

paths设置会使RequireJS偏离轨道。 BOGUS必须是不存在的目录。当RequireJS尝试加载模块./schemas/x时,它会尝试加载文件./BOGUS/x.js但找不到它。所以它调用Node require

nodeRequire设置告诉RequireJS节点的require功能是myRequire。这是一个有用的谎言。

myRequire函数会在调用节点要求之前更改路径以在开始时添加./。这里的问题是,由于某种原因,RequireJS在将./schemas/x提供给节点schemas/x函数的路径之前将require转换为./,然后Node将无法找到该模块。在路径名称的开头添加require可以解决此问题。我已经尝试了一大堆路径变体,但没有一个有效。一些变体是这样的,RequireJS能够自己找到模块,因此从未尝试调用Node schemas/或者他们阻止Node找到模块。可能有更好的方法来解决这个问题,我没有找到。 (这就是为什么我称之为"概念证明"。)请注意,我设计此功能只是改变以NODE_PATH开头的路径。

其他可能性

我看过其他可能性,但他们在我看来并不是很有希望。例如,自定义myRequire会消除{{1}},但这种自定义并不总是可行或可取。