TypeScript + Node.js + Handlebars 將檔案以字串方式導入
我正在使用 TypeScript 及 Handlebars 模板開發一個 Node.js 應用程式。我在 trying 將 Handlebars 文件 (.hbs) 成功 以字串形式 匯入時遇到困難。這些模板文件是基於 JavaScript 模板;TypeScript 和 Node.js 嘗試將它們作為模組匯入,因此在執行代碼時會拋出錯誤。由於 .hbs 文件不是標準的 .ts,我的目標是以字串形式匯入這些文件;雖然我可以輕鬆地使用 fs.readFileSync 或 fsPromises.readFile 以及 utf-8 編碼或類似方式直接解析文件為字串,但這對我的使用情境不適用,因為我需要在編譯期間 import 這些文件。我是使用 ts-node 編譯/運行應用程式,例如:mymachine$ts-node src/index.ts。
index.ts
/// <reference path="./index.d.ts" />
import test from "./templates/test.hbs";
console.log(test);
index.d.ts
declare module "*.hbs";
// also have tried:
declare module "*.hbs" {
const value: string;
export default value;
}
test.hbs
// This Handlebars template is to generate some JavaScript / TypeScript code
import axios from 'axios'
console.log("ABC123");
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
"./@types"
],
"resolveJsonModule": true,
"allowJs": true,
"declaration": true,
"outDir": "./dist",
"downlevelIteration": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true
},
"ts-node": {
"files": true
}
}
錯誤拋出
import axios
^^^^^^
SyntaxError: Cannot use import statement outside a module
我已注意到有幾個答案示範了如何在客戶端應用程式中使用 Webpack 和 raw-loader 有效地做到這一點,而且我自己也成功以 .md 檔作為測試案例在 React 應用程式中實現了這一點(透過 declare module "*.md",然後 import file from "./file.md" 會返回 file 作為字串)。然而,我不確定這些解決方案是否能延伸到後端的 Node.js。
一個簡單的變通方法是將模板文件作為字串寫在 .ts 中,而不是作為 .hbs 的原始文件(見下文),但我更希望將文件保持為純 .hbs,以保留語法高亮、Prettier 格式化以及封裝邏輯。
workaround.ts
import Handlebars from "handlebarsHelpers";
export const test = Handlebars.compile(`
// This Handlebars template is to generate some JavaScript / TypeScript code
import axios from 'axios'
console.log("ABC123");
`);
workaround-index.ts
import test from "./workaround";
console.log(test);
有什麼建議嗎?這個問題似乎與 .hbs 無關;即使使用包含相同原生 JavaScript 的 .txt,TypeScript/Node.js 也會試圖將該檔案作為模組導入,而不是將內容作為字串傳遞。