<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: prasanthmj</title>
    <description>The latest articles on DEV Community by prasanthmj (@prasanthmj).</description>
    <link>https://dev.to/prasanthmj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F151521%2Ff5218f16-d8de-4e22-96da-b0352af1b263.jpg</url>
      <title>DEV Community: prasanthmj</title>
      <link>https://dev.to/prasanthmj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prasanthmj"/>
    <language>en</language>
    <item>
      <title>Creating a complete web app on Google Apps Script using Google Sheet as database</title>
      <dc:creator>prasanthmj</dc:creator>
      <pubDate>Tue, 23 Apr 2019 11:19:23 +0000</pubDate>
      <link>https://dev.to/prasanthmj/creating-a-complete-web-app-on-google-apps-script-using-google-sheet-as-database-26o8</link>
      <guid>https://dev.to/prasanthmj/creating-a-complete-web-app-on-google-apps-script-using-google-sheet-as-database-26o8</guid>
      <description>&lt;p&gt;Google’s Apps Script should be of interest to all JavaScript developers.&lt;br&gt;
Apps Script is good for automation. You can directly access Google’s many services, such as Google Sheets, Gmail, Google Docs, Google Calendar, and more. See some &lt;a href="https://developers.google.com/apps-script/articles/tutorials" rel="noopener noreferrer"&gt;Google Apps Script starter tutorials here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With a little bit of imagination, you can create very exciting Apps and add-ons using Google Apps Script.&lt;/p&gt;

&lt;p&gt;The first limitation of Apps Script is that it uses an older version of Javascript. It does not support ES6 and its features. Not a big problem. We can use babel and cross compile to a compatible version. The next limitation is that there is no packaging/module setup. You can't directly use npm modules in the Apps Script environment. &lt;/p&gt;

&lt;p&gt;Thankfully, there is a command line tool called &lt;a href="https://github.com/google/clasp" rel="noopener noreferrer"&gt;clasp&lt;/a&gt; . The clasp tool makes it easy to upload your Apps Script code. &lt;/p&gt;

&lt;p&gt;So in the first part of this project, let us attempt to make use of ES6 and npm modules in Apps Script. We will use Webpack+babel to create a bundle from our source. Then we will upload the bundle using the clasp tool.&lt;/p&gt;

&lt;p&gt;See the code for this first part here:&lt;br&gt;
&lt;a href="https://github.com/gsmart-in/AppsCurryStep2" rel="noopener noreferrer"&gt;https://github.com/gsmart-in/AppsCurryStep2&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Webpack to create the bundle
&lt;/h2&gt;

&lt;p&gt;The most interesting part would be the webpack configuration here:&lt;br&gt;
&lt;a href="https://github.com/gsmart-in/AppsCurryStep2/blob/master/webpack.gas.js" rel="noopener noreferrer"&gt;https://github.com/gsmart-in/AppsCurryStep2/blob/master/webpack.gas.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the server folder, you can see two files: api.js and lib.js&lt;/p&gt;

&lt;p&gt;api.js is the one that is directly exposed to Apps Script. This file can contain Apps Script compatible code only and is directly uploaded. This file will contain global functions only because that is what Apps Script will understand.&lt;/p&gt;

&lt;p&gt;lib.js is our bundle entry point. We can use ES6 and npm modules in lib.js and any of its dependencies. In summary the call structure will be:&lt;/p&gt;

&lt;p&gt;api.js -&amp;gt; lib.js -&amp;gt; your custom modules.&lt;/p&gt;

&lt;p&gt;Coming back to our &lt;a href="https://github.com/gsmart-in/AppsCurryStep2/blob/master/webpack.gas.js" rel="noopener noreferrer"&gt;webpack configuration&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name].bundle.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;libraryTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;var&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;library&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AppLib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The library target is set to 'var' and library name 'AppLib' so the exported identies in the library(lib.js) can be accessed like this in api.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Today is &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;AppLib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTodaysDateLongForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ContentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTextOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the modules section of webpack configuration , we have the rules for babel cross compilation.&lt;/p&gt;

&lt;p&gt;Also, we use the Copy plugin to simply copy the api.js file to the output folder (from the output folder we upload the generated code to Apps Script using the clasp tool)&lt;/p&gt;

