问题
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