[譯] 在 Google Apps 腳本中使用 ES6 和 npm 模塊

在 Google Apps 腳本中使用 ES6 和 npm 模塊前端

全部的 JavaScript 開發者都應該對 Google 的 Apps 腳本感興趣。
Apps 腳本有利於實現自動化。經過它,你能夠直接訪問 Google 的不少服務,好比 Google 表格、Google 郵箱、Google 文檔和 Google 日曆等。 只須要一點點想象力,你就可使用 Google Apps 腳本建立很是激動人心的 Apps 和 插件。vue

與首先要求你提供信用卡的 AppEngine 不一樣,Apps 腳本目前還是免費的。至少,Apps 腳本適用於快速建立「概念驗證」模型或原型。android

Apps 腳本有不一樣的用例。它主要用於爲 Google 表格、文檔或表單建立插件。可是,它也能夠建立「獨立」的 web 應用。webpack

咱們將探究建立獨立的 web 應用這一使用場景。ios

雖然使用 Apps 腳本有不少使人興奮的地方,可是它仍有一些使人很是痛苦的限制,好比:git

  1. Apps 腳本支持很老版本的 JavaScript(JavaScript 1.6)。所以,你可能想要使用的許多現代化的 JavaScript 特性在 Apps 腳本中都是不可用的。
  2. 沒有直接的方式來使用 npm modules(但仍是有辦法可用的,下面我會向你展現)。
  3. 建立一個好的 UI 界面(使用 bootstrap、Vue,甚至是自定義 CSS)是至關困難的。咱們必須找到將自定義腳本內聯到 HTML 頁面中的方法。
  4. 你的 web app 的訪問地址將會是一串冗長而醜陋的 URL。難以分享,更別提用這樣的地址提供商業服務。
  5. 「Apps 腳本」 這個名字真讓人難受。順便說一下,正確的名字確實是 「Apps」 後面跟空格,而後是 「Script」。對於這件事來講,沒有比這更缺少想象力的名字了。有些人可能喜歡這個名字,但我尚未遇到聲稱喜歡它的人! 當你在網上搜索 Apps 腳本功能的參考或示例時,你會更加討厭它。有一個流行的縮略:GAS (Google Apps Script)。可是,若是你搜索「在表格中使用 GAS」,我真的懷疑就連 Google 本身也不能弄明白。

本系列文章旨在規避 Apps 腳本的限制,併爲「獨立」的 web apps 和插件添加一些很是棒的功能。es6

首先,咱們會使用 webpack 和 babel,從 ES6 Javascript 代碼建立一個包。接下來,我會在咱們的 Apps 腳本項目中使用 npm 包。並在本系列的下面部分,在你的 Apps 腳本項目中咱們利用 CSS 框架和 VueJS 或 ReactJS 來開發現代化的用戶界面。讓咱們深刻探討吧!github

設置你的本地 Apps 腳本環境

首先,你必須熟悉 Apps 腳本環境。Google 提供了一個命令行工具叫 clasp 來在本地管理 Apps 腳本項目。web

安裝 clasp 命令行工具:npm

npm install @google/clasp -g
複製代碼

安裝後,登陸你的 Google 帳號。

clasp login
複製代碼

這將在你的瀏覽器裏打開一個受權頁面。你必須完成這些步驟。

受權完成後,你已經作好了建立你的第一個 Apps 腳本項目的準備。

一個簡單的基於 Apps 腳本的獨立 web app

新建一個文件夾。打開終端並轉到這個新建的文件夾。運行下面的命令來建立一個新的 Apps 腳本項目:

clasp create --type standalone --title "first GAS App"
複製代碼

在一樣的文件夾裏新建一個 app.js。並在 app.js 文件裏添加下面的函數:

app.js

function doGet(){
 return  ContentService.createTextOutput("Hello World!");
}
複製代碼

爲了 webapp 類型的 Appscript 項目,你須要有一個名爲 doGet() 的函數。doGet() 是執行頁面渲染的函數。
在上面的例子裏,輸出結果是一段簡單的文本。常見的 webapp 應該返回一個完整的 HTML 頁面。爲了保持第一個項目儘量簡單,咱們將繼續使用簡單的文本。

打開 appscript.json。這個文件包含你的 apps 腳本設置。更新文件,以下所示:

appscript.json

