Pytanie Różnica między RequireJS a CommonJS


Zastanawiam się, jaka jest różnica między tymi fragmentami.

var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');

i

require(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
})

Oba działają dobrze dla mnie, ale nie jestem pewny, czy mają jakiś cel za tymi dwoma.


14
2018-01-09 13:29


pochodzenie


Myślę, że pierwszą jest składnia commonJS, a druga to AMD, częściej widziane z plikami requireJS. - Andy
Na pewnym tle możesz przeczytać Wymagaj dokumentów JS omawianie stylu CommonJS (pierwszy kod) vs. AMD (drugi kod). - Gábor Imre
RequireJS jest podobny do Browserify i WebPack - jest to moduł ładujący modułu JS. AMD to standard / spec dla RequireJS, który jest podobny do CommonJS. - Alexander Mills


Odpowiedzi:


Zastanów się nad pierwszym fragmentem, który jest w stylu CommonJS:

var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');

Te połączenia są połączeniami synchronicznymi: kiedy require zwraca, zwraca żądany moduł. CommonJS require połączenia są synchroniczne. Istnieje propozycja obsługi form asynchronicznych require ale o ile ja móc powiedzieć nie przekroczył poziomu propozycji. Node.js miał kiedyś require.async który został usunięty. Jest jeden pakiet ale to implementuje. Używanie tego pakietu wygląda podobnie jak używanie modułów w stylu AMD.

Rozważmy teraz drugi fragment, który jest w stylu AMD:

require(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
})

Ponieważ RequireJS implementuje system modułowy typu AMD, powyższy kod działa z RequireJS. To require call jest --- jak sugeruje nazwa Asynchronous Module Definition (AMD) --- asynchroniczne. Nie można polegać na zwracanej wartości require aby uzyskać wartość modułu. Zamiast tego należy użyć wywołania zwrotnego. The define połączenie działa w podobny sposób, ale oprócz modułu wymaga zdefiniowania modułu.

Teraz, jeśli używasz RequireJS, zapewnia on urządzenia, które pozwalają na użycie obu stylów podczas definiowania modułów, dzięki czemu można zdefiniować taki moduł:

define(['jquery','underscore','backbone'],function ($, _, BackBone){
    //code goes here
});

Lub użyj czegoś, co wygląda bardziej jak idiom CommonJS:

define(function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var BackBone = require('backbone');
    //code goes here
});

Ułatwia to konwersję modułu stylu CommonJS do użycia z RequireJS: po prostu zapakuj go za pomocą define zadzwoń jak powyżej. Jest jeden narzędzie aby pomóc w konwersji.

Za kulisami RequireJS odczytuje kod wywołania zwrotnego w drugiej formie i tworzy listę zależności, tak aby w końcu została zinterpretowana jak:

define(['require', 'jquery','underscore','backbone'], function (require) {
    var $ = require('jquery');
    var _ = require('underscore');
    var BackBone = require('backbone');
    //code goes here
})

Może to być zaskakujące (biorąc pod uwagę, że AMD jest asynchroniczne), że require wywołania w oddzwanianiu są synchroniczne. Jest to część obsługi RequireJS dla stylu CommonJS. RequireJS obsługuje rodzaj synchronizacji require zadzwoń, ale z następującym zastrzeżeniem: jeśli moduł jest już zdefiniowane przed wywołaniem synchronicznym require, a następnie synchroniczny require zwraca wartość modułu, ale w przeciwnym razie nie powiedzie się natychmiast. To znaczy, że tak nie jest próbować załadować moduł. Ponieważ RequireJS interpretuje definicję modułu, która używa stylu CommonJS, jak pokazano powyżej - tak jakby zależności były faktycznie wymienione w define argumenty --- wtedy te moduły są gwarantowane do załadowania przez czas synchronicznych wywołań require są zrobione.

Poza możliwością korzystania z modułów CommonJS w RequireJS (pod warunkiem dodania wrappera) możliwe jest również użycie modułów zaprojektowanych dla RequireJS w środowisku CommonJS takim jak Node.js. Na przykład użyłem node-amd-loader załadować moduły zaprojektowane przeze mnie jako moduły AMD w pliku Node.js.


22
2018-01-09 14:38



To znacznie lepsza odpowiedź niż to, co napisałem. - Achrome
to jest doskonała odpowiedź - Alexander Mills


Poprzedni fragment jest zgodny ze specyfikacją CommonJS, która określa, w jaki sposób moduły mają być eksportowane / transportowane do użycia w innych modułach.

Więc możesz napisać kod, który mógłby wyglądać tak

src / ExpressModule.js

var express = require('express');
// do initialization
exports.express = express;

A potem możesz go użyć w ten sposób

src / UserExpressModule.js

var express = require('./ExpressModule');
// do something else

Specyfikacja CommonJS została zbudowana głównie dla środowisk po stronie serwera, a przez rozszerzenie jest używana w Node.js

Z drugiej strony spektrum to AMD, w szczególności implementowane przez RequireJS. AMD zostało zbudowane dla środowisk przeglądarkowych lub kodu po stronie klienta, a tutaj możesz używać i definiować moduły takie jak ten ostatni w swoim kodzie

Przykład użycia może być podobny

src / main.js

requirejs.config({
    baseUrl: '../vendor'
    path: '../src'
});
require(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
    // do some client side computation here
});

Możesz to uwzględnić main.js plik w swoim index.html, tak jak

<script data-main="src/main.js" src="vendor/require.js"></script>

Zasadniczo, CommonJS i AMD są w swoich podstawowych specyfikacjach dla modularyzacji Javascript, ale są skierowane do różnych środowisk wykonawczych.


1
2018-01-09 13:51