nuxtで書いたコードをGASで使えるよう変換


概要

  • nuxtで作成したファイル(vueコンポーネント形式)をGASで利用できる形(x-template形式)に変換する
  • これ自体がnuxtで動くプログラム。個人で使うなら自分のPCでローカルホストを立ち上げ、変換されたコードをコピペして使えば良い。

開発背景

  • GASでフロントサイドを書くにあたって、GASのエディタはお世辞にも使いやすいとは言えません(最近のアップデートでだいぶ使いやすくはなりましたが)
  • 多分GAS開発者の多くがしているように、claspで作成してGASにプッシュする方法がありますが、claspプッシュしてWebページをリロードして、、、というのは地味に面倒ですし、エラーが見つけにくいという欠点もあります。
  • そこで、私はnuxtでUIをある程度作ってから、GASのhtmlファイルにコピーする方法をとっています。
  • nuxtで作ったファイルをそのままコピーできれば良いのですが、nuxtはコンポーネントを.vue形式で作成するのに対して、GASでは.html形式にする必要があること、コンポーネントの書き方はnuxtは〜とexhast defaultに対してGASではx-templateを使った書き方であるなど、いくつかの修正する必要があります。
  • もともとはこれらの作業を手でやっていましたが、コンポーネントファイルが多くなってくると面倒なので、プログラム化しました。

設計

ユーザー操作

  • ブラウザでnuxtアプリのフォルダをアップすると、html形式にしてダウンロードできるようにします。
  • テキストの編集は全てjavascriptで実装しました。

nuxtとGASの違い

  • ファイル形式について、nuxtではコンポーネントファイルが.vue形式、一方でGASでは.html形式
  • コンポーネントの書き方について、nuxtではHTMLに相当する部分をで括りjavascriptをexport defaultで読み取れるようにしている。一方でGASのhtmlファイルでは、HTMLの部分を<script type="text/x-template">で括り、ローカルコンポーネントを変数に入れて親コンポーネントで読み取れるようにしている

nuxt → GASへの変換

componentsのファイル

  1. ファイル名をsomething.vueからsomething.htmlに
  2. <template>の部分を<script type="text/x-template" id="something">
  3. export default"を"const something =" に
  4. template = "#something", を追加

pagesのファイル

1〜4まではcomponentsと同じ

  1. import ChildComponent from "~/components/ChildComponent.vue"を削除

layoutsのファイル

  • 私の開発ではSPAで作成しており、layouts/index.htmlは以下のような構造
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
      <?!= include("config") ?>
  </head>
  <body>
  <?!= include("components/EditComponent") ?>
  <?!= include("components/ImportMailList") ?>
  <?!= include("components/MailListHead") ?>
  <?!= include("components/MailPreview") ?>
  <?!= include("components/VarConfig") ?>

  <?!= include("pages/mailer") ?>

  <div id="app"></div>

  <script>
    new Vue({
      vuetify: vuetify,
      render: h => h(mailer)
    }).$mount("#app")
  </script>

  </body>
</html>

工夫点

フォルダのアップロードとファイルの処理

  • フォルダのアップロードにはinputタグにwebkitdirectry属性を追加する
  • webkitdirectoryでフォルダをアップした後で、各ファイルを処理する方法は以下参照
<template>
  <input type="file" @change="upload($event)" webkitdirectory>
</template>

<script>
(vue methods)
async upload(event){
      //ファイル一覧の取得と各ファイルの処理
      const files = event.target.files
      for(const file of files){
        //ファイルパスの取得
        const path = file.webkitRelativePath;

                //ファイルの読み取り等はPromiseを用いて同期処理すること
                const text = await this.editFile(file)
      }
},
editFile(file){
  return new Promise((resolve,reject)=>{
    const reader = new FileReader()
    reader.readFileAsText()
    reader.onload = function(e){
      const text = e.target.result
      resolve(text)
    }
  })
}

</script>

nuxtのファイル一覧から必要なファイルの絞り込み

  • nuxtのフォルダをアップすると、2万強のファイルがアップされる。
  • そのうち、必要なvueファイルを絞り込むには以下のようにする
const path = file.webkitRelativePath;
//不要なファイルをフィルタリング
if(!path.includes(".vue"))continue;
if(path.includes(".nuxt"))continue;
if(path.includes("node_modules"))continue;