{
  "timeZone":  "America/New_York",
  "dependencies":  {
},
  "webapp":  {
  "access":  "MYSELF",
  "executeAs":  "USER_DEPLOYING"
},
  "exceptionLogging":  "STACKDRIVER"
}
複製代碼

保存文件。
轉到終端且輸入下面的命令將這個文件推送回 Google 服務器:

clasp push
複製代碼

而後輸入下面的命令在瀏覽器中打開項目

clasp open  --webapp
複製代碼

該命令會打開瀏覽器,展現剛剛建立的 web 應用。

建立包 —— 使用 WebPack 和 Babel

接下來咱們在 Apps 腳本中使用 ES6。咱們將使用 babel 對 ES6 進行編譯並使用 webpack 並對生成的代碼進行分塊打包。

我這有一個簡單的 Apps 腳本項目:

github.com/gsmart-in/A…

讓咱們來看看這個項目的結構。

「server」 子文件夾包含代碼。api.js 文件包含暴露給 Apps 腳本的函數。

lib.js 文件裏咱們會看到 es6 代碼。在 lib 模塊,咱們能夠引入其餘 es6 文件和 npm 包。

咱們使用 webpack 來對代碼進行分塊打包,並使用 babel 來編譯。

如今咱們看看 webpack.gas.js 文件:

這是 webpack 配置文件。總之,這個配置文件告訴 webpack 的是

  • 使用 babel 將 server/lib.js 文件編譯爲向後兼容的 Javascript 代碼。而後把打包後的文件放在 「dist」 目錄下
  • 複製 api.js 文件且不更改輸入文件夾 「dist」
  • 複製一些配置文件(appsscript.js 和 .clasp.json 文件到輸出文件夾 ‘dist’ 目錄下)

重點注意這幾行代碼:

webpack.gas.js

module.exports  =  {
  mode:  'development',
  entry:{
    lib:'./server/lib.js'
  },
  output:{
     filename:  '\[name\].bundle.js',
     path:  path.resolve(__dirname,  'dist'),
     libraryTarget:  'var',
     library:  'AppLib'
  }
}
複製代碼

這意味着 webpack 將暴露一個全局變量 AppLib,經過該變量能夠訪問打包後文件能夠導出的類和函數。

如今來看 api.js 文件。

api.js

function doGet(){
  var  output  =  AppLib.getObjectValues();
  return  ContentService.createTextOutput(output);
}
複製代碼

server/lib.js 文件

lib.js

function getObjectValues(){
  let options  =  Object.assign({},  {source_url:null,  header_row:1},  {content:"Hello, World"});
  return(JSON.stringify(options));
}

export  {
  getObjectValues
};
複製代碼

咱們正在使用 Apps 腳本不支持的 Object.assign() 方法。當使用 babel 編譯成 lib.js 文件時,它將生成 Apps 腳本支持的兼容代碼。

如今讓咱們看看 package.json 文件

package.json

{
  "name": "AppsPackExample1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "gas": "webpack --config webpack.gas.js ",
    "deploy": "npm run gas && cd dist && clasp push && clasp open --webapp"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.4.0",
    "@babel/preset-env": "^7.4.2",
    "babel-loader": "^8.0.5",
    "copy-webpack-plugin": "^5.0.1",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0"
  },
  "dependencies": {
    "@babel/polyfill": "^7.4.0"
  }
}
複製代碼

當你運行以下命令時:

$>  npm run gas
複製代碼

Webpack 將 lib.js 代碼(以及你導入的其它模塊)編譯並打包到單個 JavaScript 文件中,並將文件放在 「dist」 文件夾中。

而後咱們可使用 「clasp」 上傳代碼。

參考 package.json 文件中的腳本 「deploy」。

它運行 webpack,而後執行 「clasp push」 和 「clasp open」 命令。

部署 「AppsCurryStep1」

若是上面步驟未完成,請在本地克隆示例項目代碼庫。

git clone  git@github.com:gsmart-in/AppsCurryStep1.git
複製代碼

打開終端並轉到 AppsCurryStep1 目錄下。

執行下面的命令:

clasp create  --type standalone  --title  "Apps Script with Webpack and babel"
複製代碼

這將在你的帳戶中建立一個獨立的腳本項目。

如今執行:

npm run deploy
複製代碼

這將在你的瀏覽器中打開你的 web app。

將 npm 模塊與你的 Apps 腳本項目集成

Apps 腳本的一個限制特性是沒有簡單的方法能夠將 npm 之類的包集成到你的項目中。

