如何让浏览器允许我使用导入? (打字稿)
How do I let the browser allow me to use imports? (TypeScript)
上下文
我有这两个 TypeScript 文件:
// something.ts
let x = 3;
export default x;
// index.ts
import x from "./something";
console.log(x);
在这些 tsconfig.json
设置下:
{
...
"target": "es2016",
...
// "module": "commonjs" /* <- commented out */
}
当我将它编译成 JavaScript 时,我得到了这两个文件(这是我所期望的):
// something.js
let x = 3;
export default x;
// index.js
import x from "./something";
console.log(x);
现在,我已经从我的 HTML 文件中链接了 index.js
文件,如下所示:
<script src="./dist/index.js"></script>
问题
当我尝试使用 Live Server 打开它时,我在控制台中收到此错误:
Uncaught SyntaxError: Cannot use import statement outside a module
那么,我该如何解决这个问题?
我试过的
- 在我的
tsconfig.json
文件中添加回 "module": "commonjs"
行
这会导致控制台中出现不同的错误消息:
Uncaught ReferenceError: exports is not defined
根据 ,建议的解决方案是注释掉 "module": "commonjs"
行,这实质上使我的情况陷入无限循环...
- 将
"type": "module"
添加到 <script>
标签和 package.json
来自 this SO post,建议的解决方案是将 "type": "module"
添加到 <script>
标签:
<script type="module" src="./dist/index.js"></script>
但现在我收到此错误消息:
GET http://127.0.0.1:5501/dist/something net::ERR_ABORTED 404 (Not Found)
.
在同一个 post 中,另一个建议是将 "type": "module" 添加到 package.json
文件中:
{
"type": "module",
"dependencies": {
"typescript": "^4.6.2"
}
}
根据我的观察,这并没有真正起到任何作用。
你们真的真的真的很亲近。在 ESM(在浏览器中)导入中,您必须提供文件扩展名,因此您需要这样做:
import something from "./something.js";
而不是简单地
import something from "./something";
您的其他代码无法正常工作,因为浏览器 运行 已打开,嗯...浏览器。这意味着我们不在 NodeJS 环境中,因此模块不会如此神奇地工作。因此,ESM 导入的注意事项:
- 你不能导入 npm 包
- 所有导入必须是绝对 URL 或以
./
或 /
开头
- 浏览器不会自动添加文件扩展名;你必须自己指定(例如
import something from "./something.js";
而不是 import something from "./something";
)
- 您必须在 HTML 脚本标记中指定
type="module"
以告诉浏览器您正在查看的是一个模块
- 请不要在生产中使用它,因为...
- 如果你有嵌套导入,浏览器不能同时加载它们;他们必须一个一个地加载
- 没那么快(呃)
- 该功能非常新,因此并没有真正增强那么多
真正的解法:
请改用捆绑器!!
为什么?
一个捆绑器(最流行的可能是 Webpack)找到您代码中的所有导入和导出并将它们全部合并到一个文件中。
为什么要使用捆绑器:
- 大家都在用
- 这是标准
- 很受欢迎
- ...
- 提高页面性能
- 你会得到其他好东西,比如缩小等等
- 您可以导入(一些)npm 包
这并不意味着我们应该从不 使用in-browser 导入。当您在开发中使用它时完全没问题,因为它更容易设置。 Vite 是一种流行的开发框架,它利用这一点来改善 DX(开发人员体验),方法是消除每次 re-run 代码时的捆绑等待时间。
但同样,不要在生产中使用它。
我建议您使用捆绑器,因为无论如何您已经设置了 Node 和 TS。在较长的 运行...
中会更容易
上下文
我有这两个 TypeScript 文件:
// something.ts
let x = 3;
export default x;
// index.ts
import x from "./something";
console.log(x);
在这些 tsconfig.json
设置下:
{
...
"target": "es2016",
...
// "module": "commonjs" /* <- commented out */
}
当我将它编译成 JavaScript 时,我得到了这两个文件(这是我所期望的):
// something.js
let x = 3;
export default x;
// index.js
import x from "./something";
console.log(x);
现在,我已经从我的 HTML 文件中链接了 index.js
文件,如下所示:
<script src="./dist/index.js"></script>
问题
当我尝试使用 Live Server 打开它时,我在控制台中收到此错误:
Uncaught SyntaxError: Cannot use import statement outside a module
那么,我该如何解决这个问题?
我试过的
- 在我的
tsconfig.json
文件中添加回"module": "commonjs"
行
这会导致控制台中出现不同的错误消息:
Uncaught ReferenceError: exports is not defined
根据 "module": "commonjs"
行,这实质上使我的情况陷入无限循环...
- 将
"type": "module"
添加到<script>
标签和package.json
来自 this SO post,建议的解决方案是将 "type": "module"
添加到 <script>
标签:
<script type="module" src="./dist/index.js"></script>
但现在我收到此错误消息:
GET http://127.0.0.1:5501/dist/something net::ERR_ABORTED 404 (Not Found)
.
在同一个 post 中,另一个建议是将 "type": "module" 添加到 package.json
文件中:
{
"type": "module",
"dependencies": {
"typescript": "^4.6.2"
}
}
根据我的观察,这并没有真正起到任何作用。
你们真的真的真的很亲近。在 ESM(在浏览器中)导入中,您必须提供文件扩展名,因此您需要这样做:
import something from "./something.js";
而不是简单地
import something from "./something";
您的其他代码无法正常工作,因为浏览器 运行 已打开,嗯...浏览器。这意味着我们不在 NodeJS 环境中,因此模块不会如此神奇地工作。因此,ESM 导入的注意事项:
- 你不能导入 npm 包
- 所有导入必须是绝对 URL 或以
./
或/
开头
- 浏览器不会自动添加文件扩展名;你必须自己指定(例如
import something from "./something.js";
而不是import something from "./something";
) - 您必须在 HTML 脚本标记中指定
type="module"
以告诉浏览器您正在查看的是一个模块 - 请不要在生产中使用它,因为...
- 如果你有嵌套导入,浏览器不能同时加载它们;他们必须一个一个地加载
- 没那么快(呃)
- 该功能非常新,因此并没有真正增强那么多
真正的解法:
请改用捆绑器!!
为什么?
一个捆绑器(最流行的可能是 Webpack)找到您代码中的所有导入和导出并将它们全部合并到一个文件中。
为什么要使用捆绑器:
- 大家都在用
- 这是标准
- 很受欢迎
- ...
- 提高页面性能
- 你会得到其他好东西,比如缩小等等
- 您可以导入(一些)npm 包
这并不意味着我们应该从不 使用in-browser 导入。当您在开发中使用它时完全没问题,因为它更容易设置。 Vite 是一种流行的开发框架,它利用这一点来改善 DX(开发人员体验),方法是消除每次 re-run 代码时的捆绑等待时间。
但同样,不要在生产中使用它。
我建议您使用捆绑器,因为无论如何您已经设置了 Node 和 TS。在较长的 运行...