「ローカルでは動くのにGitHub Pagesで動かない!」の解決法

はじめに

作成したWebアプリをGitHub Pagesに公開したら、突然動かなくなってパニックになった経験を共有します。同じ問題で困っている方の助けになれば嬉しいです!

問題発生:完璧だったはずが...

自分のパソコンでは完璧に動いていたおこづかい管理アプリ。ボタンもクリックできるし、機能も全部OK。「よし、GitHub Pagesで公開だ!」と意気込んでアップロードしたところ...

Uncaught ReferenceError: switchMode is not defined

え?switchModeって何?そんな関数作ってないよ?

いや、待って。確実に作ってる。ローカルでは動いてるもん。

犯人は「読み込み速度の差」だった

調べてみると、原因は意外なところにありました。

ローカル環境の場合

  • ファイルが手元にある → 瞬時に読み込み完了
  • HTMLもJavaScriptも同じタイミングで準備完了

GitHub Pagesの場合

  • ファイルをネットから取得 → 時間がかかる
  • HTMLの途中でJavaScriptが動き始める
  • 「ボタンどこ?」状態で関数が見つからない

つまり、ローカルでは偶然うまくいってただけだったんです。

解決法:たった6文字追加するだけ

解決方法は拍子抜けするほど簡単でした。

変更前

<script src="script.js"></script>

変更後

<script src="script.js" defer></script>

たったこれだけ!

defer属性を追加すると「HTML全部読み込んでからJavaScript動かして」という指示になります。

なぜdeferで解決するのか?

お弁当作りで例えると:

問題があった時

  1. 「料理開始!」(JavaScript実行)
  2. 「あれ?材料がない...」(ボタンがまだ作られてない)
  3. 失敗😭

defer後

  1. 「材料全部揃ったよ」(HTML読み込み完了)
  2. 「よし、料理開始!」(JavaScript実行)
  3. 成功😊

学んだこと

  • ローカルで動く ≠ 本番で動く
  • 基礎知識って本当に大事
  • エラーメッセージは敵じゃない、味方

まとめ

同じ問題で困っている方、とりあえずdeferを試してみてください。90%の確率で解決すると思います!

こういう小さなつまずきがたくさんあるけど、一つずつクリアしていくのが楽しいですね。


この記事が役に立ったら、同じ問題で困っている人にシェアしてもらえると嬉しいです!

MacでCSVファイルを編集しようとしたら勝手にNumbersで開いちゃう?テキストエディットで編集する方法

💭 はじめに

先日、MacCSVファイルを編集しようとしたときに、なぜか自動的に「Numbers」で開かれてしまうということがありました。

「えっ、ただカンマ区切りのテキストをちょっといじりたいだけなのに…」と少し困ってしまったので、同じ悩みを持っている方に向けて解決方法をまとめてみました!

😖 悩んだこと:勝手にNumbersで開いてしまう

CSVファイルをダブルクリックすると、表計算アプリ「Numbers」で開いてしまいます。表として見るには便利だけど、 • 素早く中身を確認したい • カンマ区切りのまま編集したい • 余計な書式設定なしで作業したい

そんなときにはかえって不便なんですよね。

✅ 解決方法:テキストエディットで開く!

ステップ①:右クリックから「このアプリケーションで開く」 1. FinderでCSVファイルを探す(例:data.csv) 2. 右クリック(または Control + クリック) 3. 「このアプリケーションで開く」→「テキストエディット」を選ぶ

これだけで、Numbersではなくテキストエディットで開けます!

🔁 おまけ:毎回テキストエディットで開くようにする設定 1. FinderでCSVファイルを右クリック 2. 「情報を見る(⌘+I)」をクリック 3. 「このアプリケーションで開く」→「テキストエディット」を選択 4. 「すべてを変更…」をクリックして、今後もテキストエディットで開くように設定!

✍ おわりに

Macでは便利なアプリが自動で開く反面、「ちょっとだけ編集したい」「素のデータを見たい」ときに余計なお世話になることもあります。

今回紹介したように、右クリックで開くアプリを選ぶだけで、シンプルにCSVを扱えるようになります! 同じことでモヤモヤしていた方の参考になればうれしいです😊

4/3機能をメニュー化して自由に選択できるようにしてみた

・学習時間:1時間

・やったこと

①機能をメニュー化して実行したいものだけを選択できるようにした

・使った技術・文法

①case文: 比較したいオブジェクトが1つの時はcase文を使えば短く記述できる

・書いたコード

require "csv"

