web-dev-qa-db-ja.com

CommonJSとAMDの両方をサポート

次のすべてのモジュール形式をサポートするjavascriptマイクロライブラリ(依存関係のないライブラリ)を作成する方法はありますか?

  • 非同期モジュールの定義
  • CommonJS
  • ライブラリのエクスポートをグローバル名前空間オブジェクト(ローダーなし)として公開する
36
slobo

これが さまざまな相互互換モジュール形式のリスト です。

あなたが探しているのは彼らが呼んでいるものだと思います " commonjsStrict.js "

22
Lee

はい、そして私はこの答えを 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とcoの場合、より多くの宣伝を得る必要があります。それを使い始めた人生ははるかに簡単でしょう!

50
Marc

Require 、Universal Module&Resource Converterは、まさにそれを行うツールです。

  • 主にAMDとCommonJSUMD/AMD/CommonJS /プレーンスクリプト(AMDローダーは不要)に変換します

  • noConflict()をベイクインして、モジュールの宣言型エクスポートを可能にします。

  • モジュールを構築するときに、モジュールを操作(依存関係の挿入/置換/削除ORコード))できます。

  • これは、coffeescript、coco、Livescript、icedCoffeescriptから変換され、1つのライナーで独自の変換を追加できます。

7

@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 を参照してください。

1
Nijikokun

私はこの正確な問題を解決し、簡単にサポートすることができました:

  • Dojo AMD(RequireJS仕様を参照)
  • jQuery($/jQuery.fn。[your_library_here]の下)
  • vanillaを使用するnode.jsrequire( '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 で入手できます。

0
Forbesmyester

これは、ニジコクンの答えに基づいています。 RequireJSは明示的なモジュール名の使用を推奨していないため、このバージョンではこれが省略されています。ローダーの2番目の引数は、依存関係を記述します。パス []何もロードする必要がない場合。

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;
}
0
monken