背景
在 GitHub 遇到一些好玩的 TS 代码想直接在浏览器运行,但是浏览器目前并不支持 TS,还处于提案阶段。
比如遇到一个好玩的在控制台播放视频的小工具 console.video.ts。 要是能直接复制即编译该多好。
如图,要是 GitHub 能有一个类似下图红框中的『Copy as JS』按钮该多好。

解决方案
在 node.js 中编译 ts 大家都知道用 tsc、esbuild 或 babel。这里相应也有几种解决方案。
tsc
1 浏览器安装 npm 包之安装 tsc 编译工具。
async function installTSCompiler() { const typescriptServices = 'https://cdn.jsdelivr.net/npm/typescript@4.6.3/lib/typescriptServices.js' return installNpmPackage(typescriptServices) .then(() => { const ts = window.ts; if (!ts) { return null } log(`ts@${ts.version} installed in your console.`); return ts; }); } function installNpmPackage(packageSrcOrName) { return isURL(packageSrcOrName) ? insertScript(packageSrcOrName) : insertScript(`https://cdn.jsdelivr.net/npm/${packageSrcOrName}`) }
2 编译
const sourceCode = `function foo(str: string): number { return str?.length ?? 0 }`; const tsc = await installTSCompiler(id); const { outputText: js } = tsc.transpileModule(sourceCode, { compilerOptions: { target: 'esnext' } }); console.log('编译结果:', js)
esbuild
1 同理浏览器安装 esbuild-wasm
await installNpmPackage('esbuild-wasm')
2 编译
const sourceCode = `const foo = (str: string): string => { return 'bar'; }` // 注意有且仅有一次初始化 await esbuild.initialize({ wasmURL: 'https://cdn.jsdelivr.net/npm/esbuild-wasm@0.14.38/esbuild.wasm', }) const output = await esbuild.transform(sourceCode, { loader: 'ts' }) console.log('编译结果:', output)
Babel
1 同理浏览器安装 esbuild-wasm
await installNpmPackage('@babel/standalone')
2 编译
const sourceCode = `const foo = (str: string): string => { return 'bar'; }` var output = Babel.transform(sourceCode, { filename: 'file.ts', presets: ["typescript"] }).code; console.log('编译结果:', output)
比较
可用性
esbuild 因为要初始化加载 wasmURL,而该链接的 host 不属于 github 的 content-security-policy host 之一,故没法在有 csp 的网站上运行比如 github 或 npm。
tsc 和 babel 方案没有类似问题 ,能在任意网站顺利编译。但是都是同步编译,存在阻塞主线程的可能性。
性能 WIP
预估 esbuild > babal > tsc
参考
- tsc – Script tag support for TypeScript
- esbuild – Running in the browser
- 完整代码
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)