3

我创建了一个需要第三方库的 TypeScript 模块:

import Dexie from "dexie";

namespace storage {
  ...
}

当我编译我的 TypeScript 文件时,我得到以下 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 插件或某事。周围类似吗?

我的tsconfig.json是这样的:

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

2 回答 2

3

Webpack可以映射require("dexie");window.Dexie.

您所要做的就是在webpack.config.js中声明以下内容:

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

为了完整起见,这是一个最小的工作示例

目录布局:

  • bower_components(来自的目录bower install
  • dist(来自的目录gulp default
  • node_modules(来自的目录npm install
  • src(TypeScript 源代码目录)
  • 打字(目录来自typings install
  • bower.json(前端依赖项)
  • gulpfile.js(构建配置)
  • index.html(用于测试 webpacked 代码的演示页面)
  • index.js(分发的主要入口点)
  • package.json(工作流程和构建依赖项)
  • tsconfig.json(TypeScript 编译器配置)
  • 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;

鲍尔.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);
});

索引.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');

包.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"
  ]
}

打字.json

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

注意:该node条目来自typings install dt~node --global --save并且是 TypeScriptmodulemodule.exports语句中解析所必需的。

webpack.config.js

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

方法:

TypeScript 代码Dexie使用命名空间导入和声明自己storage。为了遵循commonjs依赖管理的方式(在 中声明tsconfig.json),TypeScript 代码需要将storage命名空间作为模块导出:module.exports = storage.

因为 TypeScript 不知道module对象,所以我们需要获取它的定义。该module定义是 的类型定义一部分node我们使用. 要在 TypeScript 中链接节点检索到的类型定义,我们需要声明.typings install dt~node --global --save/// <reference path="../typings/index.d.ts" />

编译 TypeScript 代码后(使用gulp build),我们需要声明一个入口点以使我们的代码可访问。这是在index.js. 成功的构建会输出我们的dist/storage.js文件,该文件在index.js.

构建完成后,我们可以对我们的代码进行 webpack(将其捆绑到 HTML5 浏览器中)。我们webpack.config.js将依赖项 () 的“require”名称映射dexie到全局命名空间 ( window.Dexie) 中的对象。这向我们保证,Dexie不是我们编译代码的一部分(dist/webpacked.js)。

一旦我们有了webpacked.js,我们就可以在浏览器中使用它。但是我们必须确保在我们的 HTML 页面中引用了所有外部依赖项(这就是为什么 Dexie 也使用Bower声明为前端依赖项的原因)。

于 2016-07-19T16:28:53.210 回答
3

如何用窗口对象替换导入?

这是不可能的。有两种选择:

使用全局对象

在浏览器中,当 a 加载对象时<script>,您的代码会将其用作全局变量。在 TypeScript 中,您必须使用全局声明文件。这里没有使用模块,所以没有什么import可做的。

使用捆绑器或加载器

您可以使用捆绑器,例如Webpack。或者SystemJS这样的加载器。

于 2016-07-11T07:34:15.227 回答