Check your pageページを検査する

The browser can't know that .nmae was meant to be .name. @wcstack/lint reads your HTML and your state together and tells you — before you reload.

.nmaeが.nameの打ち間違いだとは、ブラウザには分かりません。@wcstack/lintはHTMLとstateを突き合わせて読み、再読み込みする前に教えてくれます。

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7

Why a checkerなぜ検査器なのか

In wcstack the HTML and the state meet only through path strings. That is what keeps them independent — and it means a typo in a path is not a syntax error the browser could catch. The checker reads both sides and compares them: every path in data-wcs and {{ }} against the keys and getters of your state, every filter against the built-in list, every array call in your methods against the update rule.

wcstackでは、HTMLとstateはパスの文字列だけで結ばれています。だから両者は互いに独立していられるのですが、それはパスの打ち間違いがブラウザに見つけられる構文エラーにならない、ということでもあります。検査器は両側を読んで突き合わせます。data-wcsと{{ }}のすべてのパスをstateのキーやgetterと、すべてのフィルタを組み込みの一覧と、メソッド内の配列の呼び出しを更新の規則と照らし合わせます。

Run it実行する

You need Node.js. In the folder of your index.html from step 6, run:

Node.jsが必要です。ステップ6のindex.htmlがあるフォルダで、次を実行します。

terminal
$ npx @wcstack/lint index.html

0 error(s), 0 warning(s), 0 info

No configuration and no install step: npx fetches the checker and runs it. A few options are worth knowing:

設定もインストールの手順もいりません。npxが検査器を取ってきて実行します。知っておくと便利なオプションがいくつかあります。

OptionオプションWhat it does働き
--lang=jaMessages in Japanese (--lang=en for English).メッセージを日本語にする(英語は--lang=en)。
--errors-onlyPrint only errors — handy in a fix-and-rerun loop.エラーだけを表示する。直しては実行し直すループで便利。
--strictExit with 1 on warnings too. Without it, the exit code is 1 only when there is an error.警告でも終了コードを1にする。付けなければ、終了コードが1になるのはエラーがあるときだけ。

Each finding has a severity. An error is something the page cannot run with; a warning is almost certainly a mistake; an info is a suggestion.

指摘にはそれぞれ重さがあります。errorはページがそのままでは動かないもの、warningはほぼ確実に間違いであるもの、infoは提案です。

Break it on purposeわざと壊してみる

The fastest way to trust a checker is to watch it catch something. Make each change below in your step-6 page, reload the page to see what the browser does, run the checker, then undo the change. The line numbers are those of the step-6 file.

検査器を信頼するいちばんの近道は、何かを見つけるところを見ることです。ステップ6のページに下の変更を1つずつ加え、再読み込みしてブラウザの様子を見て、検査器を実行し、変更を元に戻します。行番号はステップ6のファイルのものです。

1. A typo in a path1. パスの打ち間違い

Change {{ .name }} in the product card to {{ .nmae }}. The page still loads, but every card loses its title — the only trace is a warning in the browser console. The checker points at the line:

商品カードの{{ .name }}を{{ .nmae }}に変えます。ページは読み込まれますが、すべてのカードから商品名が消え、手がかりはブラウザのコンソールの警告だけです。検査器はその行を指します。

terminal
$ npx @wcstack/lint index.html
index.html:97:18 warning wcs/binding-path-missing Path ".nmae" does not exist in the state definition (expanded: products.*.nmae)

0 error(s), 1 warning(s), 0 info

2. A filter that doesn't exist2. 存在しないフィルタ

Change {{ .price|toFixed(2) }} in the card to {{ .price|currency }}. This time nothing on the page binds: the state stops at startup with [wcs/filter-unknown] filter not found: currency in the console. The checker:

カードの{{ .price|toFixed(2) }}を{{ .price|currency }}に変えます。今度はページの何もバインドされません。stateは起動の時点で止まり、コンソールに[wcs/filter-unknown] filter not found: currencyが出ます。検査器の結果は次のとおりです。

terminal
$ npx @wcstack/lint index.html
index.html:99:39 error wcs/filter-unknown Filter "currency" is not a built-in filter

1 error(s), 0 warning(s), 0 info

