在让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中,用于“客户端作用域”。这些脚本可以访问window和document。但是,他们不能访问在“天文范围”中导入和转换的任何模块,也不能访问运行时API。
内联脚本标记中的导入路径总是开始查看根URL (即public/),所以我回到了问题1。
(顺便说一句,在进行了一些研究之后,DOMContentLoaded似乎没有必要使用普通模块,但我认为Astro正在做一些事情来改变这种状况。)
我的设置
tsconfig.json
{
"extends": "astro/tsconfigs/strictest",
"include": [
"src/**/*",
"public/**/*"
],
"compilerOptions": {
"baseUrl": ".",
"types": [
"astro/client"
],
"paths": {
"^layouts/*": [ "src/layouts/*" ],
"^scripts/*": [ "src/scripts/*" ]
}
}
}src/scripts/sample.ts
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
---
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
---
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
---
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
---
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)
期望结果
谢谢你来了这么远。你能告诉我怎么能
document)DOMContentLoaded (或同等)之后相关问题:
发布于 2022-11-01 19:55:06
我必须使用或为了让脚本保留在HTML中,用于“客户端作用域”。这些脚本可以访问窗口和文档。
实际上,您可以在默认处理的document标记中访问window和<srcipt>对象(没有任何属性)。
要做到这一点,请复制sample4.astro,但忽略脚本标记上的type属性,并将sample.ts文件移到src目录中的某个位置(^scripts ),以便您可以从javascript导入 (注意最后一个要点)。
---
import LayoutMain from "^layouts/LayoutMain.astro";
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>
<script>
import { callMe } from "^scripts/sample";
callMe();
</script>这里是一种工作复制。
https://stackoverflow.com/questions/74271024
复制相似问题