2012-12-02 16 views
36

Czy istnieje sposób, aby utworzyć javascript mikro-Library (biblioteka, że ​​nie ma zależności), które obsługują wszystkie z następujących formatów modułów:wspieranie zarówno CommonJS i AMD

  • Asynchronous Moduł Definicja
  • CommonJS
  • narażając eksportu bibliotecznych jako globalnego obiektu przestrzeni nazw (bez ładowarki)

Odpowiedz

48

Tak, a zawdzięczam to odpowiedź na ded i jego niesamowite modułów:

(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 + '!'); 
     } 
    }; 
})); 

Może to następnie stosować:

  1. w AMD (np requireJS)

    requirejs(['mod'], function(mod) { 
        mod.sayHi('Marc'); 
    }); 
    
  2. w commonJS (np. nodeJS):

    var mod = require('./mod'); 
    mod.sayHi('Marc'); 
    
  3. globalnie (na przykład w HTML):

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

Metoda ta wymaga, aby uzyskać więcej rozgłosu - jeśli jQuery i co. zaczął używać go życie byłoby znacznie łatwiejsze!

+1

musiałem użyć 'define (imię, [ ], definition); 'on line 3, aby to działało z Curl. – jcollum

+0

Jak chciałbym dodać dodawanie zależności do modułu "mod"? –

+2

Czy to działa, jeśli moduł ma zależność, której chcę wymagać? Jeśli w środku robię var x = require ("./x"); Spodziewałabym się normalnie pracować w AMD i węźle, a bez ładowacza chciałbym użyć window.x –

1

Wystarczy zaktualizować trochę na tej odpowiedzi w odniesieniu do @marc ja też dać kredyt DED i zaktualizowaniu to trochę się z najnowszymi aktualizacjami:

(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 || {})); 

Object na końcu jest odniesieniem do rodzica lub bieżącego zakresu, powiedzmy, że masz paczkę, którą piszesz i jest to po prostu kawałek ciasta, dobrze, że kontekst może być obiektem z odstępem między nazwami i jest to tylko kawałek tego ciasta .

Ponadto, jeśli chcesz mieć zależności, istnieje opcjonalny parametr na końcu po twoim zasięgu, który obsługuje tablicę, w tym przypadku parametr definicji może wykorzystać każdą zależność jako argument. Ponadto zależności wyszczególnione w tablicy będą wymagane dla wygody użytkownika na platformie węzeł-js.

Zobacz: https://gist.github.com/Nijikokun/5192472 na prawdziwy przykład.

0

Mam rozwiązać dokładnie ten problem i udało się łatwo obsługiwać:

  • Dojo AMD (odwołanie do RequireJS specyfikacje)
  • jQuery (pod $/jQuery.fn [your_library_here].)
  • węzeł .js używający vanilla require ('path_to.js')
  • Okno przeglądarki.[your_library_here]

Używa kombinacji iniekcji zależności i IIFE, aby wykonać zadanie.

zobaczyć poniżej:

/*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'; 
    })() 
); 

Gist publiczny dostępny w https://gist.github.com/forbesmyester/5293746

7

uRequire, Uniwersalny Moduł & zasobów Converter jest narzędziem, które robi dokładnie to.

  • To głównie konwertuje AMD i CommonJS do UMD/AMD/CommonJS/plain skryptu (nie wymagane) AMD ładowarki.

  • Pozwala deklaratywny eksporcie modułów, z noConflict() pieczony w.

  • Można manipulować modułów (wstrzyknąć/wymiana/usunięcie zależności lub kod), jak je zbudować.

  • Konwertuje z coffeescript, coco, Livescript, icedCoffeescript i możesz dodać własne konwersje w jednym wkładzie!

+0

Nie mogłem uruchomić tego narzędzia. Zobacz mój inny post [stackoverflow o tym tutaj] (http://stackoverflow.com/questions/35135935/cannot-run-javascript-umd-command-line-tool-typeerror-any-is-not-a-function) – sjdirect

0

Jest to oparte na odpowiedzi Nijikokun. Ponieważ RequireJS zniechęca do używania jawnych nazw modułów, zostało to pominięte w tej wersji. Drugi argument modułu ładującego opisuje zależności. Przekaż [], jeśli nie musisz ładować żadnych.

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; 
} 
Powiązane problemy