ブックマークレットを作成する時の雛形プロジェクトを作った

ブックマークレットを作る時の雛形があればいいなぁと思って作成しました🐣
ローカルに置いておくと、ブックマークレットを作りたいときにサクッと圧縮してブックマークレットの形式にしてくれるので重宝してます。

## リポジトリ

リポジトリは以下です。

https://github.com/Int314/bookmarklet-development-template


## ファイル構成

以下のようなファイル構成になっています。

```
.
├── README.md
├── dist
│ └── bookmarklet.js
├── node_modules
├── package-lock.json
├── package.json
└── src
    └── main.js
```

- `src/main.js`: 開発用のJavaScriptファイル。ここにブックマークレットとして動作させたいコードを書きます。
- `dist/bookmarklet.js`: ビルド後に生成されるブックマークレット。ブラウザで動作させるためにブックマークに登録するJavaScriptがこのファイルに出力されます。

## 使い方

### 依存関係のインストール

まず、以下のコマンドで依存関係をインストールします。

```bash
npm install
```

### コードを書く

`src/main.js`にブックマークレットとして実行したJavaScriptのコードを書きます。

例）ページ内のすべての見出しタグ（h1〜h6）に背景色を追加するコード

```javascript
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(heading => {
  heading.style.backgroundColor = '#ff0';  // 背景色を黄色に
  heading.style.color = '#000';  // テキストを黒に
  heading.style.padding = '10px';  // パディングを追加
});

```

### ビルド

コードを書き終えたら、以下のコマンドでブックマークレット用にコードをビルドします。

```bash
npm run build
```

ビルドが成功すると、`dist/bookmarklet.js`にブックマークレット用のコードが生成されます。
この時、空白やコメントは削除されて、いい感じに圧縮されます。

```javascript
javascript:(()=>{
const headings=document.querySelectorAll("h1, h2, h3, h4, h5, h6");headings.forEach(a=>{a.style.backgroundColor="#ff0";a.style.color="#000";a.style.padding="10px"});
})();
```

## ブックマークレットの使用

1. ブラウザでお気に入りのページを開きます
2. 生成された`dist/bookmarklet.js`の内容をコピーします
3. ブラウザのブックマークに新しいブックマークを作成し、URL欄で`javascript:`に続けてコピーしたコードを貼り付けます
4. ブックマークレットをクリックして実行します

## Google Closure Compilerを使ってコードを圧縮しています

コードを圧縮するために、Google Closure Compilerを使用しています。
Google Closure CompilerはWeb版の[Closure Compiler Service UI](https://closure-compiler.appspot.com/home)もあるので、そちらを使えば早いのですが、サービスが終了する予定とのことで、ローカル実行できる環境を作りたかったんです。

### ビルドコマンド

ビルドコマンドは、`package.json`にある以下の行です。

```json
"build": "google-closure-compiler --js src/main.js --js_output_file dist/bookmarklet.js && echo \"javascript:(()=>{\" | cat - dist/bookmarklet.js > dist/temp && mv dist/temp dist/bookmarklet.js && echo \"})();\" >> dist/bookmarklet.js"
```

このコマンドは、以下のステップでブックマークレットを生成してます。

#### 1. Google Closure Compilerを使用してコードを圧縮

```bash
google-closure-compiler --js src/main.js --js_output_file dist/bookmarklet.js
```

`src/main.js`に記述されたJavaScriptコードを、Google Closure Compilerを使って最適化・圧縮します。
圧縮後のコードは`dist/bookmarklet.js`に出力されます。

どれぐらいコードを最適化するかは、コンパイルレベルオプション『`--compilation_level`』で指定できます。
とりあえずデフォルトにしてます！

- BUNDLE: 複数のファイルを結合するだけで、圧縮や最適化はしない
- WHITESPACE_ONLY: 空白や改行を削除してコードのサイズを小さくしますが、変数や関数名の変更はしない
- SIMPLE: 変数名の短縮や不要なコードの削除などの安全な最適化を行う（デフォルト）
- ADVANCED: 最大限の最適化を行いますが、外部依存関係との連携に注意が必要

https://github.com/google/closure-compiler/wiki/Flags-and-Options

#### 2. ブックマークレット形式に変換

```bash
echo "javascript:(()=>{" | cat - dist/bookmarklet.js > dist/temp && mv dist/temp dist/bookmarklet.js
```
生成された`dist/bookmarklet.js`に対して、先頭に`javascript:(()=>{`を追加しています。これにより、ブックマークレットとして動作する自己実行関数形式に変換します。
`echo`コマンドで`javascript:(()=>{`を出力し、`cat`コマンドでこれを既存の`dist/bookmarklet.js`の内容と結合し、一時ファイル (dist/temp) に保存します。
その後、一時ファイルを元のファイル名にリネームして上書きします。


#### 3. 末尾に関数の閉じ括弧を追加

```bash
echo "})();" >> dist/bookmarklet.js
```

最後に`dist/bookmarklet.js`の末尾に`})();`を追加して閉じます。

#### 最終的な結果

最終的に、以下のようにブックマークレットで動作する形式にして出力してます。

```javascript
javascript:(()=>{ /* 圧縮されたコード */ })();
```

## 参考
- https://developers.google.com/closure/compiler/docs/gettingstarted_ui?hl=ja
- https://github.com/google/closure-compiler