Présentation de l'environnement d'exécution V8

Dans Google Apps Script et JavaScript, un environnement d'exécution ou environnement d'exécution contient le moteur JavaScript qui analyse et exécute le code du script. L'environnement d'exécution fournit des règles sur la façon d'accéder à la mémoire, sur la manière dont le programme peut interagir avec le système d'exploitation de l'ordinateur et sur la syntaxe de programme autorisée. Chaque navigateur Web dispose d'un environnement d'exécution pour JavaScript.

Historiquement, Apps Script était alimenté par l'interpréteur JavaScript Rhino de Mozilla. Bien que Rhino ait fourni un moyen pratique pour Apps Script d'exécuter des scripts de développeur, il a également lié Apps Script à une version JavaScript spécifique (ES5). Les développeurs Apps Script ne peuvent pas utiliser de syntaxe et de fonctionnalités JavaScript plus modernes dans les scripts utilisant l'environnement d'exécution Rhino.

Pour résoudre ce problème, Apps Script est désormais compatible avec l'environnement d'exécution V8 qui alimente Chrome et Node.js. Migrez les scripts existants vers V8 afin de profiter de la syntaxe et des fonctionnalités JavaScript modernes.

Cette page décrit les nouvelles fonctionnalités activées par V8 et explique comment activer V8 pour l'utiliser dans vos scripts. La section Migrer des scripts vers V8 décrit les étapes à suivre pour migrer des scripts existants afin d'utiliser l'environnement d'exécution V8.

Fonctionnalités de l'environnement d'exécution V8

Les scripts qui utilisent l'environnement d'exécution V8 peuvent profiter des fonctionnalités suivantes :

Syntaxe ECMAScript moderne

Utilisez la syntaxe ECMAScript moderne dans les scripts alimentés par l'environnement d'exécution V8. Cette syntaxe inclut let, const et de nombreuses autres fonctionnalités populaires.

Consultez les exemples de syntaxe V8 pour obtenir une courte liste des améliorations de syntaxe populaires que vous pouvez apporter à l'aide de l'environnement d'exécution V8.

L'environnement d'exécution Apps Script V8 présente certaines limites et différences clés par rapport aux autres environnements d'exécution JavaScript courants. Pour en savoir plus, consultez la section Limites de l'environnement d'exécution Apps Script V8.

Détection améliorée des fonctions

La détection des fonctions Apps Script est améliorée pour les scripts utilisant V8. Le nouvel environnement d'exécution reconnaît les formats de définition de fonction suivants :

      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 () => {}

Appeler des méthodes d'objet à partir de déclencheurs et de rappels

Les scripts utilisant V8 peuvent appeler des méthodes d'objet et des méthodes statiques de classe à partir d'emplacements où vous pouviez déjà appeler des méthodes de bibliothèque. Ces emplacements incluent les éléments suivants :

L'exemple V8 suivant montre l'utilisation de méthodes d'objet lors de la création d'éléments de menu dans Google Sheets :

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');
  }
}

Afficher les journaux

Apps Script fournit deux services de journalisation : le Logger service et la console classe. Ces deux services écrivent des journaux dans le même service Stackdriver Logging.

Pour afficher les journaux Logger et console, cliquez sur Journal d'exécution en haut de l'éditeur de script.

Afficher les exécutions

Pour afficher l'historique d'exécution de votre script, ouvrez le projet Apps Script et cliquez sur Exécutions à gauche.

Le panneau Exécutions ne fournit pas de journaux horodatés des appels de service Apps Script individuels. Utilisez le console service pour créer des messages de journal appropriés. Tous les journaux créés avec console s'affichent dans le panneau Exécutions.

Exemples de syntaxe V8

Voici une courte liste des fonctionnalités syntaxiques populaires disponibles pour les scripts utilisant l'environnement d'exécution V8.

let et const

Les mots clés let et const vous permettent de définir respectivement des variables locales de portée de bloc et des constantes de portée de bloc.

// 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
      

