0

So nach einem Tag des Testens bin ich fast da: mit google-closure-compiler-js und gulp.js, um meine ES6-Modul-basierte "Bibliothek" zu minimieren/kompilieren.Verwenden von Closure Compiler auf ES6-Module mit Eigenschaften

Es gibt nur noch ein Problem. Wie ruft man die Eigenschaften eines importierten Moduls auf?

Mein Testfall besteht aus 3 Dateien:

gulpfile.js

const gulp = require("gulp"); 
const compiler = require("google-closure-compiler-js").gulp(); 
const sourcemaps = require("gulp-sourcemaps"); 

gulp.task("default", function() { 
// wildcards don't seem to work yet with the js version 
// files need to be in reverse order of dependency... 
return gulp.src(["src/boilerplate/main.js", "src/app.js"]) 
    .pipe(sourcemaps.init()) 
    .pipe(compiler({ 
     jsOutputFile: "app.min.js", 
     compilationLevel: "ADVANCED", 
     warningLevel: "VERBOSE", 
     createSourceMap: true 
    })) 
    .pipe(sourcemaps.write("/")) 
    .pipe(gulp.dest("./dist")); 
}); 

src/boilerplate/main.js

var mod = {}; 
export default mod; 

var foo = "FOO"; 
var bar = "BAR"; 

function foobar(join) { 
    join = (typeof join === "string") ? join : ""; 
    return foo + join + bar; 
} 
Object.defineProperty(mod, "foobar", {value: foobar}); 

src/app.js

import boilerplate from "./boilerplate/main.js"; 

console.log(boilerplate["foobar"]("+")); 
console.log(boilerplate.foobar("+")); 

Wenn Sie boilerplate hier einloggen, sehen Sie, dass es die Eigenschaft "foobar" hat. Symbol intakt und alles. Groß!

Daher app.js erste Aufruf - Klammernotation ["Foobar"] - funktioniert einwandfrei. Die Punktnotation jedoch nicht. Aufrufe an die Eigenschaft eines importierten Moduls werden vom Closure Compiler minimiert!
Sie erhalten Ihren klassischen "Hallo. Ich bin neu im ADVANCED-Modus" Fehler: TypeError: a.a is not a function.

Wie verhindere ich das? (& nehmen wir an, foobar Export ist nicht direkt lebensfähig, für reale Welt willen.)

  • Muss ich eine Exporte Datei? Wie genau würde ich das tun? Meine ersten Unternehmungen in diese Richtung haben mich nicht weit gebracht ... Gibt es einen spezifischen Trick zu google-closure-compiler-js?

  • Gibt es eine Art von Hack, der Punktnotation ermöglicht, bis Closure Compiler eine Funktion hinzufügt, die Aufrufe von Importeigenschaften automatisch nicht umbenennt?

  • Und was ist das closure-compiler/wiki 's Artikel über JS-Module # Typ-Referenzen beraten mich zu tun? Ist das die Antwort, die ich nicht umsetze?

    /** @param {foo.Foo} Foo */ function(Foo) {}

+2

Aus Gründen der Neugier, warum verwenden Sie ein "Mod" -Objekt, anstatt nur einen benannten Export zu verwenden? Das wird unter anderem das Treeschütteln verhindern. –

+1

Warum brauchen Sie 'Object.defineProperty'?Sie können Ihr Modul leicht auf diese Weise definieren: 'var mod = {foobar};' – Andy

+0

@ T.J.Crowder teilweise aus diesem Grund, um treeshaking zu verhindern; wenn ich eine Bibliothek erstellen möchte, die in einer verkleinerten Version vertrieben wird - das wäre wünschenswert? Und die andere Sache ist, dass ich testen wollte, wie man tatsächlich ein Objekt exportiert und darauf zugreift. Zugegeben, hier macht es keinen Sinn !, mit der Foobar-Funktion. –

Antwort

1

Für ADVANCED Modus Kompatibilität verwenden Object.defineProperties Strings in Anführungszeichen zu vermeiden.

Object.defineProperties(mod, { 
    foobar: {value: foobar} 
}); 

Immer, wenn Sie Strings in Anführungszeichen verwenden, werden Sie aufgefordert Klammern (oder andere Techniken) oder Risiko der konsistenten Eigenschaft Zugriffsregeln zu verletzen.

+0

Ja! Heiliger Rauch. Das war das fehlende Stück. Tausend Dank. –

Verwandte Themen