【问题标题】:Resolving typescript modules in the browser yields a 404在浏览器中解析 typescript 模块会产生 404
【发布时间】:2020-04-28 11:30:17
【问题描述】:

我正在寻找一个使用typescript 创建的网络应用程序的小示例。我在导入模块时遇到问题。

我只想了解为什么这是错误的以及我必须对它进行排序的选项。

问题是在尝试导入 hello 时 index.js 文件中的 404。

代码如下:

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
        <p>Check the console log...</p>
    </body>

    <script type="module" src="/dist/index.js"></script>
</html>

index.ts

import { HelloWorld } from "./hello";

var helloWorld = new HelloWorld();

helloWorld.sayHello();

你好.ts

export class HelloWorld {
    constructor() {

    }

    sayHello() {
        console.log("Hello, world!");
    }
}

tsconfig.json

{
    "compilerOptions": {
      "target": "ES2015",
      "module": "ES2015",
      "lib": ["es2015", "dom"],
      "moduleResolution": "node",

      "allowJs": true,
      "checkJs": true,
      "sourceMap": true,
      "outDir": "./dist",
      "strict": true,
      "esModuleInterop": true,
      "experimentalDecorators": true,
      "forceConsistentCasingInFileNames": true
    }
  }

上面使用tsc编译app的输出如下:

dist
    hello.js
    hello.js.map
    index.js
    index.js.map

如下:

你好.js

export class HelloWorld {
    constructor() {
    }
    sayHello() {
        console.log("Hello, world!");
    }
}
//# sourceMappingURL=hello.js.map

index.js

import { HelloWorld } from "./hello";
var helloWorld = new HelloWorld();
helloWorld.sayHello();
//# sourceMappingURL=index.js.map

现在,如果我将 index.ts 更改为完整的 hello.js 而不是 hello,那么这将起作用。这感觉不对 - 因为在我编写此代码时没有 index.js

ES2015 兼容的浏览器(如 Chrome)中运行解决此问题的正确方法是什么?

我必须使用诸如requirejs 之类的东西吗?

【问题讨论】:

    标签: typescript ecmascript-6


    【解决方案1】:

    您可以在打字稿中使用import h from './hello.js'
    另请阅读此主题https://github.com/microsoft/TypeScript/issues/16577

    【讨论】:

    • 这就是我在帖子末尾所说的......但感觉不对。将检查链接谢谢
    【解决方案2】:

    考虑使用模块加载器,例如SystemJS。查看他们提供的example,它向您展示了如何在不更改打字稿导入的情况下实现这一目标。

    通过上面的示例,您可以进行以下更改:

    index.html

    添加对 systemjs 的脚本引用。

    使用 systemjs import javascript 语法加载索引模块。无需扩展。

    添加脚本引用以导入加载无扩展名 javascript 文件所需的解析器 (resolve.js)。

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Hello World</title>
    
        <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.3.1/system.min.js"
            integrity="sha256-15j2fw0zp8UuYXmubFHW7ScK/xr5NhxkxmJcp7T3Lrc=" crossorigin="anonymous"></script>
        <script src="./dist/systemjs-hooks/resolve.js"></script>
        <script>System.import("./dist/index")</script>
    
    </head>
    
    <body>
        <p>Check the console log...</p>
    </body>
    
    </html>
    

    resolve.ts

    取自 systemjs 示例。

    (function () {
        const endsWithFileExtension = /\/?\.[a-zA-Z]{2,}$/;
        const originalResolve = System.constructor.prototype.resolve;
        System.constructor.prototype.resolve = function () {
          // apply original resolve to make sure importmaps are resolved first
          const url = originalResolve.apply(this, arguments);
          // append .js file extension if url is missing a file extension
          return endsWithFileExtension.test(url) ? url : url + ".js";
        };
      })();
    

    tsconfig.json

    module 更改为system

    {
        "compilerOptions": {
          "target": "ES2015",
          "module": "system",
          "lib": ["es2015", "dom"],
          "moduleResolution": "node",
    
          "allowJs": true,
          "checkJs": true,
          "sourceMap": true,
          "outDir": "./dist",
          "strict": true,
          "esModuleInterop": true,
          "experimentalDecorators": true,
          "forceConsistentCasingInFileNames": true
        }
      }
    

    index.js 输出

    您可以看到将module 设置为system 时得到完全不同的输出。

    System.register(["./hello"], function (exports_1, context_1) {
        "use strict";
        var hello_1, helloWorld;
        var __moduleName = context_1 && context_1.id;
        return {
            setters: [
                function (hello_1_1) {
                    hello_1 = hello_1_1;
                }
            ],
            execute: function () {
                helloWorld = new hello_1.HelloWorld();
                helloWorld.sayHello();
            }
        };
    });
    

    package.json

    我们需要引入一些额外的devDependencies 来使用resolve.ts 中的系统。

    {
      "name": "foo",
      "version": "0.0.1",
      "description": "foo",
      "main": "index.js",
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@types/systemjs": "^6.1.0",
        "typescript": "^3.8.3"
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 2015-07-31
      • 2018-11-10
      • 1970-01-01
      • 2014-10-14
      相关资源
      最近更新 更多