&lt;h2&gt;
  
  
  Using npm modules
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://github.com/gsmart-in/AppsCurryStep2/blob/master/server/lib.js" rel="noopener noreferrer"&gt;lib.js&lt;/a&gt; we can use ES6 or any advanced features you want. It can include other modules as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getTodaysDateLongForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LLLL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to try this app, &lt;a href="https://github.com/gsmart-in/AppsCurryStep2" rel="noopener noreferrer"&gt;clone the project&lt;/a&gt; and follow the instructions in the readme page.&lt;/p&gt;

&lt;p&gt;Read the detailed article here: &lt;a href="http://blog.gsmart.in/es6-and-npm-modules-in-google-apps-script/" rel="noopener noreferrer"&gt;Using ES6 and npm modules in Google Apps Script&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Rich UI for the Apps Script project
&lt;/h2&gt;

&lt;p&gt;Let us build a “Request Management” App. The app will be a Single Page App. You will be able to create new requests (for Laptops, phones, etc) and an admin can view, approve or reject those requests. In the back-end, the app will add the requests to a Google Sheet. So Google Sheet acts as a database.&lt;/p&gt;

&lt;p&gt;Here is the complete project:&lt;br&gt;
&lt;a href="https://github.com/gsmart-in/AppsCurryApp" rel="noopener noreferrer"&gt;https://github.com/gsmart-in/AppsCurryApp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See a quick demo of the app here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=g27PUdZkoYU" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F81wvnyvo5faw9ey4ja9p.jpg" alt="Single Page Apps in Google Apps Script"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is divided into two sections: “client” and “server”. The client folder contains the Vuejs, SCSS and the index.html template We combine all these together to create the bundle that is the index.html file that gets uploaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F973yrx4a1f62i46dq7qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F973yrx4a1f62i46dq7qr.png" alt="Folder Structure of Apps Curry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server folder contains the code that runs in Apps Script. The code in ES6 gets compiled to Apps Script compatible code and gets uploaded.&lt;/p&gt;

&lt;p&gt;The server folder also contains unit tests for the server side code&lt;/p&gt;
&lt;h3&gt;
  
  
  You have to bundle and inline all of CSS and Javascript to a single HTML file!
&lt;/h3&gt;

&lt;p&gt;One limitation of Google Apps Script is that it has only one function to show your page. There is no quick way to link your javascript/css files just like you would do in a normal website. So you have to bundle all JS/CSS and inline it.&lt;/p&gt;

&lt;p&gt;So we use HtmlWebpackInlineSourcePlugin webpack plugin to inline the generated CSS and JS in to index.html&lt;/p&gt;

&lt;p&gt;Here is the webpack configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;merge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webpack-merge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;common&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./webpack.common.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webpack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HtmlWebpackPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html-webpack-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HtmlWebpackInlineSourcePlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html-webpack-inline-source-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;common&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[name].bundle.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../deploy/gas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
     &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ProvidePlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jquery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;jQuery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jquery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;window.jQuery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jquery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
     &lt;span class="p"&gt;}),&lt;/span&gt;
     &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HtmlWebpackPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client/src/index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;inlineSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.(js|css)$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
     &lt;span class="p"&gt;}),&lt;/span&gt;
     &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HtmlWebpackInlineSourcePlugin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The purpose of this project was to see how far we can extend the limitations of Apps Script to make it a platform for building complete web apps. Although you can’t build production grade or even limited user base apps on this platform yet, this throws some light on the potentials of such a platform. Imagine being able to create apps, push it and never need to worry about the scaling issues. Imagine a platform that comes ready with user access management built-in. Maybe, one day, this example will help create such a better, scalable universal app platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Demo of the App
&lt;/h2&gt;

&lt;p&gt;See the complete demo of the app(cloning the project and creating an instance )&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Vt6O4pf98VU" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3yhltmdvv3jtjhus0kc.jpg" alt="Apps Curry Demo - cloning and creating an instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Read More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blog.gsmart.in/es6-and-npm-modules-in-google-apps-script/" rel="noopener noreferrer"&gt;Using ES6 and npm modules in Google Apps Script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.gsmart.in/single-page-apps-vue-bootstrap-on-google-apps-script/" rel="noopener noreferrer"&gt;Building Single Page Apps (with Vue and Bootstrap) on Google Apps Script&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>googleappsscript</category>
      <category>javascript</category>
      <category>googlesheets</category>
      <category>vue</category>
    </item>
  </channel>
</rss>
