【问题标题】:Use Typescript with Google Apps Script将 Typescript 与 Google Apps 脚本结合使用
【发布时间】:2018-02-14 16:26:28
【问题描述】:

我想在我的 Google Apps 脚本 (GAS) 项目中使用 Typescript,但我找不到将我的代码编译成 GAS 接受的东西的方法。

GAS 不支持导出,Typescript 似乎不喜欢通过全局范围访问变量(它需要导入/要求,因此需要导出)。

我正在寻找以下任何一种解决方案,我认为这些解决方案可以使事情对我有用:

1) Babel 插件等可以删除所有 Import 和 Export 语句及其属性名称(要求我不使用相同的方法名称,我没有。

所以:

import MyLibrary from './library';
export function greetJohn() { MyLibrary.greet('John'); }
export default { greetJohn }

变成:

function greetJohn() { greet('John'); }

2) 更改 typescript 使其可以看到全局范围

3) 将所有 .ts 文件合并为一个 .js 文件并通过将每个文件视为对象/函数来转换导入/导出语句的 Babel 插件等。

【问题讨论】:

  • 如果你不想使用 import, export 和 Typescript,你不必... Typescript 可以像 Javascript 一样看到全局范围。从您的问题中不清楚您为什么使用 export

标签: typescript google-apps-script commonjs clasp


【解决方案1】:

背景

自从您写了这个问题后,情况发生了变化,现在对 TypeScript 的 AppsScript 开发有更好的支持。 正如 Aliabbas Merchant 所说,将 TS 编译为 GAS 的最佳方法是使用 clasp,这是一个用于开发 AppsScript 应用程序的 CLI 工具。 Clasp 在底层使用 ts2gas 库将 TS 转换为 GAS,因此不再需要 Webpack 或任何其他捆绑器来将代码转换为 AppsScript。

Aliabbas Merchant 没有提到的是 ts2gas 不(还!)支持 export 语法,这会在开发时导致 linter 错误,并且不会被 IDE 很好地接受(即使禁用linter,IDE 将无法识别导入的变量,并且不会将它们视为对导出的引用...)

问题

问题源于 AppsScript 不使用模块系统,并且定义的每个顶级 var 也可以从其他文件访问(与将文件“包装”为模块的 TS 形成对比)。 当前版本的 ts2gas 的问题在于它转译了以下语句:

export var x = 5;

进入:

exports.x = 5

因此,在 clasp 将 .ts 转换为 .gs 后,当 .gs 的另一个文件尝试访问导出的 var 时,它没有找到它。实际上,这个 var 并没有像预期的那样存储为全局 var,而是在 exports 对象中(它本身就是一个全局 var)。如果我们能以某种方式“欺骗”编译器,那么它既可以将 var 保留在全局环境中,即使它也被导出(所以我们可以使用 TS 而不会出错),我们会赢。

解决方案

所以我们正在寻找一种解决方法。您可以在使用 TS 文档 (https://github.com/google/clasp/blob/master/docs/typescript.md) 的 clasp 中找到一些技巧,但还有一个技巧是我发现的最简单的技巧:

在本地定义变量(不导出它),然后导出一个包含我们想要导出的所有变量(当然也可以是函数)的对象。 TS 将表现为定期导出变量(它是 用于导出 vars 的语法糖),但编译器会将 vars 保留在全局和导出对象中。

示例

const a = 5;

function b() {
   return 'Hello World';
}

export {
   a,
   b
}

这样,vars 被真正导出并可以像往常一样在 TS 中使用,但在编译为 GAS 文件后也会留在全局 env 中(编译器实际上会将它们添加到 export 对象中,但我们应该不关心)。

【讨论】:

  • 这是我正在寻找的解决方案。一种在 AppScript 期望和本地开发之间取得平衡的方法。非常感谢
  • 乐于助人:)
  • 这不起作用。执行我的脚本时,我在 google 表格中遇到参考错误。
【解决方案2】:

现在可以使用 Typescript 开发 Google Apps 脚本项目,但这不能直接在 Apps 脚本编辑器上完成。

根据Develop Apps Script using TypeScript,更简单的方法是使用clasp

相关

【讨论】:

    【解决方案3】:

    过去几周我一直在研究类似的场景(不使用 TypeScript,但仍然使用 ES6/ES7)。

    我发现的一些事情可能对你想要实现的目标有所帮助:

    • GAS webpack plugin 允许您使用 webpack 在 GAS 中加载模块,方法是检测您何时分配给全局对象,然后生成 GAS 可以运行的顶级函数。这意味着您的导入和导出都将由 webpack 处理,因此您不必删除它们。
    • 我无法让 import * as x from y 语法正常工作,但 import { x } from yimport x from y 在使用 webpack 时工作正常。
    • 您可以使用 HTML loader 将 HTML 作为字符串包含在您的捆绑包中。

    如果您不想使用 webpack,一种解决方案是将所有代码放在一个 app.ts 文件中,创建一个包含所有函数的对象,将函数设置为顶级,以便它们可以被 GAS 捡到。您还可以导出容器对象并在测试套件中使用它。当你使用 Babel 编译时,使用babel-plugin-transform-remove-export 插件来删除导出语句。

    const app = {
      onInstall: () => { ...
      },
      onOpen: () => { ...
      }
    }
    
    const { onOpen, onInstall } = app;
    
    export { app };
    

    【讨论】:

    • 很好的答案。我最终将所有 .ts 文件合并到一个文件中。这有点像野兽,但对我来说,这比弄乱 WebPack 或试图偷偷摸摸 GAS 正在做什么更容易。
    【解决方案4】:

    使用TypeScript with Google App Script 的最佳(也是推荐)方式是使用clasp

    1. 安装卡扣:npm install @google/clasp -g
    2. 登录:clasp login
    3. 创建项目:clasp create [scriptTitle]
    4. 可选:将appsscripts.json 文件中的时区更改为this list 中最合适的时区。
    5. 安装类型:npm i -S @types/google-apps-script
    6. 创建 tsconfig.json 文件:
      { "compilerOptions": { "lib": [ "esnext" ], "experimentalDecorators": true } }
    7. 在 .ts 文件中编写代码
    8. 使用clasp push 推送您的代码
    9. 刷新您的脚本页面并运行您的函数。

    注意:您不需要使用importexport。变量可以跨文件访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-06
      • 2016-07-16
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多