読了時間 : 10 minutes

ローカルで自分のサイトが何も見えない瞬間を知っていますか? でもオンラインにデプロイしたらすべてが完璧になる? これは私の Gradle JBake プラグインで起きたことです。 タスク`serve`表示していたのは四角いボタン、黒い背景に黒いテキスト、そして奇妙に欠けているCSS。 しかし`publishSite`同じサイトを生成していましたが、それは完璧でした。問題の原因はCSSでもブラウザでもキャッシュでもなく、Kotlinのコードの1行と、コマンドライン引数の悪い習慣に起因していました。

強迫性障害

[]

シーン:4つのスクリーンショット、2つのレンダリング

それはシステムクラッシュの後のことだった。ローカルでのレンダリングを比較するために、スクリーンショットを4枚撮っていた(./gradlew serve`上`localhost:8820) インラインレンダリングとともに (`publishSite`GitHub Pagesでは)。ページごとに2枚のスクリーンショット:上部と下部。

ローカルレンダリング

ページの上部— ボタン Project と Template は小さくて長方形の, 標準の色(青と緑)に。Start Writing カードは を持っている黒の単色背景, フレームなし。

Rendu local - haut de page

ページ下部— サブタイトル "Derniers articles et ressources" はほぼ判読不能, 真っ黒い背景だと色が濃すぎます。ブログ画像の下の日付(「17 October 2013」など)は不在の。

Rendu local - bas de page

オンラインレンダリング

ページの上部— 同じボタンは大きい, 羊, 派手なネオン緑, 大文字のテキスト。地図には白い丸みのあるフレーム、ドロップシャドウ付き。

Rendu en ligne - haut de page

ページ下部— サブタイトルは読みやすい. 日付は見える. アイテムのカードは�丸い角そして タイトルは太字。

Rendu en ligne - bas de page

最初の反応:テーマ。私はダイナミックなテーマシステム(clair, sombre, high-contrast)を使用しています。それに基づいて`localStorage`. もしかしてローカルストアがハイコントラストテーマをトリガーしていたか? いいえ。すでに書いていたhttps://cheroliv.com/blog/2025/0098_preloading_css_variable_post.html[テーマのプリロードに関する記事全体], 私はそれがどう動くか知っている。そして、ハイコントラスト モードでも、CSS構造(楕円形のボタン、シャドウ)はそこにあるべきだった。それはそこにはなかった。

2番目の確認はブラウザキャッシュです。いいえ、クリーンなプロファイルでテストを行いました。差分は残っていました。

第三の反射:`serve`同じファイルを提供していなかった`publishSite`.

診断 : serve は正しいフォルダを指していなかった

私のGradleプラグイン`bakery`2つの主要なタスクがあります:

  • bake: 静的サイトを生成します`build/bake/`

  • serve: ローカルウェブサーバーを起動

  • publishSite: 押す`build/bake/`GitHub Pagesへ

差異は…からしか来得ない`serve`. Si publishSite`正しい内容を公開していた、それが`build/bake/`よかった。もし`serve`別のものを表示していたのは、それが役に立たなかったということだ。`build/bake/.

コードを見てみましょう。 中`SiteManager.kt`, タスク`serve`このように定義されています :

SiteManager.kt — La tâche serve (version buggy)
tasks.register("serve", JavaExec::class.java) { task ->
    task.apply {
        mainClass.set("org.jbake.launcher.Main")
        classpath = jbakeRuntime
        environment("GEM_PATH", jbakeRuntime.asPath)
        jvmArgs(/* ... */)
        args = listOf(
            "-b", file(site.bake.srcPath).absolutePath,
            "-s", layout.buildDirectory.get()
                .asFile.resolve(site.bake.destDirPath)
                .absolutePath
        )
    }
}

org.jbake.launcher.Main`はJBake 2.7.0 CLIのエントリポイントです。 アイデア:通過-b`ソースフォルダと`-s`出力先フォルダーを指定し、サーバーモードを起動します。ただし、…​

根本的な原因:JBake CLIはその通りに動作しない

JBake 2.7.0 待っている des位置引数ソースと宛先、続いてオプションのフラグ。シグニチャは:

jbake <source> <destination> [options]

しかし、私のコードでは、次のように書いていました:

args = listOf("-b", "/path/to/site", "-s", "/path/to/build/bake")

JBakeはそれをこう解釈した:

  1. -b→ フラグ「bake」をパース(ブール値)、消費された

  2. /path/to/site→ となる位置引数 1 (ソース)

  3. -s→ フラグ 'serve' (ブール型)をパースし、サーバーが起動すぐに

  4. /path/to/build/bake→ それは孤立した議論となり、無視されたり誤解されたりする

