2016-07-10 13 views
2

Ich habe ein Typoskript-Modul, das eine Drittanbieter-Bibliothek erfordert:TypeScript: Wie werden Importe durch Fensterobjekte ersetzt?

import Dexie from "dexie"; 

namespace storage { 
    ... 
} 

Wenn ich meine Typoskript-Datei kompilieren, erhalte ich die folgende JavaScript-Ausgabe:

"use strict"; 
var dexie_1 = require("dexie"); 
var storage; 
(function (storage) { 
    ... 
})(storage || (storage = {})); 

Ich bin mit dieser in Ordnung, bei der Verwendung von die Ausgabe in einer Node.js-Umgebung. Aber für die Verwendung in einem Browser möchte ich die var dexie_1 = require("dexie"); durch ein Objekt aus window wie ersetzen: var dexie_1 = window.Dexie;.

Kann ich die -Anweisung in meinem kompilierten JS durch ein Objekt aus window (globaler Namespace) ersetzen? Gibt es ein Gulp-Plugin oder etw. ähnlich herum?

Mein tsconfig.json ist dies:

{ 
    "compilerOptions": { 
    "module": "commonjs", 
    "moduleResolution": "node", 
    "target": "es5" 
    }, 
    "exclude": [ 
    "node_modules", 
    "typings/browser", 
    "typings/browser.d.ts" 
    ] 
} 
+0

könnten Sie evaluate to requirejs verwenden? – InferOn

Antwort

3

Webpack kann require("dexie"); zu window.Dexie zuordnen.

Alles, was Sie tun müssen, ist die folgende in Ihrem webpack.config.js zu erklären:

module.exports = { 
    externals: { 
    'dexie': 'Dexie' 
    } 
}; 

Hier ist eine Minimal Arbeitsbeispiel aus Gründen der Vollständigkeit halber:

Verzeichnislayout:

  • bower_components (Verzeichnis von bower install)
  • dist (Verzeichnis von gulp default)
  • node_modules (Verzeichnis von npm install)
  • src (Verzeichnis für Typoskript Quellcode)
  • Typisierungen (Verzeichnis von typings install)
  • bower.json (Frontend Abhängigkeiten)
  • gulpfile.js (Build-Konfiguration)
  • index.html
  • index.js (primären Einstiegspunkt für den Vertrieb)
  • package.json (Workflow und Bauabhängigkeiten)
  • tsconfig.json (Demo-Seite webpacked Code zu testen) (Maschinenschrift Compiler-Konfiguration)
  • webpack.config.json (Webpack Konfiguration)

src/storage.ts

/// <reference path="../typings/index.d.ts" /> 
import Dexie from "dexie"; 

namespace storage { 
    export function setupDatabase():void { 
    let db = new Dexie('MyDatabase'); 

    db.version(1).stores({ 
     friends: 'name, age' 
    }); 

    db.open().then(function() { 
     console.log('Initialized database: ' + db.name); 
    }); 
    } 
} 

module.exports = storage; 

bower.json

{ 
    "name": "storage", 
    "main": "dist/webpacked.js", 
    "private": true, 
    "dependencies": { 
    "dexie": "^1.4.1" 
    } 
} 

gulpfile.js

var gulp = require('gulp'); 
var rename = require('gulp-rename'); 
var runSequence = require('run-sequence'); 
var ts = require('gulp-typescript'); 
var tsProject = ts.createProject('tsconfig.json'); 
var webpack = require('webpack-stream'); 

gulp.task('build', function() { 
    return gulp.src('src/**/*.ts') 
    .pipe(ts(tsProject)) 
    .pipe(gulp.dest('dist')); 
}); 

gulp.task('webpack', function() { 
    return gulp.src('dist/index.js') 
    .pipe(webpack(require('./webpack.config.js'))) 
    .pipe(rename('webpacked.js')) 
    .pipe(gulp.dest('dist')); 
}); 

gulp.task('default', function (done) { 
    runSequence('build', 'webpack', done); 
}); 

