2016-07-10 10 views
2

Я создал модуль машинописи, который требует библиотеки третьей стороны:TypeScript: Как заменить импорт объектами окна?

import Dexie from "dexie"; 

namespace storage { 
    ... 
} 

Когда я компилирую мой файл машинопись, я получаю следующий вывод JavaScript:

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

Я нахожусь в порядке с этим при использовании вывод в среде Node.js. Но для использования в браузере я хочу заменить var dexie_1 = require("dexie"); на объект с window: var dexie_1 = window.Dexie;.

Можно ли заменить оператор require в моем скомпилированном JS объектом с window (глобальное пространство имен)? Есть ли плагин Gulp или sth. похожий вокруг?

Мой tsconfig.json это:

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

Вы можете оценить, как использовать requirejs? – InferOn

ответ

3

Webpack can map require("dexie"); до window.Dexie.

Все, что вам нужно сделать, это заявить следующее в вашем webpack.config.js:

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

Вот это Minimal Рабочего примера для полноты картины:

Расположение:

  • bower_components (Каталог из bower install)
  • расстояния (каталог из gulp default)
  • node_modules (каталог из npm install)
  • ЦСИ (каталог для исходного кода машинописи)
  • типизации (каталог из typings install)
  • bower.json (Фронтальные зависимости)
  • gulpfile.JS (Build конфигурации)
  • index.html (демонстрационную страницу, чтобы проверить webpacked код)
  • index.js (основной точкой входа для распределения)
  • package.json (рабочий и построить зависимости)
  • tsconfig.json (конфигурация компилятор машинописи)
  • webpack.config.json (конфигурация Webpack)

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" 
    } 
} 

Примечания: node запись происходит от typings install dt~node --global --save и необходима для Машинописи для решения module в module.exports заявления.

webpack.config.js

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

подход:

машинописи импорта кода Dexie и заявляет о себе с помощью пространства имен storage. Чтобы следовать методу управления зависимостями commonjs (который объявлен в tsconfig.json), код TypeScript должен экспортировать пространство имен storage в качестве модуля с: module.exports = storage.

Поскольку TypeScript не знает объект module, нам нужно получить его определение. Определение module является частью определения типа для node, которое мы получаем из репозитория DefinitelyTyped с помощью инструмента typings с использованием typings install dt~node --global --save. Чтобы связать обнаруженное определение типа узла в TypeScript, нам нужно объявить /// <reference path="../typings/index.d.ts" />.

После того, как мы скомпилируем наш код типа TypeScript (используя gulp build), нам нужно объявить точку входа, чтобы сделать наш код доступным. Это делается в index.js. Успешная сборка выводит наш файл dist/storage.js, на который ссылаются в index.js.

При создании на месте мы можем webpack наш код (чтобы связать его для браузера HTML5). Наш webpack.config.js отображает «требуемое» имя нашей зависимости (dexie) объекту из глобального пространства имен (window.Dexie). Это гарантирует нам, что Dexie не является частью нашего скомпилированного кода (dist/webpacked.js).

Как только у нас есть webpacked.js, мы можем использовать его в браузере. Но мы должны убедиться, что все внешние зависимости указаны на нашей HTML-странице (поэтому Dexie также объявляется как зависимость внешнего интерфейса, используя Bower).

3

Как заменить импорт с оконными объектами?

Невозможно. Есть два варианта:

Использовать глобальные объекты

В браузере, когда объект нагружен <script>, ваш код использует его в качестве глобальной переменной. В TypeScript вы должны использовать файл глобальной декларации. Модули здесь не используются, поэтому нет import.

Используйте Bundler или погрузчик

Вы можете использовать Bundler, for example Webpack. Или a loader like SystemJS.