リライト：（再現度高め・無料）初学者のためのWEBアプリ公開マニュアル

<h1>Herokuが有料化のためリライト！</h1>

[類似サービス](https://qiita.com/herixon/items/6e42f874189bf44bce4c)<br>
こちらを使用してください。<br>
初学者の方でしたら、デプロイが遅く不安になりますがrenderがいいかと思います。<br><br>
<h1>下記原文</h1>

初学者ながらjavascriptでアプリを作成して誰かに見せたいが、
・公開をする方法がわからない・・・
・ものすごく公開するまでが大変な気がする・・・
というのが悩みでした。

しかし、簡単なNode.js（express)の記述と、GitHUbへのpushさえできてしまえば、Herokuでそこそこ簡単に公開できることを学びました。
スマホにも対応してくれます。

実際の公開方法を細かく説明いたします。



■注意：
・筆者自身、GitHubをよく理解しておらず、Herokuもよく理解していないため、GitHUbにpushすると、Herokuで公開できるという認識しかございません。
・コードを簡潔に理解するため、非同期処理を用いません。
・個人情報を含むアプリはpushしないでください。
・GitHUbへのpushに相当てこずりました・・・正しい方法でない可能性があります。

■実行環境
・windows10 pro
・vscode
・node.js(16.17.0 LTS)---要インストール
・git bush---要インストール
(ターミナルはgit bushを使ってください）

■使用ライブラリ・フレームワーク
・nodemon(データ変更時自動で実行してくれる便利機能）
・express（Webアプリケーションフレームワーク）

■事前に必要なアカウント
・GitHub
・Heroku(PaaS)レンタルサーバー的な奴。基本無料。

■フォルダ構成
![フォルダ構成.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650652/5eb088ef-3921-849d-bb46-35885b99cf6a.jpeg)
■publicの中身
![publicの中身.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650652/74463a42-5ca3-68de-f4b4-f5f7f7b0cb59.jpeg)



■実作業
①空フォルダを作り、アプリ名をつける。
（ここではデスクトップ直下に作る）

②vs code で①のフォルダを開く。

③ターミナルを開き、以下を入力すると、jsonが生成される。
````
npm init
````
下記のように、設定を聞かれるが、entry point: (index.js)をapp.jsに変える以外は、enterでOK

````
package name: (marubatu-lite-hel)
version: (1.0.0)                                                                        
description:                                                                            
entry point: (index.js) app.js                                                          
test command:                                                                           
git repository:                                                                         
keywords:                                                                               
author:                                                                                 
license: (ISC)                                                                          
About to write to C:\Users\singo\Desktop\marubatu-lite-hel\package.json:

{
  "name": "marubatu-lite-hel",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
````

jsonが生成される。
中を見てみる。

````
{
  "name": "marubatu-lite-hel",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
````
④直下にapp.jsを作成する。（node.jsを操作するmainとなります）

⑤ターミナルに下記を入力し、nodemonとexpressをインストール
````
npm i express
npm i nodemon
````
jsonを確認し、
````
    "express": "^4.18.1",
    "nodemon": "^2.0.19"
````
が入っていることを確認。

⑥jsonの修正
````
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
````
を下記のように書き換える。
````
  "scripts": {
    "dev": "nodemon app.js",
    "start": "node app.js"
  },
````
・"dev": "nodemon app.js"はnodemonの実行環境を作る。
・ "start": "node app.js"はHerokuで公開するためのおまじない

⑦app.jsのテスト。app.jsに下記を記述し保存。
````
console.log("nodemon hello!");
````
⑧ターミナルで下記を入力し、nodemonが動くか試す。
````
npm run dev
````
結果
````
[nodemon] 2.0.19
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
nodemon hello!
[nodemon] clean exit - waiting for changes before restart
````
と出力される
試しにコードを
````
console.log("nodemon hello2!");
````
に変更し保存すると、
````
nodemon hello2!
````
と出力される。

⑧直下にpublicフォルダを作り、中に
・index.html
・script.js
・style.css
を作る（既存の制作物は名前を変えてpublicフォルダの直下に置く）
※htmlのlinkとsrcは下記のように設定してください。

ここでは〇×ゲームを作りますので、ネタがない方はコピペして使ってください。

 ````
<link rel="stylesheet" href="style.css">
 <script src="script.js"></script>
````


````index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
   
        <title>まるばつゲーム</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <h1>まるばつゲーム</h1>
        <p id="inputWhich">　</p>
        <br>
        <div id="field">
    
        </div>
        <script src="script.js"></script>
    </body>
    </html>
````
````script.js
const toInnerText = (x,y) => {
    let cellId = "cell"+x+y;
    let cell = document.getElementById(cellId);
    let innerText = cell.innerText;
    return innerText;
}
const gameEnd = () => {
    let check = new Array;
    let checkCell;
    for(let i=0;i<=2;i++){
        for(let j=0;j<=2;j++){
            check.push(toInnerText(i,j));
        }
        if(check[0]==check[1] && check[1]==check[2] && check[0] != ""){
            alert(check[0] + " の勝ち");
        }
        console.log(check);
        check = [];
    }
    for(j=0;j<=2;j++){
        for(i=0;i<=2;i++){
            check.push(toInnerText(i,j));
        }
        if(check[0]==check[1] && check[1]==check[2] && check[0] != ""){
            alert(check[0] + " の勝ち");
        }
        check = [];
    }
    if(toInnerText(0,0)==toInnerText(1,1)&&toInnerText(1,1)==toInnerText(2,2)&&toInnerText(0,0)!=""){
        alert(toInnerText(0,0) + "の勝ち");
    }
    if(toInnerText(0,2)==toInnerText(1,1)&&toInnerText(1,1)==toInnerText(2,0)&&toInnerText(0,2)!=""){
        alert(toInnerText(0,2) + "の勝ち");
    }
}
let tx = "〇";
    
document.getElementById("inputWhich").innerText = tx + " の番";
const inputMark=(e)=>{
    if(e.target.innerText==""){
        e.target.innerText = tx;
        if(tx=="〇"){
            tx = "✕";
        }else if(tx=="✕"){
            tx = "〇";
        }
        gameEnd();
    }else{
        alert("そのマスは既に埋まっています。");
    }
    document.getElementById("inputWhich").innerText = tx + " の番";
}
let i, j;
let tbl = document.createElement("table");
tbl.border="1";
tbl.className="gameTable";
for(i=0;i<=2;i++){
    let tr = document.createElement("tr");
    for(j=0;j<=2;j++){
        let td = document.createElement("td");
        td.id="cell"+i+j;
        td.onclick=inputMark;
        tr.appendChild(td);
    }
    tbl.appendChild(tr);
}
document.getElementById("field").appendChild(tbl);
````

````style.css
table {
    border: 1px solid black;
}
td {
    border: solid 1px black;
    width: 50px;
    height: 50px;
    text-align: center;
}
td:hover {
    background-color: antiquewhite;
}
````

⑨app.jsの編集
簡単なサーバ設定を行います。

詳細な説明は避けますが、下記のコードをコピペしていただくと、
http://localhost:3000/
にてアプリが反映されるはずです。

````app.js
const express = require("express");
const app  = express();
app.use(express.static("./public"));
const PORT = 3000;

// ルーティングの設定
app.get("/", (req, res)=>{
      res.sendFile("index.html");
      console.log("/ へアクセスがありました");
});

// HTTPサーバを起動する
app.listen(process.env.PORT || PORT, console.log(`listening at http://localhost:${PORT}`));
````
⑨非公開ファイルの設定
````
.gitignore
````
というファイルを作り、中身に
````
node_modules
````
と記述します。
node_modulesは情報量が多く、GItHubに必要ないのでPushしたくないです。そのため、gitignoreの設定を行うことで、Gitにpushされなくなります。

～～～～ここまででローカルの設定は終わりです～～～～～

以降、GitHUbとの戦いになります。
アカウント登録は済ませている状態で話を進めます。
日本語での説明とするため、毎回、日本語変換をしてください。
※ターミナルはgit bash を使用してください。

■GitHUb編
①ログインします。

②日本語化します。

③右上の自分のアイコンをクリックし、「あなたのリポジトリ」をクリックします。

④新しいをクリックします。

⑤リポジトリ名をつけます。今回は「marubatu-game-her」とします。フォルダ名とは違う名前を付けても問題ありません。

⑥「公衆」を選びます。（基本設定は公衆です）

⑦「リポジトリを作成」をクリック

⑧push用のコマンドを取得（ここのみ英語）
一番上の、
…or create a new repository on the command line
と書いてある、下記コードをコピーします。
````
echo "# marubatu-game-her" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/herixon/marubatu-game-her.git
git push -u origin main
````
すべてコピペして、一度に実行しても動くのですが、失敗することが多いため、一行づつ実行することを推奨します。

⑨VS　codeをctrl+Cでサーバを止めます

⑩以下3行の実行
以下３行は同時に実行してもエラーになることは少ないです。
````
echo "# marubatu-game-her" >> README.md
git init
git add README.md
````
⑪pushするデータを追加
※公式の手順ではないのですが、色々調べたところこのタイミングで以下のコマンドを実行するとうまくいくことが多いです。
※git addしないと、readmeファイルだけ、pushされてしまうのです。

````
git add .
````

⑫git commit
````
git commit -m "first commit"
````

git commitをすると、初回は
````
$ git commit -m "first commit"
Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'singo@MSI.(none)')  
````
とmail、name設定を聞かれますので、

````
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
````
をコピペして、メアドと名前の中身を変更しgit configを実行しましょう。

⑬最後の３行も同時に実行してもうまくいくことが多いです。
````
git branch -M main
git remote add origin https://github.com/herixon/marubatu-game-her.git
git push -u origin main
````
git pushでエンターを押せば、pushは終わりです。
といいつつ、かなりの確率でエラーが出ます。
エラーが出ずに、GihHubのページをリロードし、フォルダ一覧のページに置き換わったら成功です。

下記リンク参照
https://github.com/herixon/marubatu-game-her

※※※※※※※※
Pushに失敗したら、色々調べてみるのも大事ですが、
フォルダ内のgitというファイルを削除し、⑩～⑬を繰り返すとうまくいくことが多いです。理由や詳細を説明できず申し訳ない・・・・
誰かちゃんとしたPushの方法を教えて・・・・

個人的にGit へのpushが一番てこずりました。
初学者の壁かと思います。
※※※※※※※※

～～～～～～Herokuとの戦い編～～～～～～～～

ここからHerokuの設定が始まります。
そこまで難しくなく、事前処理を済ませてあるため、エラーは起きにくいと思います。
よくわからない場合、毎回日本語に翻訳してください。

①Herokuにログイン

②右上の「New」ボタンをクリックし「create new app」を選択。

③appnameを決める。
※URLにもなるため、重複する名前は使えません。
※GitHubの名前と一緒にしなくてもいいです。
今回は「marubatugame-easy」としました。

④choose a regionはUSを選ぶ

⑤create app をクリック

⑥導入方法にGitHubを選ぶ

⑦repo-nameをGitHubからGitHubに登録したレポジトリ名を検索
今回は「marubatu-game-her」

⑧下に候補が出てきて、間違いがなければconnectボタンを押す。

⑨Automatic deploysの設定
mainになっていることを確認し、「Enable Automatic deploys」をクリックする。
この設定をすることで、GitHubの情報が変わったら、自動で変更してくれるようになります。

⑩Deploy Branchをクリック

⑪１分ほど待つとViewボタンが出てくるのでクリック

＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃
デプロイ成功！のはず！
＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃

URLをコピペして人に見せびらかそう！
（ここで作ったゲーム）
https://marubatugame-easy.herokuapp.com/

ここまで長文を読んでいただきありがとうございました！