2012-02-09 24 views
5

Im bắt đầu để loại quấn quanh đầu tôi requirejs và cấu trúc Dojo AMD mới, nhưng tôi có một vấn đề với một số xét nghiệm sớm:Tại sao cú pháp đơn giản hóa CommonJS Wrapper không hoạt động trên mô-đun Dojo AMD của tôi?

cg/signup.js:

define(['dojo/_base/fx', 'dojo/dom'], function(fx, dom){  
    return function(){ 
     this.hidePreloader = function(id){ 
      var preloader = dom.byId(id); 
      fx.fadeOut({node : preloader}).play() 
     } 
    } 
}) 

này hoạt động tốt. Trong tệp cg.js chính:

require(['dojo/_base/kernel', 'dojo/_base/loader']) 
dojo.registerModulePath('cg', '../cg') 

require(['cg/signup', 'dojo/domReady!'], function(Signup){ 
     var sp = new Signup(); 
     sp.hidePreloader('preloader') 
}) 

Bam. Làm xong. Tuy nhiên, trong việc sử dụng cấu trúc giản CommonJS Wrapper:

define(function(require){  
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    return function(){ 
     this.hidePreloader = function(id){ 
      var preloader = dom.byId(id); 
      fx.fadeOut({node : preloader}).play() 
     } 
    } 
}) 

tôi nhận được một lỗi undefinedModule. Nó dường như đến từ dòng dojo/_base/fx, nhưng tôi không biết tại sao.

CẬP NHẬT

Để làm rõ.

index.html script

<script type="text/javascript" src="js/dojo/dojo.js.uncompressed.js" data-dojo-config="isDebug:true,async:true"></script> 
<script type="text/javascript" src="js/cg.js"></script> 

cg.js

require(['dojo/_base/kernel', 'dojo/_base/loader']) 
dojo.registerModulePath('cg', '../cg') 

require(['cg/signup', 'dojo/domReady!'], function(signup){ 
    signup.testFunc() 
}) 

js/cg/signup.js

define(['require', 'exports'], function(require, exports){ 
    var dom = require('dojo/_base/kernel'); 
// Any other require() declarations (with very very few exceptions like 'dojo/_base/array throw undefinedModule errors!!! 

    // without any error causing requires, this works fine. 
    exports.testFunc = function(){ 
     alert("hello") 
    } 
}) 
+0

Hmm, một biến thể hơi khác nhau dường như làm việc trên JSFiddle. (Nhưng tôi không thể liên kết với nó ngay bây giờ vì JSFiddle đang ở chế độ chỉ đọc.) Bạn có thể cung cấp thêm chi tiết về lỗi chính xác không? – Domenic

+0

Đó là lỗi chính xác. Bằng cách sử dụng kỹ thuật đơn giản hóa CommonJS Wrapper với cùng một đường dẫn và cùng một câu lệnh require, giao diện điều khiển sẽ in ra một lỗi 'undefinedModule'. Tôi có 'isDebug = true' trong tập lệnh cấu hình và' debugAtAllCosts' không ném thêm gì nữa. Biến thể hoạt động cho bạn là gì? – Phix

+0

Tôi không thể tách thành nhiều tệp trên JSFiddle vì vậy tôi đã thử 'define (" foo ", function (require) {...})' trong đó '...' chứa các câu lệnh require của bạn, cộng với 'console.log' s cho các đối tượng 'fx' và' dom'. Hai đối tượng điên rồ đã đăng nhập vào giao diện điều khiển ... Dojo 1.7.1? – Domenic

Trả lời

3

dojo hỗ trợ hoàn toàn định dạng đơn giản CommonJS Wrapper. tuy nhiên, có một điều kiện tiên quyết ... bạn không có mảng phụ thuộc.

