在與 Vite Eleventy 合作遇到一些困難后,我已切換到 Astro。我有我想要的一切,除了我不能有一個與document. 我認為這可能是兩個問題糾纏不清,或者可能是對外部 TS/JS 檔案的稀疏檔案的誤解。
問題1:public/和匯入路徑
JavaScript 檔案可以很容易地保存在下面public/,但TypeScript 不會被轉譯。我嘗試添加public到我的 tsconfig 中,但沒有幫助。
在“Astro scope”中匯入頁面的frontmatter,這讓我可以使用相對于頁面檔案的路徑。以這種方式匯入的 TS 會轉譯和作業,除非在尋找document.
從頁面上的標簽中匯入模塊<script>是“客戶端范圍”。如果我在其他地方的 TS 代碼src被轉譯,我仍然沒有確定的、服務的位置用于匯入路徑(換句話說,我可能會弄清楚,但它會很脆弱)。
問題2:document未定義
我必須使用<script is:inline>or<script type="module">才能將腳本嵌入到 HTML 中以用于“客戶端范圍”。這些腳本可以訪問window和document。但是,他們無權訪問在“Astro 范圍”中匯入和轉譯的任何模塊,也無權訪問Runtime 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>
結果:“Hello world”ReferenceError: callMe is not defined
src/scripts/sample.ts移至public/sample.ts樣品 3 和 4
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)
期望的結果
謝謝你走到這一步。你能告訴我我該怎么做嗎
- 有一個外部TS 檔案
- 由 Astro 頁面加載或在其中加載
- 與 DOM 互動(通過
document) - 之后
DOMContentLoaded(或同等)
相關問題:
- 模塊是否會阻止使用 DOMContentLoaded 偵聽器的需要?
- 如何在 astro JS 中使用檔案和視窗元素?
uj5u.com熱心網友回復:
我必須使用 or 才能將腳本嵌入到 HTML 中以用于“客戶端范圍”。這些腳本可以訪問視窗和檔案。
您實際上可以訪問默認處理標簽中的documentand物件(沒有任何屬性)。window<srcipt>
為此,請重現sample4.astro,但省略type腳本標記上的屬性并將sample.ts檔案移動到目錄中的某個位置src(^scripts為您),以便您可以從 javascript 匯入它(注意最后一個要點)
---
import LayoutMain from "^layouts/LayoutMain.astro";
---
<LayoutMain>
<p id="greeting"></p>
</LayoutMain>
<script type="module">
import { callMe } from "^scripts/sample";
callMe();
</script>
這是一個作業復制品。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/526167.html
