【问题标题】:Getting plain JavaScript files to work with the TypeScript module system获取纯 JavaScript 文件以使用 TypeScript 模块系统
【发布时间】:2020-01-02 11:02:22
【问题描述】:

我正在使用 Visual Studio 使用 TypeScript 创建一个 ASP.NET Core 2.2 Web 应用程序,并且我已经包含了 two.js 库以及我在网上找到的 npm 包中的 two.d.js(TypeScript 声明文件) .

问题是我不明白如何让模块工作(也许它与two.js 无关,但通常使用带有模块的纯 JavaScript)。

two.js 文件使用 JSDoc,但据我所知没有任何导出。

所以我的项目有这些文件(two.d.js、two.js 和 site.ts):

+ js
  - two.d.js
  - two.js
  - site.ts
  - something.ts

而site.js文件在开头导入two.js和something.ts:

// this uses the 'two.d.js' file and I get intellisense
import { Two } from "./two";

// this is some .ts file
import { Something } from "./something";

// create the Two.js instance
let placeholder = document.getElementById('placeholder');

// this line is what I want to get running
let twojs = new Two({ width: 1900, height: 885 }).appendTo(placeholder);

但是,当site.ts 被编译时,我尝试的任何模块选项在浏览器中都会失败:

  1. “无”(即没有模块系统):失败,exports 未在编译的site.js 文件的第一行定义:

     Object.defineProperty(exports, "__esModule", { value: true });
    
  2. ES2015 本机模块系统:./something 和 ./two 出现“404 未找到”失败。 TypeScript 编译器不会将 .js 扩展名附加到本机浏览器 import 语句,因此无法加载这些文件。但是,如果我在 TypeScript 中添加扩展名,则会出现编译错误。

  3. AMD/RequireJS:我收到“Two 不是构造函数”异常。 代码被编译成这个,我可以看到所有.js 文件都正确加载,但是我猜问题是two.js 没有原生导出任何东西:

    define(["require", "exports", "./something", "./two"], function (require, exports, something, two_1) {
    
        "use strict";
        Object.defineProperty(exports, "__esModule", { value: true });
        let placeholder = document.getElementById('placeholder');
    
        // Two is not a constructor
        let twojs = new two_1.Two({ width: 1900, height: 885 }).appendTo(placeholder);
    
    });
    

理想情况下,我希望每个页面都有一个捆绑的 .js 文件,以减少模块加载器服务器往返,但我对其他选项持开放态度。

【问题讨论】:

    标签: javascript asp.net typescript requirejs bundling-and-minification


    【解决方案1】:

    two.js 没有导出任何内容,它将Two 公开为全局变量,因此two.d.ts 在对模块进行类型注释时直言错误(实际上two.js 不符合“模块”的条件”)。你需要先纠正它。

    1. 您需要将two.d.ts 中的所有顶级export 关键字替换为declare 关键字。这将告诉 TS two.js 不是模块,而是公开了一些全局变量。

    2. site.ts 现在可以直接引用全局变量Two,不再需要import。作为一种好的做法,建议在此文件的顶部放置一个三斜杠指令以显示依赖关系。这也会在捆绑时将two.js 的内容放在site.js 之前(参见下一步)。

    /// <reference path="./two.js" />
    
    let twojs = new Two({ width: 1900, height: 885 }).appendTo(placeholder);
    
    1. 配置 tsconfig.json 如下。在命令行中运行tsc,它会将您的所有.js 和.ts 文件编译并捆绑到一个文件中。您可能需要根据项目的文件结构配置“include”(或“files”)字段以涵盖所有相关资源(例如 two.js、two.d.ts)。 Docs
    {
        "include": [...],
        "compilerOptions": {
            "module": "amd",
            "outFile": "bundle.js",
            "allowJs": true  // to include `two.js` into the bundle
        }
    }
    
    1. 使用 RequireJS 在 HTML 中包含您的脚本。
    <script data-main="scripts/bundle" src="scripts/require.js"></script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      相关资源
      最近更新 更多