如何让TypeScript原封不动保留ExtendScript专属#include语句至编译产物?
#include指令的问题 我明白你的痛点——TypeScript对非标准语法的处理确实头疼,尤其是ExtendScript这种依赖预处理指令的环境。你提到的// @ts-ignore和// @ts-expect-error只能抑制错误提示,但没法阻止TS对代码进行解析转换,最终把#include "path_to_file";改成#include;,完全破坏了ExtendScript的预处理逻辑。
TypeScript本身没有内置的“原样保留特定非标准代码行”的功能,因为它会强制解析所有代码并遵循JS语法规则进行转换,但有几个简单可行的workaround可以解决这个问题,不需要复杂的Makefile拼接:
方法1:将#include放在单独的JS文件中编译
这个方法利用TypeScript不会修改纯JS文件内容的特性,把预处理指令隔离到JS文件里:
创建一个单独的JS文件(比如
includes.js),内容直接写:#include "path_to_file";在你的TypeScript文件中引用这个JS文件:
// 如果用CommonJS模块 require("./includes.js"); // 如果用ES模块(需在tsconfig.json中配置module为ESNext等) import "./includes.js";编译时使用
--outFile选项让TS将所有文件拼接成一个输出文件:tsc your-main-file.ts includes.js --outFile compiled-script.js
这样TS会把includes.js的内容原封不动地合并到最终的编译结果中,ExtendScript就能正常识别#include指令了。
方法2:用Post-Build脚本替换自定义标记
如果你不想拆分文件,可以在TS中用自定义标记代替#include,然后用一个简单的脚本在编译后替换成真实的预处理指令:
在TypeScript文件中写标记(用注释避免TS报错):
// @ts-ignore // INCLUDE: path_to_file编写一个简短的Node.js脚本(比如
replace-includes.js):const fs = require('fs'); const path = require('path'); const outputPath = path.join(__dirname, 'compiled-script.js'); let content = fs.readFileSync(outputPath, 'utf8'); // 替换标记为真实的#include指令 content = content.replace(/\/\/ INCLUDE: (.+)/g, '#include "$1";'); fs.writeFileSync(outputPath, content);在
package.json的scripts中添加post-build命令,让编译后自动运行脚本:{ "scripts": { "build": "tsc", "postbuild": "node replace-includes.js" } }
这样每次运行npm run build,TS编译完成后就会自动把标记替换成正确的#include指令。
方法3(进阶):使用TypeScript自定义Transformer
如果你的项目大量使用#include指令,可以编写一个自定义Transformer,让TS在编译过程中直接识别并保留特定语法。不过这个方法需要配置ts-loader或ttypescript,相对复杂一些,适合大型项目。
为什么@ts-ignore没用?
TS的@ts-ignore只是让编译器忽略该行的语法错误,但它仍然会尝试解析代码。它把#include "path_to_file"当成了一个标识符(#include)加一个未使用的字符串表达式,在编译优化时会把未使用的字符串去掉,最终只留下#include;,这就是你看到的问题。
内容的提问来源于stack exchange,提问作者tbrugere

