在节点上使用RequireJS和Mocha和SquireJS

时间:2014-04-29 10:12:02

标签: node.js requirejs mocha squirejs

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

这是一个简单的foo方法,返回" foo"

$ cat src/foo.js 

define([], function() {

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

    return { foo:foo};
});

这是需要foo的栏,但只有在指定相对路径时才有效。这是它应该是怎么回事?

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

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

    return { bar : bar };
});

摩卡测试中的事情变得更加棘手:

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

    $ 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

    上设置了复制品

1 个答案:

答案 0 :(得分:5)

您的代码中存在多个问题:

  1. 不要将.js放在模块名称的末尾。添加.js告诉RequireJS绕过正常的模块名称解析。 (在某些情况下,您想要扩展名,但这些情况应该说明您需要它的原因。)

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

  3. RequireJS可以使用packages设置加载包。

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

  5. 如果我修改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();
              });
        });
    });