index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="UTF-8" /> 
    <title>Demo</title> 
    <script src="bower_components/dexie/dist/dexie.js"></script> 
    <script src="dist/webpacked.js"></script> 
    </head> 
    <body> 
    <script> 
     document.addEventListener("DOMContentLoaded", function() { 
     storage.setupDatabase(); 
     }, false); 
    </script> 
    </body> 
</html> 

index.js

window.storage = require('./dist/storage'); 

package.json

{ 
    "name": "storage", 
    "private": true, 
    "devDependencies": { 
    "dexie": "^1.4.1", 
    "gulp": "^3.9.1", 
    "gulp-rename": "^1.2.2", 
    "gulp-typescript": "^2.13.6", 
    "run-sequence": "^1.2.2", 
    "webpack-stream": "^3.2.0" 
    } 
} 

tsconfig.json

{ 
    "compilerOptions": { 
    "module": "commonjs", 
    "moduleResolution": "node", 
    "target": "es5" 
    }, 
    "exclude": [ 
    "node_modules", 
    "typings/browser", 
    "typings/browser.d.ts" 
    ] 
} 

typings.json

{ 
    "globalDependencies": { 
    "node": "registry:dt/node#6.0.0+20160709114037" 
    } 
} 

Hinweis: Der node Eintrag stammt aus typings install dt~node --global --save und ist für Typoskript benötigt module in der module.exports Anweisung zu lösen.

webpack.config.js

module.exports = { 
    externals: { 
    'dexie': 'Dexie' 
    } 
}; 

Ansatz:

Typoskript Code Importe Dexie und erklärt sich den Namespace storage verwenden. Um der commonjs Art der Abhängigkeitsverwaltung (die in tsconfig.json deklariert ist) zu folgen, muss der TypeScript-Code den storage-Namespace als ein Modul mit der folgenden Adresse exportieren: module.exports = storage.

Weil TypeScript das module Objekt nicht kennt, müssen wir seine Definition bekommen. Die module Definition ist Teil der Typdefinition für node, die wir aus dem DefinitelyTyped Repository mit dem typings Tool unter Verwendung typings install dt~node --global --save erhalten. Um die abgerufene Typdefinition des Knotens in TypeScript zu verknüpfen, müssen wir /// <reference path="../typings/index.d.ts" /> deklarieren.

Nachdem wir unseren TypeScript-Code kompiliert haben (unter Verwendung von gulp build), müssen wir einen Einstiegspunkt deklarieren, um unseren Code zugänglich zu machen. Dies wird in index.js getan. Ein erfolgreicher Build gibt unsere dist/storage.js Datei aus, die in index.js referenziert wird.

Wenn der Build an Ort und Stelle ist, können wir unseren Code webpacken (um ihn für einen HTML5-Browser zu bündeln). Unser webpack.config.js bildet den "require" Namen unserer Abhängigkeit (dexie) auf ein Objekt aus dem globalen Namespace ab (window.Dexie). Dies garantiert uns, dass Dexie nicht Bestandteil unseres kompilierten Codes (dist/webpacked.js) ist. Wenn wir webpacked.js haben, können wir es in einem Browser verwenden. Aber wir müssen sicherstellen, dass alle externen Abhängigkeiten in unserer HTML-Seite referenziert sind (deshalb wird Dexie auch als eine Frontend-Abhängigkeit deklariert, die Bower verwendet).

3

Wie Importe mit Fensterobjekte ersetzen?

Es ist nicht möglich. Es gibt zwei Möglichkeiten:

Verwenden globale Objekte

im Browser, wenn ein Objekt durch ein <script> geladen wird, Ihr Code verwendet es als eine globale Variable. In TypeScript müssen Sie eine globale Deklarationsdatei verwenden. Module werden hier nicht verwendet, daher gibt es keine import zu tun.

einen Bündler oder einen Loader verwenden

Sie einen Bündler, for example Webpack verwenden können. Oder a loader like SystemJS.

Verwandte Themen