2015-09-14 11 views
5

Im normalen ES5, wenn ich ein Paket an Autor möchte die Verwendung auf beiden Server-Seite sein könnte (über CJS, AMD, RequireJS) oder Browser, würde ich so etwas tun:Wie erstellen Sie ein Modul, das in ES6 mit Babel kompatibel mit CommonJS, AMD und Browser ist?

(function(name, definition)){ 
    if (typeof exports !== 'undefined' && typeof module !== 'undefined') { 
     module.exports = definition(); 
    } else if (typeof define === 'function' && typeof define.amd === 'object') { 
     define(definition); 
    } else { 
     this[name] = definition(); 
    } 
}('foo', function foo(){ 
     'use strict'; 

     return 'foo'; 
}) 

Wie würde ich erreichen diese Funktionalität beim Schreiben eines Pakets in ES6?

Was ich versucht:

if (typeof exports !== 'undefined' && typeof module !== 'undefined') export Foo; 
else if (typeof define === 'function' && typeof define.amd === 'object') define(Foo); 
else this['Foo'] = Foo; 

Während dieser transpiling, Babel wirft mir einen Fehler:

SyntaxError: src/index.js: 'import' and 'export' may only appear at the top level (10:69) 
    9 | 
> 10 | if (typeof exports !== 'undefined' && typeof module !== 'undefined') export Foo; 
    |                 ^
    11 | else if (typeof define === 'function' && typeof define.amd === 'object') define(Foo); 
    12 | else this['Foo'] = Foo; 
    13 | 

es funktionierte, als ich module.exports statt export verwendet, aber ist es möglich, dies streng zu tun mit ES6?

+2

Dies wird auch UMD, * Universal Module Definition * genannt. Könnte Ihrer Suche ein wenig helfen :-) – Bergi

+0

Sie sollten diesen Code nicht selbst schreiben müssen. Sie sollten einfach die ES6-'Export'-Deklaration in Ihre Quelle einfügen. Die UMD sollte vom Transpiler daraus generiert werden. – Bergi

+2

https://babeljs.io/docs/usage/modules/ ... alles ist in der Dokumentation. –

Antwort

1

So gibt es keine wirkliche Möglichkeit, ES6 Module in einer Universal-Moduldefinition zu schließen, weil ES6 Module streng ein pro Datei ist und alle Importe und Export-Anweisungen müssen auf der obersten Ebene sein.

Wenn die Loader-Spezifikation fertig ist, gibt es wahrscheinlich eine Möglichkeit, ein Modul in die Registrierung hinzuzufügen, und das wäre, wie Sie ES6-Module in eine UMD aufnehmen würden, bis keine Browser tatsächlich ES6-Module unterstützen Ziele sind AMD und CommonJS, aber Sie sollten einen der vielen Compiler oder trsnspilers wie browserify oder Babel verwenden, um das für Sie zu tun.

+0

was meinst du mit "Alle Import und Export Anweisungen müssen auf der obersten Ebene sein", ich habe diesen Fehler für meine Anwendung, aber habe es nicht verstanden, ich habe eine Datei namens main.js, und die ersten beiden Zeilen in Es sind die Import-Statements, also was ist das "Top-Level" erforderlich! –

+0

Import- und Exportanweisungen können nicht innerhalb von Funktionskörpern, Schleifen oder if/else-Blöcken liegen. ok 'import foo von 'bar',' nicht ok 'if (etwas) { import foo von 'bar'; } else { import foo von 'baz'; } – Calvin

0

Sie werden keinen universellen Ausgang haben, aber StealJS kann Ihr Babel transpiliertes ES6-Projekt nach CommonJS, AMD und als eigenständiges Gerät exportieren. Für CommonJS und AMD wird Ihre ursprüngliche Modulstruktur beibehalten, so dass Sie immer nur die Abhängigkeiten laden können, die Sie wirklich benötigen.

Die project exporting Anleitung erklärt es in etwas genauer, aber wenn das NPM-Workflow ist dies, wie Sie Ihre Build-Skript aussieht (es wird auch CSS/LESS/SASS und andere Abhängigkeiten bauen, wenn enthalten):

{ 
    dist: { 
     system: { 
      config: "package.json!npm" 
     }, 
     outputs: { 
      "+cjs": {}, 
      "+amd": {}, 
      "+global-js": {}, 
      "+global-css": {} 
     } 
    } 
}