Resolving typescript modules in the browser yields a 404

偶尔善良 提交于 2021-02-17 05:46:46

问题


I am looking to put together a small example of for a web app that is created using typescript. I have an issue with importing a module.

I just want information on why this is wrong and what options I have to sort it.

The problem is a 404 for the in the index.js file when trying to import the hello.

Here is the code:

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();

hello.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
    }
  }

The output of the above using tsc to compile the app is as follows:

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

These are as follows:

hello.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

Now if I change the index.ts to the full hello.js instead of hello then this will work. This feels wrong - as there is no index.js whilst I am coding this.

What is the correct way of resolving this to run in an ES2015 compatible browser such as Chrome?

Do I have to use something such as requirejs?


回答1:


You can use import h from './hello.js' in your typescript.
Also read this thread https://github.com/microsoft/TypeScript/issues/16577




回答2:


Consider using a module loader such as SystemJS. Looking at the example they provided it shows you how to achieve this without changing your typescript imports.

With the above example you can make the following changes:

index.html

Add script reference to systemjs.

Use the systemjs import javascript syntax to load the index module. No extension required.

Add the script reference to import a resolver (resolve.js) which is required to load extensionless javascript files.

<!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

Taken from the systemjs example.

(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

Change the module to 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 output

You can see you get a completely different output with the module set to 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

We need to bring in some additional devDependencies to use system in the 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"
  }
}



来源:https://stackoverflow.com/questions/61479159/resolving-typescript-modules-in-the-browser-yields-a-404

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!