2012-12-02 59 views
36

有沒有一種方法來創建一個javascript微型庫,支持以下所有模塊格式(即沒有依賴庫):同時支持CommonJS的和AMD

  • 異步模塊定義
  • CommonJS的
  • 暴露庫的輸出作爲一個全局命名空間對象(不加載)

回答

48

是的,我欠這個答案ded和他的真棒模塊:

(function(name, definition) { 
    if (typeof module != 'undefined') module.exports = definition(); 
    else if (typeof define == 'function' && typeof define.amd == 'object') define(definition); 
    else this[name] = definition(); 
}('mod', function() { 
    //This is the code you would normally have inside define() or add to module.exports 
    return { 
     sayHi: function(name) { 
      console.log('Hi ' + name + '!'); 
     } 
    }; 
})); 

這可以然後,可以使用:

  1. 在AMD

    (例如用requireJS):

    requirejs(['mod'], function(mod) { 
        mod.sayHi('Marc'); 
    }); 
    
  2. commonJS(例如,的NodeJS):

    var mod = require('./mod'); 
    mod.sayHi('Marc'); 
    
  3. 全球(例如,在HTML):

    <script src="mod.js"></script> 
    <script>mod.sayHi('Marc');</script> 
    

這種方法需要得到更多的宣傳 - 如果jQuery和合作。開始使用它的生活會容易得多!

+1

我不得不使用'定義(名稱,[ ],定義);在第3行,讓它與Curl一起工作。 – jcollum

+0

我將如何去添加依賴到'mod'模塊? –

+2

如果模塊具有我想要的相關性,這樣做會工作嗎?如果我在裏面做var x = require('./x');我希望在amd和node中正常工作,並且沒有加載程序,我想使用window.x –

1

只是爲了更新這個答案的問候一點點@marc我也給信貸DED並更新它有點與最新更新:年底

(function (name, definition, context, dependencies) { 
    if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); } 
    else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); } 
    else { context[name] = definition(); } 
})('events', function() { 
    // Insert code here 
    return { 
    sayHi: function(name) { 
     console.log('Hi ' + name + '!'); 
    } 
    }; 
}, (this || {})); 

對象是對父對象或當前作用域的引用,可以說你有一個你正在編寫的包,這只是一塊餡餅,而且上下文可能是一個名稱間隔的對象,而這只是該餡餅的一部分。另外,如果你希望有依賴關係,那麼在支持數組的範圍之後最後有一個可選參數,在這種情況下,定義參數可以利用每個依賴關係作爲參數。此外,爲方便起見,數組中列出的依賴項將在node-js平臺內部需要。

參見:https://gist.github.com/Nijikokun/5192472爲一個真實的例子。

0

我已經解決了這個確切的問題和管理,以輕鬆支持:

  • 道場AMD(引用RequireJS規格)
  • 的jQuery(下$/jQuery.fn [your_library_here]。)
  • 節點.js使用香草需要('path_to.js')
  • 瀏覽器窗口。[your_library_here]

它使用依賴注入和IIFE的組合來完成工作。

見下圖:

/*global jQuery:false, window:false */ 
// # A method of loading a basic library in AMD, Node.JS require(), jQuery and Javascript's plain old window namespace. 
(function(exporterFunction) { 
exporterFunction('cll', 
    function(a,b) { 
     return a+b; 
    } 
); 
})(
    (function() { // Gets an exportFunction to normalize Node/Dojo/jQuery/window.* 

     if ((typeof module != 'undefined') && (module.exports)) { // Node Module 
      return function(library_name,what_was_exported) { 
       module.exports = what_was_exported; 
       return; 
      }; 
     } 
     if (typeof define != 'undefined' && define.hasOwnProperty('amd') && define.amd) { // Dojo AMD 
      return function(library_name,what_was_exported) { 
       define(function() { 
        return what_was_exported; 
       }); 
      }; 
     } 
     if (typeof jQuery === 'function') { // jQuery Plugin 
      return function(library_name,source) { 
       jQuery.fn[library_name] = source; 
       return; 
      }; 
     } 
     if (typeof window != 'undefined') { // Fall down to attaching to window... 
      return function(library_name,what_was_exported) { 
       window[library_name] = what_was_exported; 
      }; 
     } 

    })(), 
    (function() { 
     // ## Other Parameters Here 
     // You could add parameters to the wrapping function, to include extra 
     // functionalilty which is dependant upon the environment... See 
     // https://github.com/forbesmyester/me_map_reduce for ideas. 
     return 'this_could_be_more_arguments_to_the_main_function'; 
    })() 
); 

公共要點可在https://gist.github.com/forbesmyester/5293746

7

uRequire,通用模塊&資源轉換器所做的正是該工具。

  • 主要轉換AMD和CommonJS的UMD/AMD/CommonJS的/純腳本(無需AMD裝載機)

  • 它允許模塊中的聲明性導出,用烘烤在noConflict()

  • 它可以操縱模塊(注入/更換/移除依賴關係或代碼)的同時建立它們。

  • 它從coffeescript,coco,Livescript,icedCoffeescript轉換而來,您可以在一行內添加自己的轉換!

+0

我無法使這個工具工作。看到我的其他[stackoverflow後有關它在這裏](http://stackoverflow.com/questions/35135935/cannot-run-javascript-umd-command-line-tool-typeerror-any-is-not-a-function) – sjdirect

0

這是基於Nijikokun的回答。由於RequireJS不鼓勵使用明確的模塊名,所以在這個版本中已經省略了。加載器的第二個參數描述依賴關係。如果你不需要加載任何文件,通過[]

var loader = function(name, dependencies, definition) { 
    if (typeof module === 'object' && module && module.exports) { 
     dependencies = dependencies.map(require); 
     module.exports = definition.apply(context, dependencies); 
    } else if (typeof require === 'function') { 
    define(dependencies, definition); 
    } else { 
    window[name] = definition(); 
    } 
}; 

loader('app', ['jquery', 'moment'], function($, moment) { 
    // do your thing 
    return something; 
} 
相關問題