首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Astro项目中使用外部TypeScript文件中的“`document`”

在Astro项目中使用外部TypeScript文件中的“`document`”
EN

Stack Overflow用户
提问于 2022-11-01 02:50:27
回答 1查看 89关注 0票数 1

在让Vite+Eleventy合作遇到一些困难之后,我转到了阿童木公司。我有我想要的一切,除了我不能有一个与document交互的外部document模块。我认为这可能是两个问题结在一起,或者可能是对关于外部TS/JS文件的稀疏文档的误解。

问题1: 和导入路径

JavaScript文件可以很容易地在public/下生存,但是TypeScript不是传输。我尝试将public添加到我的tsconfig中,但是没有帮助。

在页面的前端导入是在“天文范围”中完成的,这允许我使用相对于页面文件的路径。TS以这种方式导入transpiles并工作,除非在寻找document时。

从页面上的<script>标记中导入模块是“客户端作用域”。如果我在src下的其他地方的TS代码正在被转移,我仍然没有一个可以用于导入路径的确定的、服务的位置(换句话说,我可能会找出它,但它是脆弱的)。

document 问题2: 未定义

我必须使用<script is:inline><script type="module">,以便将脚本保留在HTML中,用于“客户端作用域”。这些脚本可以访问windowdocument。但是,他们不能访问在“天文范围”中导入和转换的任何模块,也不能访问运行时API

内联脚本标记中的导入路径总是开始查看根URL (即public/),所以我回到了问题1。

(顺便说一句,在进行了一些研究之后,DOMContentLoaded似乎没有必要使用普通模块,但我认为Astro正在做一些事情来改变这种状况。)

我的设置

tsconfig.json

代码语言:javascript
复制
{
  "extends": "astro/tsconfigs/strictest",
  "include": [
    "src/**/*",
    "public/**/*"
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "types": [
      "astro/client"
    ],
    "paths": {
      "^layouts/*": [ "src/layouts/*" ],
      "^scripts/*": [ "src/scripts/*" ]
    }
  }
}

src/scripts/sample.ts

代码语言:javascript
复制
type NotJavaScript = {
    hasTypes: boolean;
};

export const callMe = () => {
    document.getElementById("greeting").textContent = "Color me your color, baby";
};

document.addEventListener("DOMContentLoaded", () => {
    document.getElementById("greeting").textContent = "Hello world";
});

src/pages/sample/sample1.astro

代码语言:javascript
复制
---
import LayoutMain from "^layouts/LayoutMain.astro";
import "^scripts/sample"
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>

结果:ReferenceError: document is not defined

src/pages/sample/sample2.astro

代码语言:javascript
复制
---
import LayoutMain from "^layouts/LayoutMain.astro";
import "^scripts/sample"
// same result as `import { callMe } from "^scripts/sample"`
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>

<script is:inline>
// document.addEventListener moved from TS file
document.addEventListener("DOMContentLoaded", () => {
    document.getElementById("greeting").textContent = "Hello world";
    callMe();
});
</script>

结果:使用ReferenceError: callMe is not defined的"Hello“

src/scripts/sample.ts将样本3和4迁移到public/sample.ts

src/pages/sample/sample3.astro

代码语言:javascript
复制
---
import LayoutMain from "^layouts/LayoutMain.astro";
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>

<script is:inline>
    import "/sample.ts";
    callMe();
</script>

结果:SyntaxError: import declarations may only appear at top level of a module

src/pages/sample/sample4.astro

代码语言:javascript
复制
---
import LayoutMain from "^layouts/LayoutMain.astro";
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>

<script type="module">
    import { callMe } from "/sample.ts";
    callMe();
</script>

结果:Loading module from “http://localhost:3000/sample.ts” was blocked because of a disallowed MIME type (“text/html”).

我也见过SyntaxError: unexpected token: identifier (指type)

期望结果

谢谢你来了这么远。你能告诉我怎么能

  • 有一个外部TS文件
  • 加载到天文页面或在其中加载的
  • 与DOM交互(通过document)
  • DOMContentLoaded (或同等)之后

相关问题:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-01 19:55:06

我必须使用或为了让脚本保留在HTML中,用于“客户端作用域”。这些脚本可以访问窗口和文档。

实际上,您可以在默认处理的document标记中访问window<srcipt>对象(没有任何属性)。

要做到这一点,请复制sample4.astro,但忽略脚本标记上的type属性,并将sample.ts文件移到src目录中的某个位置(^scripts ),以便您可以从javascript导入 (注意最后一个要点)。

代码语言:javascript
复制
---
import LayoutMain from "^layouts/LayoutMain.astro";
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>

<script>
    import { callMe } from "^scripts/sample";
    callMe();
</script>

这里是一种工作复制。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74271024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档