Visão geral do ambiente de execução V8

No Google Apps Script e no JavaScript, um ambiente de execução contém o mecanismo JavaScript que analisa e executa o código do script. O ambiente de execução fornece regras sobre como a memória é acessada, como o programa pode interagir com o sistema operacional do computador e qual sintaxe de programação é permitida. Cada navegador da Web tem um ambiente de execução para JavaScript.

Historicamente, o Apps Script é alimentado pelo interpretador JavaScript Rhino da Mozilla. Embora o Rhino oferecesse uma maneira conveniente para o Apps Script executar scripts de desenvolvedores, ele também vinculava o Apps Script a uma versão específica do JavaScript (ES5). Os desenvolvedores do Apps Script não podem usar uma sintaxe e recursos mais modernos do JavaScript em scripts que usam o ambiente de execução Rhino.

Para resolver esse problema, o Apps Script agora é compatível com o ambiente de execução V8, que alimenta o Chrome e o Node.js. Migre os scripts atuais para o V8 para aproveitar a sintaxe e os recursos modernos do JavaScript.

Nesta página, descrevemos os novos recursos ativados pelo V8 e como você pode ativar o V8 para uso nos seus scripts. Migrar scripts para o V8 descreve as etapas para migrar scripts atuais e usar o ambiente de execução do V8.

Recursos do ambiente de execução V8

Os scripts que usam o ambiente de execução do V8 podem aproveitar os seguintes recursos:

Sintaxe moderna do ECMAScript

Use a sintaxe moderna do ECMAScript em scripts com tecnologia do ambiente de execução V8. Essa sintaxe inclui let, const e muitos outros recursos populares.

Consulte Exemplos de sintaxe do V8 para uma pequena lista de melhorias de sintaxe populares que você pode fazer usando o ambiente de execução do V8.

O ambiente de execução V8 do Apps Script tem algumas limitações e diferenças importantes em comparação com outros ambientes de execução JavaScript comuns. Consulte Limitações do ambiente de execução do V8 do Apps Script para mais detalhes.

Detecção de função aprimorada

A detecção de funções do Apps Script foi aprimorada para scripts que usam o V8. O novo ambiente de execução reconhece estes formatos de definição de função:

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

Chamar métodos de objetos de triggers e callbacks

Os scripts que usam o V8 podem chamar métodos de objetos e métodos estáticos de classes em locais onde já era possível chamar métodos de biblioteca. Esses lugares incluem:

O exemplo do V8 a seguir mostra o uso de métodos de objeto ao construir itens de menu no Google Planilhas:

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

Ver registros

O Apps Script oferece dois serviços de geração de registros: o serviço Logger e a classe console. Os dois serviços gravam registros no mesmo serviço do Stackdriver Logging.

Para mostrar os registros Logger e console, clique em Registro de execução na parte de cima do editor de script.

Ver execuções

Para conferir o histórico de execução do script, abra o projeto do Apps Script e, à esquerda, clique em Execuções .

O painel Execuções não fornece registros com carimbo de data/hora das chamadas de serviço individuais do Apps Script. Use o serviço console para criar mensagens de registro adequadas. Todos os registros criados com console aparecem no painel Execuções.

Exemplos de sintaxe do V8

Confira abaixo uma pequena lista de recursos sintáticos populares disponíveis para scripts que usam o ambiente de execução V8.

let e const

As palavras-chave let e const permitem definir variáveis locais e constantes de escopo de bloco, respectivamente.

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

Funções de seta

As funções de seta oferecem uma maneira compacta de definir funções em expressões.

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

As classes oferecem uma maneira de organizar conceitualmente o código com herança. As classes em V8 são principalmente açúcar sintático sobre a herança baseada em protótipo do 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)
      

Atribuições de desestruturação

As expressões de atribuição por desestruturação são uma maneira rápida de desempacotar valores de matrizes e objetos em variáveis distintas.

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


      

Literais de modelo

Literais de modelo são literais de string que permitem expressões incorporadas. Elas evitam instruções mais complexas de concatenação de strings.

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


      

Parâmetros padrão

Com os parâmetros padrão, você pode especificar valores padrão para parâmetros de função na declaração da função. Isso pode simplificar o código no corpo da função, já que remove a necessidade de atribuir valores padrão explicitamente a parâmetros ausentes.

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

      

Strings de várias linhas

Defina strings de várias linhas usando a mesma sintaxe dos literais de modelo. Assim como com literais de modelo, essa sintaxe permite evitar concatenações de strings e simplificar definições de strings.

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

Limitações do ambiente de execução V8

O ambiente de execução do Apps Script V8 não é um ambiente padrão do Node.js ou do navegador. Isso pode causar problemas de compatibilidade ao chamar bibliotecas de terceiros ou adaptar exemplos de código de outros ambientes JavaScript.

APIs indisponíveis

As seguintes APIs JavaScript padrão NÃO estão disponíveis no ambiente de execução V8 do Apps Script:

  • Temporizadores: setTimeout, setInterval, clearTimeout, clearInterval
  • Streams: ReadableStream, WritableStream, TextEncoder, TextDecoder
  • APIs da Web: fetch, FormData, File, Blob, URL, URLSearchParams, DOMException, atob, btoa
  • Cripto: crypto, SubtleCrypto
  • Objetos globais: window, navigator, performance, process (Node.js)

