W Google Apps Script i JavaScript środowisko wykonawcze lub środowisko wykonawcze zawiera silnik JavaScript, który analizuje i wykonuje kod skryptu. Środowisko wykonawcze określa zasady dostępu do pamięci, sposób interakcji programu z systemem operacyjnym komputera oraz prawidłową składnię programu. Każda przeglądarka internetowa ma środowisko wykonawcze dla JavaScriptu.
W przeszłości Apps Script korzystał z interpretera JavaScript Rhino firmy Mozilla. Rhino zapewniało wygodny sposób wykonywania skryptów deweloperskich w Apps Script, ale jednocześnie wiązało Apps Script z określoną wersją JavaScriptu (ES5). Deweloperzy Apps Script nie mogą używać w skryptach nowoczesnej składni i funkcji JavaScriptu, jeśli korzystają ze środowiska wykonawczego Rhino.
Aby rozwiązać ten problem, Apps Script jest teraz obsługiwany przez środowisko wykonawcze V8, które jest używane w Chrome i Node.js. Przenieś istniejące skrypty do V8, aby korzystać z nowoczesnej składni i funkcji JavaScript.
Z tego artykułu dowiesz się, jakie nowe funkcje są dostępne dzięki V8 i jak włączyć V8 w skryptach. Przenoszenie skryptów do V8 opisuje czynności, które należy wykonać, aby przenieść istniejące skrypty do środowiska wykonawczego V8.
Funkcje środowiska wykonawczego V8
Skrypty korzystające ze środowiska wykonawczego V8 mogą korzystać z tych funkcji:
Nowoczesna składnia ECMAScript
Używaj nowoczesnej składni ECMAScript w skryptach, które są obsługiwane przez środowisko wykonawcze V8. Ta składnia obejmuje let, const i wiele innych popularnych funkcji.
Krótką listę popularnych ulepszeń składni, które możesz wprowadzić za pomocą środowiska wykonawczego V8, znajdziesz w przykładach składni V8.
Środowisko wykonawcze Apps Script V8 ma pewne ograniczenia i kluczowe różnice w porównaniu z innymi popularnymi środowiskami wykonawczymi JavaScriptu. Więcej informacji znajdziesz w sekcji Ograniczenia środowiska wykonawczego Apps Script V8.
Ulepszone wykrywanie funkcji
Wykrywanie funkcji Apps Script zostało ulepszone w przypadku skryptów korzystających z V8. Nowe środowisko wykonawcze rozpoznaje te formaty definicji funkcji:
function normalFunction() {} async function asyncFunction() {} function* generatorFunction() {} var varFunction = function() {} let letFunction = function() {} const constFunction = function() {} var namedVarFunction = function alternateNameVarFunction() {} let namedLetFunction = function alternateNameLetFunction() {} const namedConstFunction = function alternateNameConstFunction() {} var varAsyncFunction = async function() {} let letAsyncFunction = async function() {} const constAsyncFunction = async function() {} var namedVarAsyncFunction = async function alternateNameVarAsyncFunction() {} let namedLetAsyncFunction = async function alternateNameLetAsyncFunction() {} const namedConstAsyncFunction = async function alternateNameConstAsyncFunction() {} var varGeneratorFunction = function*() {} let letGeneratorFunction = function*() {} const constGeneratorFunction = function*() {} var namedVarGeneratorFunction = function* alternateNameVarGeneratorFunction() {} let namedLetGeneratorFunction = function* alternateNameLetGeneratorFunction() {} const namedConstGeneratorFunction = function* alternateNameConstGeneratorFunction() {} var varLambda = () => {} let letLambda = () => {} const constLambda = () => {} var varAsyncLambda = async () => {} let letAsyncLambda = async () => {} const constAsyncLambda = async () => {}
Wywoływanie metod obiektów połączeń z poziomu wyzwalaczy i wywołań zwrotnych
Skrypty korzystające z V8 mogą wywoływać metody obiektów i statyczne metody klas w miejscach, w których można było już wywoływać metody biblioteki. Są to między innymi:
- Wywoływanie funkcji w dodatkach do Google Workspace
- Wyzwalacze, które można zainstalować
- Elementy menu w edytorach Google Workspace
- funkcje wywołania zwrotnego użytkownika, takie jak opisana w przykładzie kodu
ScriptApp.newStateToken().
Ten przykład w V8 pokazuje użycie metod obiektu podczas tworzenia elementów menu w Arkuszach Google:
function onOpen() {
const ui = SpreadsheetApp.getUi(); // Or DocumentApp, SlidesApp, or FormApp.
ui.createMenu('Custom Menu')
.addItem('First item', 'menu.item1')
.addSeparator()
.addSubMenu(ui.createMenu('Sub-menu')
.addItem('Second item', 'menu.item2'))
.addToUi();
}
const menu = {
item1: function() {
SpreadsheetApp.getUi().alert('You clicked: First item');
},
item2: function() {
SpreadsheetApp.getUi().alert('You clicked: Second item');
}
}
Wyświetl logi
Apps Script udostępnia 2 usługi rejestrowania: Logger i klasę console. Obie te usługi zapisują logi w tej samej usłudze Stackdriver Logging.
Aby wyświetlić dzienniki Logger i console, u góry edytora skryptów kliknij Dziennik wykonywania.
Wyświetlanie wykonań
Aby wyświetlić historię wykonywania skryptu, otwórz projekt Apps Script i po lewej stronie kliknij Wykonania .
Panel Wykonania nie zawiera logów z sygnaturami czasowymi poszczególnych wywołań usługi Apps Script. Użyj usługi console, aby tworzyć odpowiednie komunikaty dziennika. Wszystkie logi utworzone za pomocą console są wyświetlane w panelu Wykonania.
Przykłady składni V8
Poniżej znajduje się krótka lista popularnych funkcji składniowych dostępnych w skryptach korzystających ze środowiska wykonawczego V8.
let i const
Słowa kluczowe let i const umożliwiają odpowiednio definiowanie zmiennych lokalnych o zakresie bloku i stałych o zakresie bloku.
// V8 runtime let s = "hello"; if (s === "hello") { s = "world"; console.log(s); // Prints "world" } console.log(s); // Prints "hello" const N = 100; N = 5; // Results in TypeError |
Funkcje strzałkowe
Funkcje strzałkowe umożliwiają zwięzłe definiowanie funkcji w wyrażeniach.
// Rhino runtime function square(x) { return x * x; } console.log(square(5)); // Outputs 25 |
// V8 runtime const square = x => x * x; console.log(square(5)); // Outputs 25 // Outputs [1, 4, 9] console.log([1, 2, 3].map(x => x * x)); |
Zajęcia
Klasy umożliwiają koncepcyjne porządkowanie kodu za pomocą dziedziczenia. Klasy w V8 są przede wszystkim cukrem syntaktycznym w stosunku do dziedziczenia opartego na prototypach JavaScript.
// V8 runtime class Rectangle { constructor(width, height) { // class constructor this.width = width; this.height = height; } logToConsole() { // class method console.log(`Rectangle(width=${this.width}, height=${this.height})`); } } const r = new Rectangle(10, 20); r.logToConsole(); // Outputs Rectangle(width=10, height=20) |
Przypisania destrukcyjne
Wyrażenia przypisania destrukcyjnego to szybki sposób na rozpakowanie wartości z tablic i obiektów do odrębnych zmiennych.
// Rhino runtime var data = {a: 12, b: false, c: 'blue'}; var a = data.a; var c = data.c; console.log(a, c); // Outputs 12 "blue" var a = [1, 2, 3]; var x = a[0]; var y = a[1]; var z = a[2]; console.log(x, y, z); // Outputs 1 2 3 |
// V8 runtime const data = {a: 12, b: false, c: 'blue'}; const {a, c} = data; console.log(a, c); // Outputs 12 "blue" const array = [1, 2, 3]; const [x, y, z] = array; console.log(x, y, z); // Outputs 1 2 3 |
Literały szablonu
Literały szablonu to literały ciągów znaków, które umożliwiają umieszczanie wyrażeń. Pozwalają one uniknąć bardziej złożonych instrukcji łączenia ciągów znaków.
// Rhino runtime var name = 'Hi ' + first + ' ' + last + '.'; var url = 'http://localhost:3000/api/messages/' + id; |
// V8 runtime const name = `Hi ${first} ${last}.`; const url = `http://localhost:3000/api/messages/${id}`; |
Parametry domyślne
Parametry domyślne umożliwiają określanie wartości domyślnych parametrów funkcji w deklaracji funkcji. Może to uprościć kod w treści funkcji, ponieważ eliminuje konieczność jawnego przypisywania wartości domyślnych do brakujących parametrów.
// Rhino runtime function hello(greeting, name) { greeting = greeting || "hello"; name = name || "world"; console.log( greeting + " " + name + "!"); } hello(); // Outputs "hello world!" |
// V8 runtime const hello = function(greeting="hello", name="world") { console.log( greeting + " " + name + "!"); } hello(); // Outputs "hello world!" |
Ciągi wielowierszowe
Definiuj ciągi wielowierszowe, używając tej samej składni co literały szablonu. Podobnie jak w przypadku literałów szablonu ta składnia pozwala uniknąć łączenia ciągów znaków i uprościć definicje ciągów znaków.
// Rhino runtime var multiline = "This string is sort of\n" + "like a multi-line string,\n" + "but it's not really one."; |
// V8 runtime const multiline = `This on the other hand, actually is a multi-line string, thanks to JavaScript ES6`; |
Ograniczenia środowiska wykonawczego V8
Środowisko wykonawcze V8 Apps Script nie jest standardowym środowiskiem Node.js ani przeglądarki. Może to powodować problemy ze zgodnością podczas wywoływania bibliotek innych firm lub dostosowywania przykładów kodu z innych środowisk JavaScript.
Niedostępne interfejsy API
Te standardowe interfejsy JavaScript API NIE są dostępne w środowisku wykonawczym V8 Apps Script:
- Liczniki czasu:
setTimeout,setInterval,clearTimeout,clearInterval - Strumienie:
ReadableStream,WritableStream,TextEncoder,TextDecoder - Interfejsy API sieci:
fetch,FormData,File,Blob,URL,URLSearchParams,DOMException,atob,btoa - Kryptowaluty:
crypto,SubtleCrypto - Obiekty globalne:
window,navigator,performance,process(Node.js)
Zamiast tego używaj tych interfejsów Apps Script API:
- Liczniki czasu: używaj
Utilities.sleepdo wstrzymywania synchronicznego. Timery asynchroniczne nie są obsługiwane. - Pobieranie: użyj
UrlFetchApp.fetch(url, params), aby wysyłać żądania HTTP(S). - atob: użyj
Utilities.base64Decodedo dekodowania ciągów znaków zakodowanych w formacie Base64. - btoa: użyj
Utilities.base64Encodedo kodowania ciągów znaków w formacie Base64. - Kryptografia: użyj
Utilitiesw przypadku funkcji kryptograficznych, takich jakcomputeDigest,computeHmacSha256SignatureicomputeRsaSha256Signature.
W przypadku interfejsów API, które nie mają alternatywy w Apps Script, np. TextEncoder, możesz czasami użyć polyfill. Polyfill to biblioteka, która replikuje funkcje interfejsu API niedostępne domyślnie w środowisku wykonawczym.
Zanim użyjesz polyfillu, upewnij się, że jest on zgodny ze środowiskiem wykonawczym V8 w Apps Script.
Ograniczenia asynchroniczne
Środowisko wykonawcze V8 obsługuje składnię async i await oraz obiekt Promise.
Środowisko wykonawcze Apps Script jest jednak zasadniczo synchroniczne.
- Mikrozadania (obsługiwane): środowisko wykonawcze przetwarza kolejkę mikrozadań (w której występują wywołania zwrotne
Promise.theni rozwiązaniaawait) po wyczyszczeniu bieżącego stosu wywołań. - Makrozadania (nieobsługiwane): Apps Script nie ma standardowej pętli zdarzeń dla makrozadań. Funkcje takie jak
setTimeoutisetIntervalsą niedostępne. - Wyjątek dotyczący WebAssembly: interfejs WebAssembly API jest jedyną wbudowaną funkcją, która działa w sposób nieblokujący w środowisku wykonawczym, co umożliwia stosowanie określonych asynchronicznych wzorców kompilacji (WebAssembly.instantiate).
Wszystkie operacje wejścia/wyjścia, takie jak UrlFetchApp.fetch, są blokujące. Aby uzyskać równoległe żądania sieciowe, użyj
UrlFetchApp.fetchAll.
Ograniczenia dotyczące zajęć
Środowisko wykonawcze V8 ma określone ograniczenia dotyczące nowoczesnych funkcji klas ES6+:
- Pola prywatne: prywatne pola klasy (np.
#field) nie są obsługiwane i powodują błędy analizowania. Aby uzyskać prawdziwe hermetyzowanie, rozważ użycie domknięć lubWeakMap. - Pola statyczne: bezpośrednie deklaracje pól statycznych w treści klasy (np.
static count = 0;) nie są obsługiwane. Przypisz do klasy właściwości statyczne po jej zdefiniowaniu (np.MyClass.count = 0;).
Ograniczenia modułów
- Moduły ES6: środowisko wykonawcze V8 nie obsługuje modułów ES6 (
import/export). Aby używać bibliotek, musisz skorzystać z mechanizmu bibliotek Apps Script lub połączyć kod i jego zależności w jeden plik skryptu. (Issue Tracker) - Kolejność wykonywania plików: wszystkie pliki skryptu w projekcie są wykonywane w zakresie globalnym. Najlepiej unikać kodu najwyższego poziomu z efektami ubocznymi i upewnić się, że funkcje i klasy są zdefiniowane przed użyciem w plikach. W edytorze możesz jawnie uporządkować pliki, jeśli istnieją między nimi zależności.
Włącz środowisko wykonawcze V8
Jeśli skrypt korzysta ze środowiska wykonawczego Rhino, przełącz go na V8, wykonując te czynności:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Włącz środowisko wykonawcze Chrome V8.
Możesz też określić środowisko wykonawcze skryptu bezpośrednio, edytując plik manifestu skryptu:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Wyświetlaj plik manifestu „appsscript.json” w edytorze.
- Po lewej stronie kliknij Edytor >
appsscript.json. - W pliku manifestu
appsscript.jsonustaw poleruntimeVersionna wartośćV8. - U góry kliknij Zapisz projekt .
W artykule Przenoszenie skryptów do V8 znajdziesz inne czynności, które należy wykonać, aby skrypt działał prawidłowo w środowisku V8.
Włącz środowisko wykonawcze Rhino
Jeśli Twój skrypt korzysta z V8 i musisz przełączyć go na oryginalne środowisko wykonawcze Rhino, wykonaj te czynności:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Odznacz pole wyboru Włącz środowisko wykonawcze Chrome 8.
Możesz też edytować plik manifestu skryptu:
- Otwórz projekt Apps Script.
- Po lewej stronie kliknij Ustawienia projektu .
- Zaznacz pole wyboru Wyświetlaj plik manifestu „appsscript.json” w edytorze.
- Po lewej stronie kliknij Edytor >
appsscript.json. - W pliku manifestu
appsscript.jsonustaw poleruntimeVersionna wartośćDEPRECATED_ES5. - U góry kliknij Zapisz projekt .
Jak przeprowadzić migrację istniejących skryptów?
W przewodniku Przenoszenie skryptów do V8 znajdziesz opis czynności, które musisz wykonać, aby przenieść istniejący skrypt do środowiska V8. Obejmuje to włączenie środowiska wykonawczego V8 i sprawdzenie skryptu pod kątem znanych niezgodności.
Automatyczna migracja skryptów do V8
Od 18 lutego 2020 roku Google stopniowo przenosi do V8 dotychczasowe skrypty, które przejdą nasz automatyczny test zgodności. Po migracji skrypty, których dotyczy problem, będą nadal działać normalnie.
Jeśli chcesz zrezygnować z automatycznej migracji skryptu, ustaw w jego manifeście pole
runtimeVersion
na wartość DEPRECATED_ES5. W dowolnym momencie możesz ręcznie przenieść skrypt do V8.
Jak zgłaszać błędy?
W przewodniku pomocy znajdziesz informacje o tym, jak uzyskać pomoc dotyczącą programowania na stronie Stack Overflow, wyszukiwać istniejące raporty o problemach, zgłaszać nowe błędy i przesyłać prośby o nowe funkcje.