Help us understand the problem. What is going on with this article?

GASがV8エンジンに対応したのでドキュメント読んだ

GASがV8エンジンに対応したのでドキュメント読んでみた

公式のV8移行ドキュメント
Migrating scripts to the V8 runtime
を読んだのでメモ

だいぶテキトーです。

経緯

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で変数宣言したり、アロー関数を使ったりできます。

G Suite の今後のリリース


適用方法

現在、デフォルトエンジンはRhinoなので、V8に変更してあげる必要があります。

方法は以下の2つがあるのですが、前者は現在未リリース

  • メニューから切り替える方法 (実行タブに追加される予定)
  • スクリプトマニフェストでエンジンを指定する方法

後者のやり方は以下のツイートがわかりやすい。

https://twitter.com/howdy39/status/1225168177996320768?s=20


移行

ここから公式ドキュメントMigrating scripts to the V8 runtime の翻訳です

モダンなJavaScriptで書けるようになったが、既存のスクリプトをそのままV8エンジンに変更すると動かなくなるかも。

今までのGASとV8ベースのGASは非互換性が少しあるので移行にあたって少し注意が必要。

V8移行手順

  1. スクリプトでV8エンジンを有効にする (適応方法参照)
  2. 非互換性を知って注意深くスクリプトを修正してね
  3. 「その他の差異」についても調査してスクリプトを修正してね。
  4. 「非互換性」「その他の差異」を修正し終わったら、モダンな書き方で変更を始められるよ
  5. 書き終わったらちゃんと想定どおり動くかテストしてね
  6. スクリプトを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()の出力形式がRhinoV8で違うので注意

Error.fileNameError.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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした