2012-02-16 15 views
35

मैं समझने की कोशिश कर रहा हूं कि स्टैंड-अलोन जावास्क्रिप्ट कोड कैसे विकसित किया जाए। मैं कमांड लाइन से चल रहे परीक्षण और मॉड्यूल के साथ जावास्क्रिप्ट कोड लिखना चाहता हूं। तो मैंने पुस्तकालयों requirejs, underscore, और mocha के साथ node.js और npm स्थापित किया है।RequJS के साथ मोचा परीक्षण चलाते समय मुझे "परिभाषित परिभाषित नहीं किया गया" क्यों दिखाई देता है?

मेरे निर्देशिका संरचना इस तरह दिखता है:

> tree . 
. 
├── node_modules 
├── src 
│   └── utils.js 
└── test 
    └── utils.js 

जहां src/utils.js एक छोटे से मॉड्यूल है कि मैं, लिख रहा हूँ निम्न कोड के साथ है:

:

> cat src/utils.js 
define(['underscore'], function() { 

    "use strict"; 

    if ('function' !== typeof Object.beget) { 
     Object.beget = function (o) { 
      var f = function() { 
      }; 
      f.prototype = o; 
      return new f(); 
     }; 
    } 

}); 

और test/utils.js परीक्षा है

> cat test/utils.js 
var requirejs = require('requirejs'); 
requirejs.config({nodeRequire: require}); 

requirejs(['../src/utils'], function(utils) { 

    suite('utils', function() { 
     test('should always work', function() { 
      assert.equal(1, 1); 
     }) 
    }) 

}); 

जो मैं तब शीर्ष स्तर निर्देशिका से चलाने की कोशिश करता हूं (

> mocha 

node.js:201 
     throw e; // process.nextTick error, or 'error' event on first tick 
      ^
Error: Calling node's require("../src/utils") failed with error: ReferenceError: define is not defined 
    at /.../node_modules/requirejs/bin/r.js:2276:27 
    at Function.execCb (/.../node_modules/requirejs/bin/r.js:1872:25) 
    at execManager (/.../node_modules/requirejs/bin/r.js:541:31) 
    ... 

तो मेरी सवाल कर रहे हैं:

  • इस कोड की संरचना करने के सही तरीका है तो mochatest निर्देशिका) देखता है?
  • मेरा परीक्षण क्यों नहीं चल रहा है?
  • इस तरह की चीज़ सीखने का सबसे अच्छा तरीका क्या है? मुझे Google के साथ अच्छे उदाहरण खोजने में कठिनाई हो रही है।

धन्यवाद ...

[खेद - क्षण भर तैनात गलत कोड से परिणाम; अब तय किया गया]

पीएस मैं requjs का उपयोग कर रहा हूं क्योंकि मैं बाद में ब्राउज़र से यह कोड (या इसमें से कुछ) चलाने के लिए भी चाहता हूं।

अपडेट/समाधान

कुछ ऐसा जो नीचे दिए गए उत्तर में नहीं है कि मैं ऊपर परीक्षण शैली के लिए mocha -u tdd का उपयोग करने के लिए आवश्यक है। यहाँ अंतिम परीक्षण (जो भी ज़ोर की आवश्यकता है) और इसके उपयोग है:

> cat test/utils.js 

var requirejs = require('requirejs'); 
requirejs.config({nodeRequire: require}); 

requirejs(['../src/utils', 'assert'], function(utils, assert) { 

    suite('utils', function() { 
     test('should always work', function() { 
      assert.equal(1, 1); 
     }) 
    }) 

}); 
> mocha -u tdd 

    . 

    ✔ 1 tests complete (1ms) 
+0

मेरे लिए इसे काम करने के लिए, मुझे amdefine मॉड्यूल स्थापित करने और इन पंक्तियों को जोड़ने की आवश्यकता है coffeescript = >> परिभाषित = आवश्यकता ('amdefine') (मॉड्यूल) अगर (टाइप करें परिभाषित करें! = 'Function') << = में इसे बनाने के लिए मेरी 'कक्षा' फ़ाइल (परीक्षण फ़ाइल नहीं)। यह – devric

उत्तर

15

आपका परीक्षण नहीं चल रहा है क्योंकि src/utils.js मान्य Node.js लाइब्रेरी नहीं है।

RequireJS प्रलेखन के अनुसार, क्रम में Node.js साथ सह-अस्तित्व और CommonJS मानक की आवश्यकता होती है, तो RequireJS के define समारोह भरी हुई है तो आप अपने src/utils.js फ़ाइल के शीर्ष पर add a bit of boilerplate की जरूरत है।

