ts 编译运行时,为何没有正确加载 JavaScript 文件?

363 天前
 z888888cn

报错如下:

Failed to load resource: the server responded with a status of 404 (Not Found) http://…ake_game/bin/game

我自己排查过,是因为加载的文件没有后缀,正确的加载应该是 game.js ,我只要修改 main.js 就可以了,import { *Game* } from './game';改成import { *Game* } from './game.js';可是 main.js 是 main.ts 生成的。请问这个有什么解决方法?

项目目录结构如下:

│  index.html
│  package-lock.json
│  package.json
│  tsconfig.json
├─bin
│      game.js
│      game.js.map
│      main.js
│      main.js.map
│      snake.js
│      snake.js.map
│      
└─src
        game.ts
        main.ts
        snake.ts

index.html

<script src="./bin/main.js" type="module"></script>

main.ts

import { Game } from './game';

const game = new Game();
game.start();

game.ts

export class Game {
}

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "es2015",
        "moduleResolution": "node",
        "strict": true,
        "esModuleInterop": true,
        "sourceMap": true,
        "outDir": "./bin"
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules"
    ]
}
1297 次点击
所在节点    TypeScript
7 条回复
gucheen
363 天前
是 feature 不是 bug ,参见
https://github.com/microsoft/TypeScript/issues/16577
你这个情况可以考虑自己对编译后的文件二次处理,或者在你的服务器上做 rewrite
leokun
363 天前
用什么工具编译的
z888888cn
363 天前
@leokun 执行`npx tsc`,编译 Typescript 生成的 JavaScript 脚本。
DOLLOR
363 天前
main.ts 里把
import { Game } from './game';
改为
import { Game } from './game.js';
z888888cn
363 天前
@gucheen 感谢,我通过 nginx 配置解决了。但是 nginx 配置看着有点懵懵的。nginx 配置如下

```
server {
listen 80;

# 指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;

# 预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
# 带 cookie 请求需要加上这个字段,并设置为 true
add_header Access-Control-Allow-Credentials true;

# 表示允许这个域跨域调用(客户端发送请求的域名和端口)
# $http_origin 动态获取请求客户端请求的域 不用*的原因是带 cookie 的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;

# 表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;

# OPTIONS 预检命令,预检命令通过时才发送请求
# 检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}

location / {
root C:/Users/Intel/Desktop/snake_game;
index index.html index.htm;

# 处理 /bin 目录下的请求
location /bin/ {
# 如果请求的路径具有任意后缀名文件,则不进行重写
location ~* \..+$ {
# 指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;

# 预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
# 带 cookie 请求需要加上这个字段,并设置为 true
add_header Access-Control-Allow-Credentials true;

# 表示允许这个域跨域调用(客户端发送请求的域名和端口)
# $http_origin 动态获取请求客户端请求的域 不用*的原因是带 cookie 的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;

# 表示请求头的字段 动态获取
add_header Access-Control-Allow-Headers
$http_access_control_request_headers;

# OPTIONS 预检命令,预检命令通过时才发送请求
# 检查请求的类型是不是预检命令
if ($request_method = OPTIONS){
return 200;
}

break;
}

# 如果请求的文件不带后缀名,则增加 js ,则进行重写
rewrite ^/bin/(.*)$ /bin/$1.js break;

# 如果请求的是不存在的文件,则返回 404 错误
try_files $uri =404;
}
}
}
# 关闭后台执行
daemon off;
```
leokun
363 天前
@z888888cn tsc 不太适合 web 工具库的构建,例如路径别名(path)和拓展名都不支持
ts 库的选择 tsup 或者 rollup ,前者用 tsc 构建 d.ts ,用 esbuild 构建 js
web 应用就很多选择了,vite 、webpack 等

如果想要在 node 直接运行 ts ,tsx(不是 react 的 tsx)也是不错的选择
z888888cn
362 天前
@leokun 非常感谢,我用 rollup 编译 ts 脚本,超级方便。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/937866

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX