1

我正在尝试在节点中使用 RequireJS,但发现路径问题存在困难。

这是一个返回“foo”的简单 foo 方法

$ cat src/foo.js 

define([], function() {

    var foo = function() {
        return "foo";
    };

    return { foo:foo};
});

这是需要 foo 的 bar,但它仅在指定相对路径时才有效。这就是它应该的样子吗?

$ cat src/bar.js
define(['./foo.js'], function(foo) {

    var bar = function() {
        return foo.foo().replace("foo","bar");
    };

    return { bar : bar };
});

在 mocha 测试中事情变得更加棘手:

  1. 加载 foo 和 bar 需要 __dirname 解决方法。
  2. bar 的异步加载失败(参见测试 3 和 4)。
  3. 导入 Squire 需要准确的路径,因为它是使用 npm install 安装的,但不符合标准 node require 语法并且不包括 amdefine 解决方法:

这是测试代码:

$ cat test/footests.js 
var requirejs = require('requirejs');
var chai = requirejs("chai");
var should = chai.should();
var Squire = requirejs(__dirname + "/../node_modules/squirejs/src/Squire.js");

describe('when calling foo.foo()', function () {
   it('should return "foo"', function() {
        var foo = requirejs(__dirname + "/../src/foo.js");
        foo.foo().should.equal("foo");
    });
});

describe('when calling bar.bar()', function () {
    var bar = requirejs(__dirname + "/../src/bar.js");
    it('should return "bar"', function() {
        bar.bar().should.equal("bar");
    });
});

describe('when calling bar.bar() with async requirejs', function () {
    it('should return "bar"', function(done) {
        requirejs(__dirname + "/../src/bar.js", function(bar) {
            bar.bar().should.equal("bar");
            done();
        })
    });
});
describe('when mocking foo.foo() and calling bar.bar()', function () {
    it('should return "barbar"', function(done) {
        var injector = new Squire();
        var fooMock = {
            foo : function() {
                return "foofoo"; /* instead of just foo */
            }
        };
        injector
          .mock('./foo.js', fooMock)
          .require(__dirname + "/../src/bar.js", function(bar) {
              bar.bar().should.equal("barbar");
              done();
          });
    });
});

我已经在 github https://github.com/itaifrenkel/node-requirejs-example上设置了一个复制品

4

1 回答 1

5

您的代码中有多个问题:

  1. 不要放在.js模块名称的末尾。添加.js告诉 RequireJS 绕过正常的模块名称解析。(在某些情况下您需要扩展,但这些情况应该是您可以说出为什么需要它的情况。)

  2. Node 中的 RequireJS 可以进行配置,就像在浏览器中使用它一样。这消除了在整个地方复制路径的需要。

  3. RequireJS 可以通过设置加载包packages

  4. 不要在不需要时使用 RequireJS 加载 Node 模块。(例如,chai不需要使用 RequireJS 加载。)

如果我修改以从其单独的依赖项bar.js中删除扩展名并使用以下测试文件,则它可以工作:.js

var requirejs = require('requirejs');
requirejs.config({
    baseUrl: __dirname + "/../src",
    packages: [
        {
            name: "squirejs",
            location: "../node_modules/squirejs",
            main: "src/Squire"
        }
    ]
});
var chai = require("chai");
var should = chai.should();
var Squire = requirejs("squirejs");

describe('when calling foo.foo()', function () {
   it('should return "foo"', function() {
        var foo = requirejs("foo");
        foo.foo().should.equal("foo");
    });
});

describe('when calling bar.bar()', function () {
    var bar = requirejs("bar");
    it('should return "bar"', function() {
        bar.bar().should.equal("bar");
    });
});

describe('when calling bar.bar() with async requirejs', function () {
    it('should return "bar"', function(done) {
        requirejs(["bar"], function(bar) {
            bar.bar().should.equal("bar");
            done();
        });
    });
});
describe('when mocking foo.foo() and calling bar.bar()', function () {
    it('should return "barbar"', function(done) {
        var injector = new Squire();
        var fooMock = {
            foo : function() {
                return "foofoo"; /* instead of just foo */
            }
        };
        injector
          .mock('./foo', fooMock)
          .require(["bar"], function(bar) {
              bar.bar().should.equal("barfoo");
              done();
          });
    });
});
于 2014-04-29T10:48:57.900 回答