:

हालांकि, बाद से RequireJS "क्लासिक" वेब ब्राउज़र उन्मुख स्रोत कोड की आवश्यकता के लिए सक्षम होने के लिए डिजाइन किया गया था, मैं अपने Node.js पुस्तकालयों है कि मैं भी ब्राउज़र में चल चाहते हैं के साथ निम्नलिखित पैटर्न का उपयोग करते हैं

if(typeof require != 'undefined') { 
    // Require server-side-specific modules 
} 

// Insert code here 

if(typeof module != 'undefined') { 
    module.exports = whateverImExporting; 
} 

इसका लाभ अन्य Node.js उपयोगकर्ताओं के लिए अतिरिक्त लाइब्रेरी की आवश्यकता नहीं है और आमतौर पर क्लाइंट पर RequJS के साथ अच्छी तरह से काम करता है।

एक बार जब आप अपना कोड Node.js में चलाते हैं, तो आप परीक्षण शुरू कर सकते हैं। मैं व्यक्तिगत रूप से अभी भी मोचा पर एक्सप्रेसो पसंद करता हूं, भले ही इसके उत्तराधिकारी परीक्षण ढांचे।

+1

परीक्षण के बाद इसे हटाने के लिए एक कार्य करने की आवश्यकता के बाद परेशान करने की तरह है! मुझे नहीं लगता कि आपको यह भी पता चलेगा कि मुझे "सूट" (मोचा से) को परिभाषित करने के लिए क्या करना है, क्योंकि बॉयलरप्लेट के साथ मेरा परीक्षण अब उस पर असफल हो जाता है? भी, क्या आप कह रहे हैं कि "परिभाषित" ब्राउज़र कोड के लिए काम नहीं करेगा? मैं ऊपर वैकल्पिक दृष्टिकोण के लिए आपकी प्रेरणा को समझ नहीं पा रहा हूं - क्या यह "बस" शैली का सवाल है? –

+0

आह, मैं आपका बिंदु देखता हूं - आप वेब ब्राउज़र के लिए नोड सामग्री को परिभाषित नहीं करना चाहते हैं। –

+0

यह बहुत कठिन नहीं है, आप '' आवश्यकता ('mocha') ''बॉयलरप्लेट' खो रहे हैं। [घोड़े के मुंह से सीधे लिया गया] (https://github.com/visionmedia/mocha/blob/master/test/suite.js) उत्तर है। (मैं स्टैक ओवरफ्लो में नया हूं, आपको नहीं पता था कि टिप्पणियों में आपके पास बहुभाषी स्रोत कोड नहीं हो सकता है।) –

-1

मैं का उपयोग नहीं करते requirejs तो मुझे यकीन है कि वाक्य रचना की तरह दिखता है क्या नहीं कर रहा हूँ, लेकिन यह मैं क्या कोड दोनों को चलाने के लिए करते हैं node भीतर और browser:

आयात के लिए, निर्धारित अगर हम या ब्राउज़र नोड में चल रहे हैं:

var root = typeof exports !== "undefined" && exports !== null ? exports : window; 

तो हम किसी भी निर्भरता सही ढंग से प्राप्त कर सकते हैं (वे या तो पहले से ही उपलब्ध हो जाएगा ब्राउज़र में या यदि हमका उपयोग करते हैं):

var foo = root.foo; 
if (!foo && (typeof require !== 'undefined')) { 
    foo = require('./foo'); 
} 

var Bar = function() { 
    // do something with foo 
} 

और फिर किसी भी कार्यक्षमता की जरूरत है कि अन्य फ़ाइलों द्वारा प्रयोग की जाने, हम इसे जड़ को निर्यात:

root.bar = Bar; 

उदाहरण के रूप में, GitHub एक महान स्रोत है।बस जाएं और अपनी पसंदीदा लाइब्रेरी के लिए कोड देखें कि यह कैसे किया गया :) मैंने जावास्क्रिप्ट लाइब्रेरी का परीक्षण करने के लिए mocha का उपयोग किया जो ब्राउज़र और नोड दोनों में उपयोग किया जा सकता है। कोड https://github.com/bunkat/later पर उपलब्ध है।

4

मोचा दस्तावेज में इस सामान को सेट करने के तरीके की कमी है, और यह हुड के तहत किए गए सभी जादू चालों के कारण पता लगाना मुश्किल है।