define(function (require, exports, module) { 
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 

này sẽ KHÔNG làm việc như nhau

define(['require', 'exports', 'module'], function (require, exports, module) { 
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 

cũng sẽ này ...

// in this case require, exports and module will not even exist 
define([], function (require, exports, module) { 
     var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 
+0

Cảm ơn bạn đã thêm vào cuộc trò chuyện này, tôi sẽ phải mở dự án đó và thực hiện một số thử nghiệm khác. Đó là một thông báo thú vị, bạn có biết thêm về lý do tại sao không? – Phix

+1

nó được thực hiện theo cách này bởi vì để hỗ trợ định dạng này, các chức năng cơ thể cần phải được quét để sử dụng (s) của 'require (...)' và rằng thêm một số chi phí. để tránh chi phí trên không cần thiết, bạn cần phải "báo hiệu" cho bộ tải mà bạn đang (hoặc không phụ thuộc vào quan điểm của bạn) bằng cách sử dụng định dạng này. "tín hiệu" mà bạn đang sử dụng định dạng này không có mảng phụ thuộc - đó là lý do tại sao một mảng phụ thuộc trống khác với không có chút nào. – neonstalwart

+0

Tôi đã thử ví dụ đơn giản này trong dojo 1.8.3 và nó không hoạt động chút nào. –

1

require được xác định? Tôi không thấy giá trị đối số đó đến từ đâu. Tôi nghĩ bạn có thể phải làm điều gì đó như

define(["require"], function(require){ ... 
+0

Không, nó hoạt động với 'dojo/_base/kernel' nhưng không phải' dojo/_base/fx', do đó yêu cầu được xác định. – Phix

1

Tôi bắt đầu nghĩ rằng có lẽ tôi không có ý định học Dojo. Nhưng, tất cả đi kèm với một chút đọc nhiều hơn. Tôi không chắc chắn chính xác những gì tôi đã làm khác nhau hoặc bất cứ điều gì, nhưng đây là cách bố trí làm việc.

script index.html và cấu hình

<script type="text/javascript"> 
dojoConfig = { 
    async : true, 
    isDebug : true, 
    debugAtAllCosts : true, 
    packages : [{ 
     name : 'cg', 
     location : '/../js/cg' 
    }] 
} 
</script> 
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"></script> 
<script type="text/javascript" src="js/cg.js"></script> 

js/cg.js

require(['cg/signup', 'dojo/ready'], function(signup){ 
    signup.init('preloader') 
}) 

js/cg/signup.js

define(['dojo', 'require'], function(dojo, require){ 
    var fx = require('dojo/_base/fx') 

    return new function(){  
     this.init = function(id){ 
      fx.fadeOut({node : dojo.byId(id)}).play() 
     } 
    } 
}) 

Again , n ot hoàn toàn chắc chắn lý do tại sao các tuyên bố var fx = require(...) hoạt động khác nhau trong này hơn những người khác, có thể là xây dựng tôi tải về so với CDN, những người quan tâm. Nó hoạt động.Một số liên kết Tôi sử dụng để giúp cho những người khác có thể trong cùng một thuyền:

Writing Modular JS

AMD vs CommonJS Wrapper

Dojo Toolkit AMD

Dojo Config (1.7)

2

Dưới đây là một chút wrapper xung quanh Dojo xác định có sử dụng mã lấy từ RequireJS để tính toán các phụ thuộc dựa trên hàm toString của hàm định nghĩa. Nó bao bọc "định nghĩa" hiện tại trong không gian tên chung, tính toán các phụ thuộc và sau đó gọi định nghĩa được bao bọc.

defineWrapper.js:

// Workaround for the fact that Dojo AMD does not support the Simplified CommonJS Wrapper module definition 
(function() { 
    var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, 
     cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g, 
     ostring = Object.prototype.toString; 
    function isArray(it) { 
     return ostring.call(it) === '[object Array]'; 
    } 
    function isFunction(it) { 
     return ostring.call(it) === '[object Function]'; 
    } 
    var oldDefine = define; 

    define = function(name, deps, callback) { 
     //Allow for anonymous functions 
     if (typeof name !== 'string') { 
      //Adjust args appropriately 
      callback = deps; 
      deps = name; 
      name = null; 
     } 

     //This module may not have dependencies 
     if (!isArray(deps)) { 
      callback = deps; 
      deps = []; 
     } 

     //If no name, and callback is a function, then figure out if it a 
     //CommonJS thing with dependencies. 
     if (!deps.length && isFunction(callback)) { 
      //Remove comments from the callback string, 
      //look for require calls, and pull them into the dependencies, 
      //but only if there are function args. 
      if (callback.length) { 
       callback 
        .toString() 
        .replace(commentRegExp, '') 
        .replace(cjsRequireRegExp, function(match, dep) { 
         deps.push(dep); 
        }); 

       //May be a CommonJS thing even without require calls, but still 
       //could use exports, and module. Avoid doing exports and module 
       //work though if it just needs require. 
       //REQUIRES the function to expect the CommonJS variables in the 
       //order listed below. 
       deps = (callback.length === 1 ? ['require'] : 
        ['require', 'exports', 'module']).concat(deps); 
      } 
     } 

     if(name === null) { 
      return oldDefine(deps, callback); 
     } else { 
      return oldDefine(name, deps, callback); 
     } 
    } 
})(); 

Làm thế nào bạn sẽ sử dụng nó?

<script src="...dojo..."></script> 
<script src="defineWrapper.js"></script> 
<script>require(["some_simplified_commonjs_defined_module"], function(module) { 
    // use module here 
});</script> 
2

Lưu ý rằng Dojo không hỗ trợ CommonJS đơn giản hóa phong cách để phát hiện sự phụ thuộc khi thực hiện một xây dựng . Điều này có nghĩa là bạn sẽ cần phải sử dụng kiểu danh sách phụ thuộc bình thường, hoặc bạn sẽ phải sao chép tất cả các phụ thuộc của bạn khi xác định các lớp trong hồ sơ xây dựng.

Dưới đây là các lỗi liên quan theo dõi của họ:

http://bugs.dojotoolkit.org/ticket/15350

+0

do dojo 1.9.0 hiện được hỗ trợ trong bản dựng – neonstalwart

Các vấn đề liên quan