# ===登録===
def register_tasks(tasks)
  puts "タスクを入力してください。\n終了したいときは「end」を入力してください。"

  loop do
    input = gets.chomp
    if input == "end"
      break
    end
    tasks.push(input)
  end
end

# ===一覧表示===
def show_tasks(tasks)
  puts "タスク一覧"
  tasks.each_with_index do |task, i|
    puts "#{i + 1}: #{task}"
  end
end

# ===削除===
def delete_tasks(tasks)
  if tasks.empty?
    puts "削除するタスクはありません"
  else
    puts "削除したいタスクの番号を選択してください。\n0を入力すると削除を終了します。"
    loop do
      input = gets.to_i
      if input < 0 || input > tasks.length
        puts "無効な番号です。"
      elsif input == 0
        break
      else
        tasks.delete_at(input - 1)
        show_tasks(tasks)
      end
    end
  end
end

# ===CSVファイルの読み込み===
def load_tasks_from_csv(tasks, file_path)
  if File.exist?(file_path)
    CSV.foreach(file_path) do |row|
      tasks << row[0]
    end
    show_tasks(tasks)
  end
end

# ===CSVファイルに保存===
def save_tasks_to_csv(tasks, file_path)
  CSV.open(file_path, "w") do |csv|
    tasks.each do |task|
      csv << [task]
    end
  end
end


tasks = []
file_path = "tasks.csv"
load_tasks_from_csv(tasks, file_path)

loop do
  puts "===メニュー==="
  puts "1. タスクを登録"
  puts "2. タスクを一覧表示"
  puts "3. タスクを削除"
  puts "0. アプリを終了"
  puts "番号を選択してください"

  input = gets.to_i

  case input
  when 1
    register_tasks(tasks)
  when 2
    show_tasks(tasks)
  when 3
    delete_tasks(tasks)
  when 0
    puts "アプリを終了します。"
    break
  else
    puts "無効な値です。"
  end
end

save_tasks_to_csv(tasks, file_path)

・感想と次のステップ

一方通行の処理から「選択式」に変えることで、操作の自由度が一気に上がった。

次のステップでは、「完了したタスクにチェックをつける」ような機能を実装したい。
そのために、タスクを文字列だけでなく、オブジェクト(クラス)として扱う方法も学びたい。

4/2(水)夜活 ToDoリストCLIアプリ | ステップ④:CSVファイルにタスクを保存復元できる機能を追加

・学習時間:1時間

・ステップ4でやったこと

①複数のタスクを削除できるようにした。

csvファイルに保存・CSVファイルから読み込みができるようにした。

・使った技術・文法

csvライブラリ: 

②openメソッド: 保存

③foreach:読み込み

・書いたコード

require "csv"

tasks = []

# ===CSVファイルを読み込み===
if File.exist?("tasks.csv")
  CSV.foreach("tasks.csv") do |row|
    tasks << row[0]
  end
  tasks.each_with_index do |task, i|
    puts "#{i + 1}: #{task}"
  end
end

# ===タスクの登録===
puts "タスクを入力してください。\n終了したいときは「end」を入力してください。"

loop do
  input = gets.chomp
  if input == "end"
    break
  end
  tasks.push(input)
end

# ===タスクの一覧表示===
tasks.each_with_index do |task, i|
  puts "#{i + 1}: #{task}"
end

# ===タスクの削除===
if tasks.empty?
  puts "削除するタスクはありません"
else
  puts "削除したいタスクの番号を選択してください。\n0を入力すると削除を終了します。"
  loop do
    input = gets.to_i
    if input < 0 || input > tasks.length
      puts "無効な番号です。"
    elsif input == 0
      break
    else
      tasks.delete_at(input - 1)
      tasks.each_with_index do |task, i|
        puts "#{i + 1}: #{task}"
      end
    end
  end
end

# ===CSVファイルに保存===
CSV.open("tasks.csv", "w") do |csv|
  tasks.each do |task|
    csv << [task]
  end
end

・感想と次のステップ CSVライブラリの使い方がなんとなくわかった。 現在は登録 → 一覧表示 (関数化したほうがよさそう?)→ 削除処理が一方通行のため 明日の朝活でメニューを追加して、操作を選べるようにする機能にチャレンジする。

4/3(木)朝活 ToDoリストCLIアプリ | ステップ⑤:メニュー形式にする

・学習時間:1時間

・やったこと

メニュー形式で各機能を呼び出せるようにするため各機能を関数化しました。

・使った技術・文法

①関数

②引数

・書いたコード

require "csv"