Fonctions fléchées

Les fonctions fléchées offrent un moyen compact de définir des fonctions dans des expressions.

// 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));
      

Classes

Les classes permettent d'organiser conceptuellement le code avec l'héritage. Dans V8, les classes sont principalement un sucre syntaxique par rapport à l'héritage basé sur le prototype 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)
      

Affectations de déstructuration

Les expressions d'affectation de déstructuration sont un moyen rapide de dépaqueter des valeurs de tableaux et d'objets dans des variables distinctes.

// 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


      

Littéraux de modèle

Les littéraux de modèle sont des littéraux de chaîne qui autorisent les expressions intégrées. Ils vous permettent d'éviter des instructions de concaténation de chaînes plus complexes.

// 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}`;


      

Paramètres par défaut

Les paramètres par défaut vous permettent de spécifier des valeurs par défaut pour les paramètres de fonction dans la déclaration. Cela peut simplifier le code dans le corps de la fonction, car il n'est plus nécessaire d'attribuer explicitement des valeurs par défaut aux paramètres manquants.

// 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!"

      

Chaînes multilignes

Définissez des chaînes multilignes à l'aide de la même syntaxe que les littéraux de modèle. Comme pour les littéraux de modèle, cette syntaxe vous permet d'éviter les concaténations de chaînes et de simplifier les définitions de chaînes.

// 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`;
      

Limites de l'environnement d'exécution V8

L'environnement d'exécution Apps Script V8 n'est pas un environnement Node.js ou de navigateur standard. Cela peut entraîner des problèmes de compatibilité lorsque vous appelez des bibliothèques tierces ou adaptez des exemples de code provenant d'autres environnements JavaScript.

API non disponibles

Les API JavaScript standards suivantes NE SONT PAS disponibles dans l'environnement d'exécution Apps Script V8 :

  • Minuteurs : setTimeout, setInterval, clearTimeout, clearInterval
  • Flux : ReadableStream, WritableStream, TextEncoder, TextDecoder
  • API Web: fetch, FormData, File, Blob, URL, URLSearchParams, DOMException, atob, btoa
  • Crypto: crypto, SubtleCrypto
  • Objets globaux : window, navigator, performance, process (Node.js)

Utilisez les API Apps Script suivantes comme alternatives :

Pour les API sans alternative Apps Script, telles que TextEncoder, vous pouvez parfois utiliser un polyfill. Un polyfill est une bibliothèque qui réplique les fonctionnalités d'API qui ne sont pas disponibles par défaut dans l'environnement d'exécution. Avant d'utiliser un polyfill, vérifiez qu'il est compatible avec l'environnement d'exécution V8 d'Apps Script.

Limites asynchrones

L'environnement d'exécution V8 est compatible avec la syntaxe async et await, ainsi qu'avec l'objet Promise. Toutefois, l'environnement d'exécution Apps Script est fondamentalement synchrone.

  • Microtâches (compatibles) : l'environnement d'exécution traite la file d'attente des microtâches (où se produisent les Promise.then rappels et les await résolutions) une fois que la pile d'appels actuelle est effacée.
  • Macrotâches (non compatibles) : Apps Script ne dispose pas de boucle d'événement standard pour les macrotâches. Les fonctions telles que setTimeout et setInterval ne sont pas disponibles.
  • Exception WebAssembly : l'API WebAssembly est la seule fonctionnalité intégrée qui fonctionne de manière non bloquante dans l'environnement d'exécution, ce qui permet des modèles de compilation asynchrones spécifiques (WebAssembly.instantiate).

Toutes les opérations d'E/S, telles que UrlFetchApp.fetch, sont bloquantes. Pour effectuer des requêtes réseau parallèles, utilisez UrlFetchApp.fetchAll.

Limites de classe