結果 : JBake は取っていました`/path/to/site`ソースとして、目的地を考慮に入れていなかった提供された (build/bake), そしてそれはそのデフォルトディレクトリを使用していました(しばしば`./output`一時的なコピー). ファイル`css/styles.css`ビルドはしたがって上書きまたは無視され、カスタム変数も丸みも影もない古いデフォルトのCSSが提供されていた。

比較すると`bake` et publishSite`使用している公式のGradle JBakeプラグイン(`jbake-gradle-plugin) きれいに書き込む`build/bake/`Gradle の API を通じて実行されます。CLI を経由しません。

解決策:位置引数、フラグではない

修正は単純だ — 知ってしまえば。ソースとデスティネーションを位置引数として渡すだけです。その後`-s`最後に:

SiteManager.kt — La tâche serve (version corrigée)
args = listOf(
    file(site.bake.srcPath).absolutePath,
    layout.buildDirectory.get()
        .asFile.resolve(site.bake.destDirPath)
        .absolutePath,
    "-s"
)

それだけです。3行変更され、バグが修正されました。

プラグインをローカルで公開した後 (publishToMavenLocal), un `./gradlew serve`JBakeを正しい構文で実行:

jbake /home/user/project/site /home/user/project/build/bake -s

そして今回は、JBakeに組み込まれたJettyサーバーが、内容をうまく提供しています。build/bake/— オンラインで公開されているものと同じです。

@startuml
!define RECTANGLE class

package "前に (bug)" {
  RECTANGLE JBakeCLI1 {
    + args = ["-b", "サイト", "-s", "ビルド/ベイク"]
  }

  RECTANGLE Source1 {
    + site/
  }

  RECTANGLE Dest1 {
    + ??? (dossier temporaire)
  }

  RECTANGLE Jetty1 {
    + sert mauvais fichiers
  }

  JBakeCLI1 --> Source1 : lit
  JBakeCLI1 -[#red]x Dest1 : destination ignorée
  Jetty1 --> Dest1 : sert
}

package "後(修正)" {
  RECTANGLE JBakeCLI2 {
    + args = ["サイト", "ビルド/ベイク", "-s"]
  }

  RECTANGLE Source2 {
    + site/
  }

  RECTANGLE Dest2 {
    + build/bake/
  }

  RECTANGLE Jetty2 {
    + sert les bons fichiers
  }

  JBakeCLI2 --> Source2 : lit
  JBakeCLI2 --> Dest2 : écrit dans
  Jetty2 --> Dest2 : sert OK
}
@enduml

curlを使った素早い検証

サーバーが正しいコンテンツを提供していることを確認するため、シンプルな`curl`確認します`index.html`含む`data-bs-theme="light"`そして`build/bake/css/styles.css`確かに31 402バイト — 生成されたファイルと同一である`bake`.

$ ./gradlew serve
# Dans un autre terminal :
$ curl -s http://localhost:8820/ | grep data-bs-theme
<html ... data-bs-theme="light" ...>

$ curl -I http://localhost:8820/css/styles.css
HTTP/1.1 200 OK
Content-Length: 31402
Content-Type: text/css

ローカルレンダリングは現在同一ピクセルデプロイされたレンダリングに。

なぜこのバグが厄介だったのか

なぜ捕まえるのが難しかったか、わかりますか?

  1. 明示的なエラーはありません: JBakeはクラッシュしませんでした。それは単に間違ったフォルダで「動作していた」だけ。

  2. ビルドは機能していた:`./gradlew bake`正しくファイルを生成していた`build/bake/`.

  3. デプロイメントが機能していました:`publishSite`オンラインで良いコンテンツを推していた。

  4. だけ serve 壊れていた: 開発タスク、つまり常に使ってイテレーションを行うもの

  5. -key value`の習慣: 開発者として、私たちは何年ものUnix CLIに条件付けられている (-o output, -i input). JBake CLI は例外です — ソースとデスティネーションは位置引数です。

結論

JBake(または他のCLIツール)をラップするGradleプラグインをメンテナンスしている場合引数のドキュメントを読んでくださいたとえあなたがそれらを知っていると思っていても。 暗黙の仮説 (-s= "set destination") これは視覚的なデバッグに何時間もかかる可能性があります。

ここで、この修正は文字通りに変更することだった:

args = listOf("-b", src, "-s", dest)   // ❌ BUG

en :

args = listOf(src, dest, "-s")         // ✅ FIX

3つのトークンが移動されただけで、私のローカルサイトは本番サイトと同じくらい美しくなりました。

レッスン: レンダリングがローカルと本番で理由なく異なる場合、まずまず pipeline を疑う — CSSでもなく、ブラウザでもなく、ましてやフレームワークでもない。これはしばしば、レンダリング直前の手順がごまかしていることが多い。

関連記事