# ===登録===
def register_tasks(tasks)
  puts "タスクを入力してください。\n終了したいときは「end」を入力してください。"

  loop do
    input = gets.chomp
    if input == "end"
      break
    end
    tasks.push(input)
  end
end

# ===一覧表示===
def show_tasks(tasks)
  tasks.each_with_index do |task, i|
    puts "#{i + 1}: #{task}"
  end
end

# ===削除===
def delete_tasks(tasks)
  if tasks.empty?
    puts "削除するタスクはありません"
  else
    puts "削除したいタスクの番号を選択してください。\n0を入力すると削除を終了します。"
    loop do
      input = gets.to_i
      if input < 0 || input > tasks.length
        puts "無効な番号です。"
      elsif input == 0
        break
      else
        tasks.delete_at(input - 1)
        show_tasks(tasks)
      end
    end
  end
end

# ===CSVファイルの読み込み===
def load_tasks_from_csv(tasks, file_path)
  if File.exist?(file_path)
    CSV.foreach(file_path) do |row|
      tasks << row[0]
    end
    show_tasks(tasks)
  end
end

# ===CSVファイルに保存===
def save_tasks_to_csv(tasks, file_path)
  CSV.open(file_path, "w") do |csv|
    tasks.each do |task|
      csv << [task]
    end
  end
end


tasks = []
file_path = "tasks.csv"

load_tasks_from_csv(tasks, file_path)

register_tasks(tasks)

show_tasks(tasks)

delete_tasks(tasks)

save_tasks_to_csv(tasks, file_path)

・感想と次のステップ

関数にすることで実行部分がスッキリし、読みやすくなった。 今日の夜活でメニュー形式で操作を選べるメニュー機能にチャレンジします。

4/2(水)夜活 ToDoリストCLIアプリ | ステップ④:CSVファイルにタスクを保存復元できる機能を追加

・学習時間:1時間

・ステップ4でやったこと

①複数のタスクを削除できるようにした。

csvファイルに保存・CSVファイルから読み込みができるようにした。

・使った技術・文法

csvライブラリ: 

②openメソッド: 保存

③foreach:読み込み

・書いたコード

require "csv"

tasks = []

# ===CSVファイルを読み込み===
if File.exist?("tasks.csv")
  CSV.foreach("tasks.csv") do |row|
    tasks << row[0]
  end
  tasks.each_with_index do |task, i|
    puts "#{i + 1}: #{task}"
  end
end

# ===タスクの登録===
puts "タスクを入力してください。\n終了したいときは「end」を入力してください。"

loop do
  input = gets.chomp
  if input == "end"
    break
  end
  tasks.push(input)
end

# ===タスクの一覧表示===
tasks.each_with_index do |task, i|
  puts "#{i + 1}: #{task}"
end

# ===タスクの削除===
if tasks.empty?
  puts "削除するタスクはありません"
else
  puts "削除したいタスクの番号を選択してください。\n0を入力すると削除を終了します。"
  loop do
    input = gets.to_i
    if input < 0 || input > tasks.length
      puts "無効な番号です。"
    elsif input == 0
      break
    else
      tasks.delete_at(input - 1)
      tasks.each_with_index do |task, i|
        puts "#{i + 1}: #{task}"
      end
    end
  end
end

# ===CSVファイルに保存===
CSV.open("tasks.csv", "w") do |csv|
  tasks.each do |task|
    csv << [task]
  end
end

・感想と次のステップ CSVライブラリの使い方がなんとなくわかった。 現在は登録 → 一覧表示 (関数化したほうがよさそう?)→ 削除処理が一方通行のため 明日の朝活でメニューを追加して、操作を選べるようにする機能にチャレンジする。

4/2(水)朝活 ToDoリストCLIアプリ | ステップ③:タスクを削除する機能を追加

・学習時間:1時間

・ステップ3でやったこと

①タスクの番号を入力することでタスクを削除できるようにした。

②登録されたタスクを番号付きで一覧表示されるようにした。

・使った技術・文法

①length,size: 配列の要素数を取得するメソッド

②delete_at(添字): 添字を指定して配列の要素を削除できる。

・書いたコード

# 削除機能
puts "終了したタスクの番号を選択してください。"

input = gets.to_i
if input < 1 || input > tasks.length
  puts "無効な番号です。"
else
  tasks.delete_at(input - 1)
end

tasks.each_with_index do |task, i|
  puts "#{i + 1}: #{task}"
end

・感想・次のステップ

今日の夜「削除対象がない」時の対応と複数のタスクを削除する機能にチャレンジする。