Check the page againもう一度ページを検査する

The mistakes of Part 2 don't break the page. It runs, it looks right — and it loses the cart after a reload. The checker reads the wcs-* tags too, and reports them before you reload.

Part 2の間違いはページを壊しません。ページは動き、正しく見え、そして再読み込みの後でカートを失います。検査器はwcs-*タグも読み、再読み込みの前にそれを報告します。

  1. 8
  2. 9
  3. 10
  4. 11
  5. 12

Run it実行する

In the folder of your index.html from step 11:

ステップ11のindex.htmlがあるフォルダで実行します。

terminal
$ npx @wcstack/lint index.html

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

If you see seven warnings about .stock, .name and .price instead, npx ran a checker older than 4.0.2, which doesn't read the type comments of step 8. Run npx @wcstack/lint@latest index.html.

代わりに.stock・.name・.priceについての警告が7つ出たら、npxが4.0.2より古い検査器を実行しています。その版はステップ8の型のコメントを読みません。npx @wcstack/lint@latest index.htmlを実行してください。

The checker knows every wcs-* tag: the properties each one has, which of them are outputs, inputs and commands, and how <wcs-storage> and a trigger behave at startup. That is what the three mistakes below need.

検査器はすべてのwcs-*タグを知っています。それぞれがどんなプロパティを持ち、そのどれが出力・入力・命令か、<wcs-storage>やtriggerが起動時にどう振る舞うかです。下の3つの間違いには、それが要ります。

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

Make each change in your step-11 page, try it in the browser, run the checker, then undo it. The line numbers are those of the step-11 file.

ステップ11のページに変更を1つずつ加え、ブラウザで試し、検査器を実行し、変更を元に戻します。行番号はステップ11のファイルのものです。

1. Bind the cart itself1. カートそのものをバインドする

Change the tag's binding to data-wcs="value: cart". In the browser, add House Blend twice: the page says 2, the stored cart says 1. Reload: the cart is gone. The checker gives both reasons:

タグのバインディングをdata-wcs="value: cart"に変えます。ブラウザでHouse Blendを2回入れると、ページは2、保存されたカートは1です。再読み込みするとカートは消えます。検査器は両方の理由を挙げます。

terminal
$ npx @wcstack/lint index.html
index.html:107:13 warning wcs/storage-seed-clobber The <wcs-storage> value-bound slot "cart" is seeded with []. The initial write-back overwrites the persisted value on every load — add #init=element to the binding (`value#init=element: cart`) so the stored value wins, and seed the slot with null (what an empty key loads as)
index.html:107:20 warning wcs/input-nested-write "cart" is bound to the input "value" of <wcs-storage>, but the page writes below it ("cart.*.quantity"). A binding is re-applied only when "cart" itself is assigned, so those writes never reach <wcs-storage> — bind a getter that reads the fields by path (`this["cart.*.quantity"]`, `$getAll`) and returns a new value, or replace "cart" instead of writing below it

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

The first is the reload: the starting [] is saved over the stored cart. The second is the quantity: addToCart and the stepper write cart.*.quantity, below the bound path. Step 11's savedCart answers both.

1つ目は再読み込みの件です。最初の[]が保存済みのカートの上に保存されます。2つ目は数量の件です。addToCartと数量のボタンは、バインドしたパスの下のcart.*.quantityに書きます。ステップ11のsavedCartが、どちらにも答えています。

2. Let the element win, with the cart2. カートのまま要素を勝たせる

Now try data-wcs="value#init=element: cart", in a private window so that localStorage starts empty. “Add to cart” does nothing, and the console says Cannot read properties of null (reading 'findIndex'): the empty key loaded as null, and #init=element wrote it into cart. The checker:

次はdata-wcs="value#init=element: cart"を、localStorageが空で始まるプライベートウィンドウで試します。「Add to cart」は何もせず、コンソールにCannot read properties of null (reading 'findIndex')が出ます。空のキーがnullを読み、#init=elementがそれをcartに書いたのです。検査器の結果は次のとおりです。

terminal
$ npx @wcstack/lint index.html
index.html:107:13 warning wcs/storage-init-seed The <wcs-storage> value-bound slot "cart" is seeded with [], but #init=element pulls the element's value into it. On a first visit (an empty key) that is null, so the seed is replaced by null — seed it with null and supply the default where you read it (`this.cart ?? …`), or bind an accessor pair whose setter ignores null
index.html:107:33 warning wcs/input-nested-write "cart" is bound to the input "value" of <wcs-storage>, but the page writes below it ("cart.*.quantity"). A binding is re-applied only when "cart" itself is assigned, so those writes never reach <wcs-storage> — bind a getter that reads the fields by path (`this["cart.*.quantity"]`, `$getAll`) and returns a new value, or replace "cart" instead of writing below it

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

“An accessor pair whose setter ignores null” is savedCart.

「nullを無視するsetterを持つアクセサペア」とは、savedCartのことです。

3. A typo in the type3. 型の打ち間違い

In the @typedef, change name: string to nmae: string. The page is unaffected — the comment is not code — but the checker believes it:

@typedefのname: stringをnmae: stringに変えます。ページには影響しません(コメントはコードではないので)。けれども検査器はそれを信じます。

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

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

The warning points at the product card, and the mistake is in the comment. The type is a promise about the file; when the two disagree, check the file first.

警告は商品カードを指していますが、間違いはコメントの中にあります。型はファイルについての約束です。食い違ったら、まずファイルを確かめましょう。

What the checker can't see検査器に見えないもの

The checker can't see the file a page fetches, beyond the type you declare, and it can't run the page: a cart that empties on reload for a reason it doesn't know shows up only in the browser. Keep the habit the demos teach: add something, reload, and look. (Forgetting #init=element on savedCart, from step 11, it does report since 4.0.3.)

検査器には、ページが読み込むファイルは宣言した型より先は見えず、ページを動かすこともできません。検査器の知らない理由で再読み込みのたびにカートが空になるなら、それはブラウザでしか分かりません。デモが教える習慣を続けましょう。何かを入れて、再読み込みして、見ることです。(ステップ11の、savedCartの#init=elementの付け忘れは、4.0.3から報告します。)

Part 2 completePart 2 完了

The shop now loads its catalog from a file, says so when that fails, and keeps the cart across reloads and tabs — with two tags and no fetch(), localStorage or try / catch in your code. Along the way:

ショップは商品一覧をファイルから読み、失敗したらそれを伝え、カートを再読み込みやタブをまたいで残すようになりました。使ったのはタグ2つで、コードにはfetch()もlocalStorageもtry / catchもありません。その途中で学んだこと:

Coming nextこの先

Part 3 — Grow into an app adds product pages with <wcs-router>, splits out a component, tests the page with @wcstack/testing, and publishes it with a pinned, verified version. From there on you need Node.js and a local server.

Part 3 アプリに育てるでは、<wcs-router>で商品ページを加え、部品に分け、@wcstack/testingでテストし、固定して検証できるバージョンで公開します。ここから先はNode.jsとローカルサーバーが必要です。