0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ClaudeでHTMLを継ぎ足し編集して画面にJSが漏れた話と、私の対処5箇条

0
Posted at

Claude Cowork を社内AXの相棒として毎日使っているエンジニアの実践ログです。社内固有名・個人名は伏せています。

最初、Claude に「ちょっとここだけ書き足して」を3回繰り返せばラクできると思っていた。実際は逆。ブラウザを開いたら、本文の真ん中に JS のソースコードがズラっと表示されていた。if (type === 'success' || type === 'info') とか丸見え。3秒くらい固まった。

これ、地味に詰まった話なので残しておく。

何が起きたか

私が触っていたのは、業務用の シングルファイルHTML(1ファイルに HTML/CSS/JS が全部入っているやつ)だった。Claude に対して、追加機能を継ぎ足しで書かせていた。1回目はちゃんと <script> の中に入った。2回目もOKに見えた。3回目、UI に変化がない。リロードしてもダメ。

開いたら、画面の下の方に JS の生コードがテキストとして並んでいた。

原因はシンプル。Claude が新しい関数を </script> の外に書いてしまっていた。HTML としては「テキスト」扱いになるので、ブラウザはそれを律儀にレンダリングしていた。

うん、自分でも何やってんだろうって思った。

なぜ起きるか(私の解釈)

シングルファイルHTML × LLM の継ぎ足し編集は、3つの理由で壊れる。

  1. <script> の閉じ位置を見失う。長いファイルだと、LLM は </script> がどこかを毎回スキャンし切れない。
  2. 「ファイルの末尾」と「scriptの末尾」の区別がぼやける。「最後に追記して」と言われると、本当にファイル末尾に追記してしまう。
  3. 複数回の Edit が累積する。1回ごとは正しくても、2-3回繰り返すと、前回の追記が前提条件として壊れている。

結局、私が悪い。「全体構造を保つ責任」を Claude に丸投げしたら、こうなる。

私の判断:継ぎ足し3回でダメなら全書き直しに切る

これは賛否あると思う。でも私はもう、継ぎ足しでつまずいたら Python で1発書き直し に切るようにしている。理由は単純で、

  • 壊れたHTML を「丁寧に直して」と頼むのは、もう一度ガチャを引く行為
  • 書き直しの方が、結果として時間が短い

判断軸はこう。

3回目の継ぎ足しで挙動が想定と違ったら、もう Edit しない。Write で全書き直し。

中途半端に直そうとすると、また </script> の外に何か残ったままになる。経験則。

真似できるテンプレ:Python で1ファイルHTML を書き直す

私が使っている最小スニペット。

# rewrite_html.py
from pathlib import Path

OUT = Path("page.html")

HTML = """<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>業務ツール</title>
  <style> body { font-family: system-ui; } </style>
</head>
<body>
  <h1>ツール名</h1>
  <div id="app"></div>
  <script>
    // ここに JS を1ブロックで全部書く
    function init() { /* ... */ }
    init();
  </script>
</body>
</html>
"""
OUT.write_text(HTML, encoding="utf-8")
print(f"wrote {OUT} ({OUT.stat().st_size} bytes)")

ポイントは、Claude に「このテンプレに対して、機能Xを実装した完全版を1回で出して」と頼むこと。Edit じゃなくて Write。これが効く。

投稿前の壊れ検知チェック

書き直してもらった後、私は必ずこれを走らせている。

# script の開閉が対称か
grep -c '<script' page.html
grep -c '</script>' page.html

# 重要な関数の重複がないか
grep -c 'function init' page.html

# init() の呼び出し回数(末尾に1個だけのはず)
grep -c '^init();' page.html

<script></script> の数が一致しているか、init()1個だけ か。これだけで9割の事故は防げる。地味だけど、本当に効く。

ハマったところ

今回ハマった点を、嘘なく置いておく。

  1. 1回目の Edit が成功して油断した ── 2回目以降の累積で壊れることを想像できていなかった。
  2. 「画面が空白」ではなく「JSが表示される」と気付きにくい ── エラーじゃない。だから F12 を開かない。これが一番怖い。
  3. Claude に「壊れたHTML を直して」と頼んで、また </script> の外に追記された ── ガチャ。これで20分溶かした。正直しんどかった。
  4. ブラウザキャッシュで「直したはずなのに直ってない」状態を疑った ── 違った。コード側だった。Ctrl+F5 で時間を浪費。
  5. init() の重複呼び出しで、データが二重に描画された ── 末尾追記時、前の init(); が残っていた。
  6. テンプレリテラル ${...} のエスケープが追記時に崩れた ── バッククォート絡みは特に弱い。
  7. 「ちょっとだけ追記」が癖になっていた自分への自戒 ── これが本丸。

まとめ

  • シングルファイルHTML × LLM 継ぎ足し編集は、3回目で壊れる前提で運用する
  • 継ぎ足しでつまずいたら、Edit ではなく Write で全書き直し
  • 書き直しは「テンプレ + 完全版を1回で」が早い
  • <script></script> の数チェックを習慣にする
  • 「画面に JS が表示される」= </script> の外漏れ、と覚えておく

みなさんはシングルファイルHTML を LLM に触らせるとき、Edit と Write をどう使い分けていますか? 「3回までは Edit でいい」みたいなマイ基準があれば、コメントでぜひ教えてください。


Claude Cowork を社内AXの相棒として毎日使っているエンジニアの実践ログです。

私が日中見ている事業は「N限(Ngen)インターン」── 新卒の実務試験型(ワークサンプル型)インターンを企業に提供しています。AI時代の新卒採用に関心がある方は、下記からどうぞ。

シリーズ: Claude Cowork で社内AXを回す

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?