【问题标题】:npm + Mocha + RequireJSnpm + Mocha + RequireJS
【发布时间】:2014-05-14 08:38:20
【问题描述】:

我有很多时间尝试使用 Mocha 和 RequireJS 设置 node/npm。这就是我所做的。

我创建了一个 testing/ 目录,结构如下:

testing/
   |
   +-- package.json
   |
   +-- README.md
   |
   +-- test/
         |
         +-- mocha.opts
         |
         +-- widgets/
                |
                +--mywidget/
                       |
                       +-- test.js

以下是每个相关文件包含的内容:

package.json:

{
    "name":"testing-project",
    "version":"2.5.0",
    "description":"Testing Project",
    "keywords":["test"],
    "engines": { "node": ">= 0.7.0 < 0.11.0" },
    "scripts" : {
        "test": "./node_modules/.bin/mocha"
    },
    "devDependencies": {
        "mocha": ">= 1.18.2",
        "requirejs": ">= 2.1.11",
        "should": ">= 3.2.0",
        "expect.js": ">= 0.3.1"
    }
}

测试/mocha.opts:

--require expect.js
--require should
--require requirejs
--require mocha
--reporter spec
--ui tdd
--recursive
--growl

test/widgets/mywidget/test.js

'use strict';
var requirejs = require('requirejs');
// Also tried with:  require('../../../r.js')  which I downloaded from RequireJS' site

requirejs.config({
    baseUrl: '../../../../',
    nodeRequire: require
});

console.log('before require');
requirejs(['mywidget/trunk/src/mywidgetfile.js'], function(myObj){
    console.log('after require');

    var expect = require('expect.js');

    // Instead of the above "requirejs['mywidget..." line, I've also tried:
    // var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js');   AND:
    // var myObj = requirejs('../../../../mywidget/trunk/src/mywidgetfile.js');

    describe('My Widget', function(){
        describe('my-widget#getInfo', function(){

            it('should pass this test', function(done){
                expect( myObj.returnString('test') ).to.equal( 'test' );

                done();
            })
        })
    });
});
console.log('done');

它将输出控制台行“before require”和“done”,但只要我有 requirejs(['mywidget... 行,它就不会命中 after require。如果我删除 requirejs 行(以及相应的右大括号/括号行),而是使用直接的“var myObj =”行,我得到“找不到模块”,如果我使用第二个“var myObj”行,我得到“参考错误:定义未定义”。

为了方便其他开发人员,我正在尝试使用 npm 将这一切打包,以便我从顶部“testing/”目录中运行命令“npm test”。

我一直在寻找答案并尝试了很多事情,但我似乎不需要使用 RequireJS 的文件并定义了“define()”。我可以执行测试,这不是问题......它只是试图将 RequireJS 插入到我开始遇到问题的组合中。

任何帮助都将是巨大的!

谢谢!

【问题讨论】:

    标签: node.js requirejs npm mocha.js requirejs-optimizer


    【解决方案1】:

    您向我们展示的内容存在多个问题。您错误地同时使用了 RequireJS 和 Mocha。

    RequireJS

    我很确定您的 baseUrl 不正确。您似乎认为 Mocha 的当前工作目录在执行test/widgets/mywidget/test.js 中的测试时会设置为test/widgets/mywidget/。事实并非如此。当您运行npm test 时,工作目录就在您所在的位置。根据您的描述,您在运行它时位于testing/。我不清楚您的baseUrl 应该有什么价值,因为您没有在问题中提供足够的信息,但我相信从我刚刚给出的解释中您可以弄清楚。

    现在你可能会想“当然,我的baseUrl 是正确的,因为当我执行requirejs(['mywidget/trunk/src/mywidgetfile.js'], function(myObj){ 时我没有收到错误”。这将是一个错误的推论。虽然这个requirejs 调用安排你的模块的加载,但RequireJS 没有机会尝试加载它,因为Mocha 在RequireJS 尝试加载它之前就退出了。您可以通过将模块路径替换为完全垃圾来检查这一点,您不会收到错误。

    一旦您解决了这个baseUrl 问题,使用var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js') 将按您的预期工作。因此,您将能够避免使用 require 的异步形式(这是使用依赖项数组作为第一个参数的形式)。 (您使用的 requirejs 函数只是 RequireJS 文档中通常称为 require 的函数的别名。)

    摩卡

    您的测试没有运行,因为 Mocha 没有看到它们。 Mocha 的工作方式是读取它找到的所有测试文件,然后执行它们。每个describe 调用的回调立即执行,每个it 调用的回调被记录为要运行的测试。一旦 Mocha 确定存在哪些测试,它就会运行它们。

    您的测试文件发生的情况是 Mocha 像往常一样执行它。但是,在测试文件的顶级范围内没有调用 describeit。您的回调中有对requirejs 的调用,但请记住我上面所说的:RequireJS 没有机会加载模块,因此它没有机会运行回调。 (即使它确实运行了,也为时已晚。)所以 Mocha 看不到任何测试并立即退出。

    前进的道路

    找出您需要的baseUrl,然后这应该可以工作:

    'use strict';
    var requirejs = require('requirejs');
    
    requirejs.config({
        baseUrl: <whatever value is needed here>,
        nodeRequire: require
    });
    
    var myObj = requirejs('mywidget/trunk/src/mywidgetfile.js');
    
    describe('My Widget', function() {
    // etc...
    

    您也可以考虑完全从您的测试套件中删除 RequireJS。我编写了一个在 Node 中和在浏览器中一样好用的库。它由 AMD 模块组成,由浏览器中的 RequireJS 加载,但我在测试套件中没有使用 RequireJS。这是我用来在 Node.js 中加载我的模块的loader。还有amdefine,我没用过,但应该提供类似的功能。

    【讨论】:

    • 谢谢你,@Louis。谢谢你的解释。这很有帮助,对我有用。由于某种原因,一件事不起作用的是baseUrl。我必须指定: var myObj = requirejs('../mywidget/trunk/src/mywidgetfile.js');而不是使用basePath。但其他一切都很好。谢谢!
    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多