L'environnement d'exécution V8 présente des limites spécifiques concernant les fonctionnalités de classe ES6+ modernes :

  • Champs privés : les champs de classe privés (par exemple, #field) ne sont pas compatibles et entraînent des erreurs d’analyse. Envisagez d'utiliser des fermetures ou WeakMap pour une véritable encapsulation.
  • Champs statiques : les déclarations de champs statiques directs dans le corps de la classe (par exemple, static count = 0;) ne sont pas compatibles. Attribuez des propriétés statiques à la classe après sa définition (par exemple, MyClass.count = 0;).

Limites de module

  • Modules ES6 : l'environnement d'exécution V8 n'est pas compatible avec les modules ES6 (import / export). Pour utiliser des bibliothèques, vous devez utiliser le mécanisme de bibliothèque Apps Script ou regrouper votre code et ses dépendances dans un seul fichier de script. (Outil de suivi des problèmes)
  • Ordre d'exécution des fichiers : tous les fichiers de script de votre projet sont exécutés dans une portée globale. Il est préférable d'éviter le code de premier niveau avec des effets secondaires et de s'assurer que les fonctions et les classes sont définies avant d'être utilisées dans les fichiers. Organisez explicitement vos fichiers dans l'éditeur si des dépendances existent entre eux.

Activer l'environnement d'exécution V8

Si un script utilise l'environnement d'exécution Rhino, passez à V8 en procédant comme suit :

  1. Ouvrez le projet Apps Script.
  2. À gauche, cliquez sur Paramètres du projet .
  3. Cochez la case Activer l'environnement d'exécution Chrome V8.

Vous pouvez également spécifier directement l'environnement d'exécution du script en modifiant le fichier manifeste du script :

  1. Ouvrez le projet Apps Script.
  2. À gauche, cliquez sur Paramètres du projet .
  3. Cochez la case Afficher le fichier manifeste "appsscript.json" dans l'éditeur.
  4. À gauche, cliquez sur Éditeur > appsscript.json.
  5. Dans le fichier manifeste appsscript.json, définissez le runtimeVersion champ sur la valeur V8.
  6. En haut, cliquez sur Enregistrer le projet .

La section Migrer des scripts vers V8 explique les autres étapes à suivre pour vous assurer que votre script fonctionne correctement avec V8.

Activer l'environnement d'exécution Rhino

Si votre script utilise V8 et que vous devez le passer à l'environnement d'exécution Rhino d'origine, procédez comme suit :

  1. Ouvrez le projet Apps Script.
  2. À gauche, cliquez sur Paramètres du projet .
  3. Décochez la case Activer l'environnement d'exécution Chrome V8.

Vous pouvez également modifier le fichier manifeste de votre script :

  1. Ouvrez le projet Apps Script.
  2. À gauche, cliquez sur Paramètres du projet .
  3. Cochez la case Afficher le fichier manifeste "appsscript.json" dans l'éditeur.
  4. À gauche, cliquez sur Éditeur > appsscript.json.
  5. Dans le fichier manifeste appsscript.json, définissez le runtimeVersion champ sur la valeur DEPRECATED_ES5.
  6. En haut, cliquez sur Enregistrer le projet .

Comment migrer des scripts existants ?

Le guide Migrer des scripts vers V8 décrit les étapes à suivre pour migrer un script existant afin d'utiliser V8. Cela implique d'activer l'environnement d'exécution V8 et de vérifier si le script présente des incompatibilités connues.

Migration automatique des scripts vers V8

À partir du 18 février 2020, Google migre progressivement vers V8 les scripts existants qui réussissent notre test de compatibilité automatisé. Les scripts concernés continuent de fonctionner normalement après la migration.

Si vous souhaitez désactiver la migration automatique d'un script, définissez le runtimeVersion champ dans son fichier manifeste sur DEPRECATED_ES5. Vous pourrez ensuite choisir de migrer manuellement le script vers V8 à tout moment

Comment signaler des bugs ?

Le guide d'assistance explique comment obtenir de l'aide à la programmation sur Stack Overflow, rechercher des rapports de problèmes existants, signaler de nouveaux bugs et envoyer de nouvelles demandes de fonctionnalités.