03 / 実在パッケージの調査例 / 読了目安:7分
slugify:URL に「!」が残るのはなぜ?
「Déjà Vu!」は「deja-vu!」になりますが、欲しいのは「deja-vu」。REA で JavaScript パッケージを調べ、記号を制御する設定を探して結果を確認します。
このページの内容
答えを先に
lower: true は大文字を小文字にするだけです。記号も除くには、 strict: true を追加します。ライブラリの不具合ではなく、有効にする必要のあるオプションです。
slugify("Déjà Vu!", { lower: true, strict: true })
// → "deja-vu"01. 作りたかった URL
スラッグは URL の末尾にある読みやすい部分です。例えば example.com/posts/deja-vu の deja-vu が該当します。この例では実際の slugify 1.6.6 npm リリースを使い、以下の結果はその版をローカルで実行したものです。
下のタイトルを試し、次の項目を有効にしてください: 記号を除く。違いを確認できます。
「!」が残っている場合は有効にしてください: 記号を除く。
{ lower: true, strict: false }ブラウザー内で動作し、データは送信しません。REA は本文の調査手順で使用します。
同じ比較を JavaScript で行うと、次のようになります。
slugify("Déjà Vu!")
// → "Deja-Vu!"
slugify("Déjà Vu!", { lower: true })
// → "deja-vu!"アクセント記号は消えましたが、感嘆符は残りました。REA でパッケージのメインファイルを探し、フィルター処理を読んで、どのオプションが記号を除くか確認しました。以下で同じ手順を再現できます。
02. パッケージを取得し REA で調べる
固定バージョンの npm tarball を取得し、パッケージをインストール・実行せずに展開しました。以下の準備コマンドには、シェルで次のツールが必要です: tar:
mkdir rea-slugify-case
cd rea-slugify-case
npm pack [email protected]
tar -xzf slugify-1.6.6.tgz続いて、REA の JavaScript アプリ解析を実行しました。対象は展開後の package ディレクトリです:
コーディングエージェントを使うなら、パスを置き換えて以下を貼り付けてください。
REA で /absolute/path/to/rea-slugify-case/package を調べてください。記事の URL を作るために slugify を使っています。slugify('Déjà Vu!', { lower: true }) で感嘆符が残るのはなぜですか?エントリーファイルを探し、感嘆符を許可するコードと、それを除くオプションを示してください。パッケージは変更しないでください。または、ターミナルから直接解析結果を取得します:
npx -y [email protected] analyze-javascript-application ./package --json > analysis.jsonREA が特定したパッケージ名は slugify、バージョンは 1.6.6、エントリーポイントは ./slugify.jsでした。関連ファイル3件、解析失敗0件が記録されています。グラフ全体のカバレッジは 部分的とされており、公開サマリーでもその情報を残しています。
これは読める JavaScript ソースを含む配布物です。REA がファイル一覧と解析の文脈を提供し、続くソース確認と直接実行で動作を確かめました。ネイティブの逆コンパイルは行っていません。
03. 記号を除くオプションを探す
配布物に含まれる slugify.jsの33〜42行目では、文字列を正規化し、ロケールや文字マップによる置換を行い、文字をフィルターします。既定のフィルターは感嘆符を明示的に許可しています。
// remove not allowed characters
.replace(options.remove || /[^\w\s$*_+~.()'"!\-:@]+/g, '')
}, '');
if (options.strict) {
slug = slug.replace(/[^A-Za-z0-9\s]/g, '');
}strict の分岐はその後で実行され、英数字と空白以外を除きます。小文字化は57〜58行目の別処理です。ここから次の予測を検証できます。
slugify("Déjà Vu!", { lower: true, strict: true })
// should return "deja-vu"同じファイルから、連続する空白が一つの区切りになる理由、& が and に変わる理由、ドイツ語ロケールで Ä が AE に変わる理由も分かります。
04. 実際のパッケージで検証する
変更していない1.6.6に対して、最初の問いとその周辺動作を含む8件のアサーションを実行しました。
元のパッケージ · Node.js 22.23.1 · macOS arm64
| 入力 | オプション | 観測した結果 |
|---|---|---|
| Déjà Vu! | 既定値 | Deja-Vu! |
| Déjà Vu! | lower | deja-vu! |
| Déjà Vu! | lower + strict | deja-vu |
| hello world(前後に空白) | 既定値 | hello-world |
| Rock & Roll | 既定値 | Rock-and-Roll |
| Äpfel | ドイツ語ロケール + lower | aepfel |
| 空文字列 | 既定値 | 空文字列 |
| 42(数値) | 既定値 | 「string argument expected」をスロー |
記録した検証結果を読むか、上のパッケージデモを試してください。同じ固定バージョンのパッケージをブラウザー内で実行します。
05. テストした範囲
この版と入力では、ソースと観測結果が一致しました。目的の出力が deja-vuなら、次の両方を使います: lower: true と strict: true。
検証の範囲が重要です。 8件の検証で、すべての Unicode やロケールの動作が確かめられるわけではありません。REA のグラフは部分的で、関連が表示されないからといって存在しない証拠にはなりません。ネイティブバイナリを再実装したり、非公開ソースを復元したりしたわけでもありません。
配布ソースが読めるため、通常のソース確認でも調査できます。この例が示すのは、対象を特定し、一つのルールを調べ、元の実装で主張を検証する一連の習慣です。
06. サンプルを取得して実行する
小さな再現用キットをダウンロードしてください。固定した依存関係、8件すべてのアサーション、REA の根拠を自分で取得する手順が含まれています。
npm install --ignore-scripts
node verify.mjs検証スクリプトは各結果を表示し、失敗があればエラーで終了します。npm パッケージを Node.js で実行するのはこの検証段階だけです。それ以前の REA による静的解析では実行しません。
別のチュートリアルへアプリのエクスポート先を探す。根拠資料: REA 解析サマリー · 検証結果 · 確認したソース · MIT ライセンス。パッケージの作者は simov とコントリビューターです。解析と実行検証は2026年10月12日にローカルで行いました。公開サマリーにはローカルファイルシステムのパスを含めていません。