Use as seguintes APIs do Apps Script como alternativas:

Para APIs sem uma alternativa do Apps Script, como TextEncoder, às vezes é possível usar um polyfill. Um polyfill é uma biblioteca que replica a funcionalidade da API não disponível por padrão no ambiente de execução. Antes de usar um polyfill, confirme se ele é compatível com o ambiente de execução V8 do Apps Script.

Limitações assíncronas

O ambiente de execução do V8 é compatível com a sintaxe async e await e com o objeto Promise. No entanto, o ambiente de execução do Apps Script é fundamentalmente síncrono.

  • Microtarefas (compatível): o ambiente de execução processa a fila de microtarefas (em que callbacks Promise.then e resoluções await ocorrem) depois que a pilha de chamadas atual é limpa.
  • Macrotarefas (não compatíveis): o Apps Script não tem um loop de eventos padrão para macrotarefas. Funções como setTimeout e setInterval não estão disponíveis.
  • Exceção do WebAssembly: a API WebAssembly é o único recurso integrado que opera de maneira não bloqueadora no tempo de execução, permitindo padrões de compilação assíncronos específicos (WebAssembly.instantiate).

Todas as operações de E/S, como UrlFetchApp.fetch, são de bloqueio. Para fazer solicitações de rede paralelas, use UrlFetchApp.fetchAll.

Limitações das turmas

O ambiente de execução V8 tem limitações específicas em relação aos recursos modernos de classe ES6+:

  • Campos privados: campos de classe privada (por exemplo, #field) não são compatíveis e causam erros de análise. Considere usar closures ou WeakMap para encapsulamento verdadeiro.
  • Campos estáticos: declarações diretas de campos estáticos no corpo da classe (por exemplo, static count = 0;) não são compatíveis. Atribua propriedades estáticas à classe após a definição dela (por exemplo, MyClass.count = 0;).

Limitações do módulo

  • Módulos ES6: o tempo de execução do V8 não oferece suporte a módulos ES6 (import / export). Para usar bibliotecas, use o mecanismo de biblioteca do Apps Script ou agrupe seu código e as dependências dele em um único arquivo de script. (Issue Tracker, link em inglês)
  • Ordem de execução de arquivos: todos os arquivos de script no seu projeto são executados em um escopo global. É melhor evitar código de nível superior com efeitos colaterais e garantir que as funções e classes sejam definidas antes de serem usadas em todos os arquivos. Ordene explicitamente os arquivos no editor se houver dependências entre eles.

Ativar o ambiente de execução V8

Se um script estiver usando o ambiente de execução do Rhino, mude para o V8 fazendo o seguinte:

  1. Abra o projeto do Apps Script.
  2. À esquerda, clique em Configurações do projeto .
  3. Marque a caixa de seleção Ativar tempo de execução do Chrome V8.

Se preferir, especifique o ambiente de execução do script diretamente editando o arquivo de manifesto do script:

  1. Abra o projeto do Apps Script.
  2. À esquerda, clique em Configurações do projeto .
  3. Selecione a caixa de seleção Mostrar arquivo de manifesto "appsscript.json" no editor.
  4. À esquerda, clique em Editor > appsscript.json.
  5. No arquivo de manifesto appsscript.json, defina o campo runtimeVersion com o valor V8.
  6. Na parte de cima, clique em Salvar projeto .

Migrar scripts para o V8 explica outras etapas que você precisa seguir para garantir que o script funcione bem usando o V8.

Ativar o ambiente de execução do Rhino

Se o script estiver usando V8 e você precisar mudar para o ambiente de execução Rhino original, faça o seguinte:

  1. Abra o projeto do Apps Script.
  2. À esquerda, clique em Configurações do projeto .
  3. Desmarque a caixa de seleção Ativar o tempo de execução do Chrome V8.

Como alternativa, edite o manifesto do script:

  1. Abra o projeto do Apps Script.
  2. À esquerda, clique em Configurações do projeto .
  3. Selecione a caixa de seleção Mostrar arquivo de manifesto "appsscript.json" no editor.
  4. À esquerda, clique em Editor > appsscript.json.
  5. No arquivo de manifesto appsscript.json, defina o campo runtimeVersion com o valor DEPRECATED_ES5.
  6. Na parte de cima, clique em Salvar projeto .

Como migro scripts atuais?

O guia Migração de scripts para o V8 descreve as etapas necessárias para migrar um script atual para usar o V8. Isso envolve ativar o tempo de execução V8 e verificar se há incompatibilidades conhecidas no script.

Migração automática de scripts para o V8

A partir de 18 de fevereiro de 2020, o Google vai migrar gradualmente para o V8 os scripts atuais que passarem no nosso teste de compatibilidade automatizado. Os scripts afetados continuam funcionando normalmente após a migração.

Se você quiser desativar a migração automática de um script, defina o campo runtimeVersion no manifesto como DEPRECATED_ES5. Escolha migrar o script para V8 manualmente a qualquer momento depois disso.

Como faço para informar bugs?

O guia de suporte explica como receber ajuda de programação no Stack Overflow, pesquisar relatórios de problemas existentes, registrar novos bugs e fazer novas solicitações de recursos.