मैं require.js का उपयोग कर नोड के तहत मोचा में काम करने के लिए ब्राउज़र फ़ाइलें प्राप्त करने के लिए कुंजी पाया: मोचा है addFile के साथ फ़ाइलों को अपने सूट को जोड़ा गया है करने के लिए:

mocha.addFile('lib/tests/Main_spec_node'); 

और दूसरा, अतुल्यकालिक रूप से अपने मॉड्यूल लोड करने के लिए वैकल्पिक कॉलबैक साथ beforeEach का उपयोग करें:

describe('Testing "Other"', function(done){ 
    var Other; 
    beforeEach(function(done){ 
     requirejs(['lib/Other'], function(_File){ 
      Other = _File; 
      done(); // #1 Other Suite will run after this is called 
     }); 
    }); 

    describe('#1 Other Suite:', function(){ 
     it('Other.test', function(){ 
      chai.expect(Other.test).to.equal(true); 
     }); 
    }); 
}); 

मैं यह कैसे प्राप्त करने के लिए के लिए एक बूटस्ट्रैप बनाया सभी काम कर रहे हैं: https://github.com/clubajax/mocha-bootstrap

+0

+1 पहले से पहले requjs निर्भरता लोडिंग के समाधान के लिए +1 – bennidi

1

आप ब्राउज़र (एएमडी) के लिए डिज़ाइन किए गए जेएस मॉड्यूल को चलाने की कोशिश कर रहे हैं, लेकिन बैकएंड में यह काम नहीं कर सकता है (क्योंकि मॉड्यूल आमज तरीके से लोड होते हैं)। इस वजह से, आप दो मुद्दों का सामना करना पड़ेगा:

  1. परिभाषित परिभाषित नहीं है
  2. 0 परीक्षण चलाने

ब्राउज़र define में परिभाषित किया जाएगा। यह सेट किया जाएगा जब आपको आवश्यकता के साथ कुछ चाहिए। लेकिन नोडज सामान्य मॉड्यूल मॉड्यूल लोड करता है। इस मामले में define परिभाषित नहीं किया गया है। लेकिन जब हमें आवश्यकता के साथ आवश्यकता होती है तो यह परिभाषित किया जाएगा!

इसका मतलब है कि अब हमें कोड असीमित रूप से आवश्यक है, और यह दूसरी समस्या, एसिंक निष्पादन के साथ एक समस्या लाता है। https://github.com/mochajs/mocha/issues/362

यहां एक पूर्ण कार्य उदाहरण है। देखो कि मुझे मॉड्यूल लोड करने के लिए requjs (amd) को कॉन्फ़िगर करना था, हम अपने मॉड्यूल को लोड करने के लिए आवश्यकता (नोड/कॉमनजे) का उपयोग नहीं कर रहे हैं।

> cat $PROJECT_HOME/test/test.js 

var requirejs = require('requirejs'); 
var path = require('path') 
var project_directory = path.resolve(__dirname, '..') 

requirejs.config({ 
    nodeRequire: require, 
    paths: { 
    'widget': project_directory + '/src/js/some/widget' 
    } 
}); 

describe("Mocha needs one test in order to wait on requirejs tests", function() { 
    it('should wait for other tests', function(){ 
    require('assert').ok(true); 
    }); 
}); 


requirejs(['widget/viewModel', 'assert'], function(model, assert){ 

    describe('MyViewModel', function() { 
    it("should be 4 when 2", function() { 
     assert.equal(model.square(2),4) 
    }) 
    }); 

}) 

और मॉड्यूल आप परीक्षण करना चाहते हैं के लिए: शीर्ष करने के लिए

if (typeof define !== 'function') { 
    var define = require('amdefine')(module); 
} 

:

> cat $PROJECT_HOME/src/js/some/widget/viewModel.js 

define(["knockout"], function (ko) { 

    function VideModel() { 
     var self = this; 

     self.square = function(n){ 
      return n*n; 
     } 

    } 

    return new VideModel(); 
}) 
0

शायद ज़रुरत David's answer में काफी स्पष्ट नहीं था, मैं तो बस इस जोड़ने के लिए की जरूरत जेएस फ़ाइल का जहां मैं define का उपयोग करता हूं, जैसा कि आवश्यकताजेएस दस्तावेज़ ("Building node modules with AMD or RequireJS") में वर्णित है और उसी फ़ोल्डर में amdefine पैकेज जोड़ें:

npm install amdefine 

यह node_modules फ़ोल्डर amdefine मॉड्यूल के अंदर बनाता है।

संबंधित मुद्दे