GASがV8エンジンに対応したのでドキュメント読んでみた
公式のV8移行ドキュメント
Migrating scripts to the V8 runtime
を読んだのでメモ
だいぶテキトーです。
-
GASがV8エンジンに対応したのでドキュメント読んでみた
- 経緯
- 適用方法
- 移行
-
V8移行手順
for each (variable in object)
からfor (variable in object)
に変えるDate.prototype.getYear()
からDate.prototype.getFullYear()
に変える- 予約語を避ける
const
で宣言した変数に再代入しないように書き換える- XMLリテラルやXMLオブジェクトはパースする
__iterator__
関数でカスタムイテレータを作っていたら、ECMAScript 6 iterators
で書き換える- グローバル変数を避ける
- 条件付きcatch句を避ける
Object.prototype.toSource()
を使っていたら削除してください
- その他の違い、注意点
- 感想
- 参考
経緯
2020/02/05 、Release Notesに更新がありました。
February 5, 2020
Apps Script now supports the V8 runtime. This enables modern JavaScript features and syntax in Apps Script. You can migrate existing scripts to use V8 and its features.
「V8ランタイム対応!GASをモダンJavaScriptで書けるよ!」
var
じゃなくconst
で変数宣言したり、アロー関数を使ったりできます。
適用方法
現在、デフォルトエンジンはRhino
なので、V8
に変更してあげる必要があります。
方法は以下の2つがあるのですが、前者は現在未リリース
- メニューから切り替える方法 (実行タブに追加される予定)
- スクリプトマニフェストでエンジンを指定する方法
後者のやり方は以下のツイートがわかりやすい。
https://twitter.com/howdy39/status/1225168177996320768?s=20
移行
ここから公式ドキュメントMigrating scripts to the V8 runtime の翻訳です
モダンなJavaScriptで書けるようになったが、既存のスクリプトをそのままV8エンジンに変更すると動かなくなるかも。
今までのGASとV8ベースのGASは非互換性が少しあるので移行にあたって少し注意が必要。
V8移行手順
- スクリプトでV8エンジンを有効にする (適応方法参照)
- 非互換性を知って注意深くスクリプトを修正してね
- 「その他の差異」についても調査してスクリプトを修正してね。
- 「非互換性」「その他の差異」を修正し終わったら、モダンな書き方で変更を始められるよ
- 書き終わったらちゃんと想定どおり動くかテストしてね
- スクリプトをWebアプリや拡張機能として公開しているなら、新しいバージョンで再公開してね
非互換性と対応
Shiro
ベースのこれまでのGASは現在のJavaScriptの標準仕様と非互換性を持っています。
V8エンジンに移行する際はまず非互換性のある記法を修正しましょう。
for each (variable in object)
から for (variable in object)
に変える
これはfor each
で検索してeach
を削除するだけなので楽ですね。
Date.prototype.getYear()
からDate.prototype.getFullYear()
に変える
getFullYear()
は4桁で年を返す。
予約語を避ける
ECMAScriptの予約語を変数や関数名に使用しているなら、名前を変更します。
Rhino
ではECMAScriptの予約語のいくつかが許可されていて、既存のスクリプトでclass
,import
,export
などで命名しているかもしれないので注意が必要です。
const
で宣言した変数に再代入しないように書き換える
GASでconst
は以前から使えたが、以下のような挙動だった
// Rhino runtime
const x = 1;
x = 2; // No error
console.log(x); // Outputs 1
V8からは標準的な挙動になる
// V8 runtime
const x = 1;
x = 2; // Throws TypeError
console.log(x); // Never executed
そもそもGASでconst
使えることを知らなかった。
XMLリテラルやXMLオブジェクトはパースする
今までは非標準機能としてXMLを直接扱うことができました。
V8では代わりにXmlServixeクラスのparse
を使ってください。
// V8 runtime
var incompatibleXml1 = <container><item/></container>; // Don't use
var incompatibleXml2 = new XML('<container><item/></container>'); // Don't use
var xml3 = XmlService.parse('<container><item/></container>'); // OK
__iterator__
関数でカスタムイテレータを作っていたら、ECMAScript 6 iterators
で書き換える
Iteration protocols - JavaScript | MDN
グローバル変数を避ける
V8エンジンではスクリプトは呼び出される際に解析されるので、解析されていないスクリプトで宣言している変数を使おうとするとエラーになる。
スクリプトファイルが解析される順序はHTMLのscript
タグと同じで、上から順。
ファイルの順序を入れ替えれば対応できるが、それは望ましくない。
移行の際はグローバル変数を関数内に移動して、最初はundefined
で持つことで同じ機能を維持しながらエラーを回避できる。
// First.gs
var globalVar = calculate();
function myFunction() {
Logger.log("globalVar = %s", globalVar);
}
///////////////////////////////////////
// Second.gs
function calculate() {
return Math.random();
}
を
// First.gs
function myFunction2() {
var localVar = calculate();
Logger.log("localVar = %s", localVar);
}
////////////////////////////////////////
// Second.gs
var cachedValue;
function calculate() {
if (cachedValue == undefined) {
cachedValue = Math.random();
}
return cachedValue;
}
のように書き換える
条件付きcatch句を避ける
// Rhino runtime
try {
doSomething();
} catch (e if e instanceof TypeError) { // Don't use
// Handle exception
}
このような書き方でif条件を使えないので、以下のようにする
// V8 runtime
try {
doSomething();
} catch (e) {
if (e instanceof TypeError) {
// Handle exception
}
}
Object.prototype.toSource()
を使っていたら削除してください
初耳学
JavaScript 1.3のメソッドですがV8ではサポートされていません。
その他の違い、注意点
Date
クラスのLocal関連メソッドの出力形式の違い
toLocalString()
,toLocalDateString()
,toLocalTimeString()
の出力形式がRhino
とV8
で違うので注意
Error.fileName
とError.lineNumber
がサポートされていない
依存している処理があるなら削除する。
Error.prototype.stack
で代替できるが、これも非推奨
enumの扱いの違い
enumオブジェクトにJSON.stringify()
した際Rhino
では{}
を返すのみだったがV8
ではオブジェクト名を返すようになった。
引数にundefined
を渡す際の扱いの違い
Rhino
では文字列の"undefined"
として扱われたが、V8
ではnull
を渡したことと同等になる。
感想
web版VBAもJavaScript(typescript)ベースだし、IEももうすぐお亡くなりになるのでモダンなJSを気軽に書ける環境が整ってきた感。
Excel操作をJavaScriptで記録 ~Microsoft、“Office Scripts”をパブリックプレビュー - 窓の杜
V8エンジンとstrictモードはデフォになって欲しい
参考
V8 Runtime Overview | Apps Script | Google Developers
Migrating scripts to the V8 runtime | Apps Script | Google Developers
google/clasp