例如,你可能想在項目中使用 momentjs 來處理日期,或者 lodash 工具集方法。

實際上,Apps 腳本是有庫功能的,可是它有幾個限制。咱們不會在這篇文章中探索這個庫的功能;咱們將安裝 npm 模塊並使用 webpack 打包這些模塊來建立與 Apps 腳本兼容的包。

由於咱們已經開始使用 webpack 來建立能夠集成到 apps 腳本的包,因此咱們如今添加一些 npm 包應該更容易。讓咱們開始使用 moment.js 吧!

打開終端,轉到你上一步建立的 AppsCurryStep1 目錄下,添加 momentjs。

npm install moment  --save
複製代碼

如今讓咱們在 Apps 腳本項目中使用一些 momentjs 的功能。

在 lib.js 文件中添加一個新的函數。

server/lib.js

import * as moment from "moment";

function getObjectValues() {
  let options = Object.assign(
    {},
    { source_url: null, header_row: 1 },
    { content: "Hello, World" }
  );

  return JSON.stringify(options);
}

function getTodaysDateLongForm() {
  return moment().format("LLLL");
}

export { getObjectValues, getTodaysDateLongForm };
複製代碼

提示: 不要忘記導出新函數。

如今讓咱們在 api.js 文件中使用這個新函數吧。

server/api.js

function doGet() {
  var output = "Today is " + AppLib.getTodaysDateLongForm() + "\\n\\n";

  return ContentService.createTextOutput(output);
}
複製代碼

轉到終端並輸入:

npm run deploy
複製代碼

這個更新了的腳本會打開瀏覽器,並打印今天的日期。

打印今天的日期並無多少樂趣。讓咱們添加另外一個有更多功能的函數。

server/lib.js

function getDaysToAnotherDate(y,m,d){
  return  moment().to(\[y,m,d\]);
}
複製代碼

如今在 api.js 文件中更新 doGet() 並調用 getDaysToAnotherDate()。

server/api.js

function doGet(){
  var  output  =  'Today is '+AppLib.getTodaysDateLongForm()+"\\n\\n";
  output  +=  "My launch date is "+AppLib.getDaysToAnotherDate(2020,3,1)+"\\n\\n";
  return  ContentService.createTextOutput(output);
}
複製代碼

下面,讓咱們添加 lodash。

首先,執行下面的命令:

npm install lodash  --save
複製代碼

而後咱們使用 lodash 添加一個隨機數生成器。

server/lib.js

function printSomeNumbers(){
  let out  =  _.times(6,  ()=>{
    return  _.padStart(_.random(1,100).toString(),  10,  '.')+"\\n\\n";
  });
  return  out;
}
複製代碼

讓咱們在 api.js 中調用該函數:

server/api.js

function doGet(){
  var  output  =  'Today is '+AppLib.getTodaysDateLongForm()+"\\n\\n";
  output  +=  "My launch date is "+AppLib.getDaysToAnotherDate(2020,3,1)+"\\n\\n";
  output  +=  "\\n\\n";
  output  +=  "Random Numbers using lodash\\n\\n";
  output  +=  AppLib.printSomeNumbers();
  return  ContentService.createTextOutput(output);
}
複製代碼

再次部署這個項目:

npm run deploy
複製代碼

你應該能夠在線上看到你的 web 應用頁面的隨機數字。

第 2 部分的源代碼(與 npm 模塊集成)可在此處得到: github.com/gsmart-in/A…

下一步

既然添加 npm 包到你的 Apps 腳本項目中如此容易,那咱們能夠開始建立一些 npm 包了。

封裝 Google APIs、Gmail、Google 表格、Google Docs和其它公共的 API 的包,將會帶來不少的樂趣!

另外一個重要的部分還沒說到。目前咱們看到 web 應用只是一個簡單的文本界面。試試使用現代化 CSS 框架,bootstrap、bulma、material design 以及 VueJS 和 React,並用 Apps 腳本建立一些單頁面 Web 應用?對,咱們會這樣作的。咱們會在客戶端使用 bootstrap 和 Vuejs,在服務端使用 Apps 腳本,並構建一個單頁應用。

多麼使人興奮啊!請繼續關注本系列的文章。

更新

在第二部分,咱們將使用 bootstrap 和 VueJS 構建咱們的 web 應用的客戶端。點擊此處閱讀所有:
在 Google Apps 腳本中(使用 Vue 和 Bootstrap)構建單頁應用

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索