BLOG

記事一覧 タグ一覧

ESModuleをGASで実行できるようにする

最終更新日:
投稿日:

GAS開発ではnpmライブラリを使うためにバンドルを行う必要があります。加えて、GASでエントリーポイントとして認識されるためにはfunctionを使って定義されている必要があります。

そこで、exportした関数のエントリーポイントを自動で生成するesbuildプラグイン esbuild-plugin-gas-generator を作成しました。

ESModuleとタイトルに書きましたがESModuleをバンドルできるというだけで、import.metaや Top Level Await は使えません。ご了承ください。

GitHub - miyaji255/esbuild-plugin-gas-generator: This plugin allows you to execute functions exported within Google Apps Script (GAS) environment.
This plugin allows you to execute functions exported within Google Apps Script (GAS) environment. - miyaji255/esbuild-plugin-gas-generator
GitHub - miyaji255/esbuild-plugin-gas-generator: This plugin allows you to execute functions exported within Google Apps Script (GAS) environment. favicon https://github.com/miyaji255/esbuild-plugin-gas-generator
GitHub - miyaji255/esbuild-plugin-gas-generator: This plugin allows you to execute functions exported within Google Apps Script (GAS) environment.
esbuild-plugin-gas-generator
This plugin allows you to execute functions exported within Google Apps Script (GAS) environment.. Latest version: 2.0.2, last published: 13 days ago. Start using esbuild-plugin-gas-generator in your project by running `npm i esbuild-plugin-gas-generator`. There are no other projects in the npm registry using esbuild-plugin-gas-generator.
esbuild-plugin-gas-generator favicon https://www.npmjs.com/package/esbuild-plugin-gas-generator
esbuild-plugin-gas-generator

使い方

build.jsに以下のように記述することで使用できます。プラグインの都合上bundleとformatはtrue'iife'であることが必須です。

出力ファイルはoutfileかオプションのtargetsで指定する。

const esbuild = require('esbuild');
const GasPlugin = require('esbuild-plugin-gas-generator');

esbuild.build({
    entryPoints: ['src/index.ts'],
    bundle: true,
    format: 'iife',    
    outfile: 'dist/bundle.js',
    plugins: [GasPlugin()],

    plugins: [
        GasPlugin({
            // appsscript.json のパスを指定する
            appsscript: "appsscript.json",
            // appsscript.json の内容を直接指定する
            appsscript: {
                timeZone: "Asia/Tokyo",
                dependencies: {},
                exceptionLogging: "STACKDRIVER",
                runtimeVersion: "V8"
            }
        })
    ]
}).catch((e) => {
    console.error(e);
    process.exit(1);
});

エントリーポイントでexportすると自動でGAS用のエントリーポイントを生成します。

export function hello() {
    console.log("hello")
}

実装

exportされたシンボルを収集するためにv2ではesbuildのmetafileという機能を使いました。これはbuild結果からimport/exportの情報を取得できる機能です。

つまり、build中にもう一度buildしているということです。他のプラグインも2度ビルドしている場合、競合する可能性があるのでexcludePluginsで除外することができます。

こうして作成したメタデータから次のようなコードを生成します。

function hello() {}
"use strict";
var _exports = (()=>{
    function hello() {
        console.log("hello")
    }
    return {hello}
})();
Object.assign(globalThis, _exports);
v1の実装

meriyahでパースしてexportした変数をすべて以下のように変換します

function hello() {}
(()=>{
function hello() {
    console.log("hello")
}

globalThis.hello=hello;
})()