03 / 実在パッケージの調査例 / 読了目安:7分

slugify:URL に「!」が残るのはなぜ?

「Déjà Vu!」は「deja-vu!」になりますが、欲しいのは「deja-vu」。REA で JavaScript パッケージを調べ、記号を制御する設定を探して結果を確認します。

このページの内容
slugify 1.6.6 / MITREA 6.4.0確認日:2026年10月12日

答えを先に

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 リリースを使い、以下の結果はその版をローカルで実行したものです。

下のタイトルを試し、次の項目を有効にしてください: 記号を除く。違いを確認できます。

実際のパッケージを試す slugify 1.6.6
生成された URL
example.com/posts/deja-vu!

「!」が残っている場合は有効にしてください: 記号を除く。

JavaScript のオプション{ 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 slugify@1.6.6
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 rea-agents@6.4.0 analyze-javascript-application ./package --json > analysis.json

REA が特定したパッケージ名は slugify、バージョンは 1.6.6、エントリーポイントは ./slugify.jsでした。関連ファイル3件、解析失敗0件が記録されています。グラフ全体のカバレッジは 部分的とされており、公開サマリーでもその情報を残しています。

これは読める JavaScript ソースを含む配布物です。REA がファイル一覧と解析の文脈を提供し、続くソース確認と直接実行で動作を確かめました。ネイティブの逆コンパイルは行っていません。

03. 記号を除くオプションを探す

配布物に含まれる slugify.jsの33〜42行目では、文字列を正規化し、ロケールや文字マップによる置換を行い、文字をフィルターします。既定のフィルターは感嘆符を明示的に許可しています。

slugify.js · 41〜47行目
// 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件のアサーションを実行しました。

8 / 8
検証はすべて成功しました。

元のパッケージ · Node.js 22.23.1 · macOS arm64

入力オプション観測した結果
Déjà Vu!既定値Deja-Vu!
Déjà Vu!lowerdeja-vu!
Déjà Vu!lower + strictdeja-vu
hello world(前後に空白)既定値hello-world
Rock & Roll既定値Rock-and-Roll
Äpfelドイツ語ロケール + loweraepfel
空文字列既定値空文字列
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日にローカルで行いました。公開サマリーにはローカルファイルシステムのパスを含めていません。

REA は初めてですか? REA とは? · ガイドの検証方針