The 47 built-in filters are listed on the state page.

47個の組み込みフィルタはstateのページに一覧があります。

3. push instead of a new array3. 新しい配列の代わりにpush

In addToCart, change this.cart = this.cart.concat( to this.cart.push(. In the browser, “Add to cart” now does nothing the first time you add a product. The checker reports an error, and three warnings after it:

addToCartのthis.cart = this.cart.concat(をthis.cart.push(に変えます。ブラウザでは、商品を初めて入れるときの「Add to cart」が何も起こさなくなります。検査器はエラーを1つと、それに続く警告を3つ出します。

terminal
$ npx @wcstack/lint index.html
index.html:59:11 error wcs/array-mutation Destructive array method "push" does not trigger a reactive update (re-assigning the same reference does not reflect added/removed elements either). Use a non-destructive method with reassignment (e.g. this.cart = this.cart.concat(item)).
index.html:117:40 warning wcs/binding-path-missing Path ".name" does not exist in the state definition (expanded: cart.*.name)
index.html:120:98 warning wcs/binding-path-missing Path ".quantity" does not exist in the state definition (expanded: cart.*.quantity)
index.html:121:24 warning wcs/binding-path-missing Path ".quantity" does not exist in the state definition (expanded: cart.*.quantity)

1 error(s), 3 warning(s), 0 info

Fix the error first: the warnings come from the same line. cart starts as an empty array, and the checker learned what a cart line looks like — name, quantity, … — from the object you passed to concat. Without that assignment it no longer knows the shape of a line. Put the concat back and all four go away.

先にエラーを直します。警告は同じ行から来ています。cartは空の配列から始まるので、検査器はカートの行の形(name、quantityなど)を、concatに渡したオブジェクトから知っていました。その代入が無くなると、行の形が分からなくなります。concatに戻せば、4つとも消えます。

Same codes, both sides両側で同じコード

The codes are the ones the browser console uses: wcs/binding-path-missing and wcs/filter-unknown above appeared in both places. A message you see at runtime can be found again, statically, with the checker.

コードはブラウザのコンソールと同じものです。上のwcs/binding-path-missingとwcs/filter-unknownは、どちらにも現れました。実行時に見たメッセージは、検査器で静的に見つけ直せます。

In your editor and your agentエディタとAIエージェントで

In VS Code, the wcstack-intellisense extension shows the same diagnostics as you type, completes paths and filters inside data-wcs, and gives the inline state script TypeScript's completion and hover.

VS Codeでは、拡張機能wcstack-intellisenseが、同じ診断を入力中に表示し、data-wcsの中でパスとフィルタを補完し、インラインのstateスクリプトにTypeScriptの補完とホバーを付けます。

If an AI coding agent writes your pages, have it run npx @wcstack/lint --errors-only index.html after each edit and fix until it exits with 0. It doesn't have to get the syntax right the first time; it has to converge.

AIのコーディングエージェントにページを書かせるなら、編集のたびにnpx @wcstack/lint --errors-only index.htmlを実行させ、終了コードが0になるまで直させます。最初から構文を正しく書けなくてもかまいません。収束すればよいのです。

Part 1 completePart 1 完了

You built a shop with a catalog, a cart, totals and search, in one HTML file and one script tag. Along the way:

HTMLファイル1つとscriptタグ1つで、商品一覧・カート・合計・検索のあるショップを作りました。その途中で学んだこと:

Coming nextこの先

Part 2 — Connect to the outside loads the catalog from a JSON file with <wcs-fetch> and keeps the cart across reloads with <wcs-storage>: tags and a few getters, no fetch() or localStorage in your code. Part 3 — Grow into an app adds product pages with <wcs-router>, splits the page into components, tests it with @wcstack/testing, and publishes it with pinned versions; it is in preparation.

Part 2 外の世界とつなぐでは、<wcs-fetch>でJSONファイルから商品一覧を読み込み、<wcs-storage>で再読み込みしてもカートを残します。加えるのはタグといくつかのgetterで、コードにfetch()やlocalStorageは出てきません。Part 3 アプリに育てるでは、<wcs-router>で商品ページを加え、ページを部品に分け、@wcstack/testingでテストし、バージョンを固定して公開します。こちらは準備中です。