网站搜索

TypeScript + Node.js + Handlebars 将文件作为字符串导入


我正在使用 TypeScript 开发一个 Node.js 应用,并使用 Handlebars 进行模板处理。我在将 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 也会尝试将该文件作为模块导入,而不是将内容作为字符串传递。

相关文章