JavaScript
chrome-extension
dmm
React
性欲駆動開発

旧DMM.R18で女優をフォローするChrome拡張をReact+Webpackで作った


モチベーション

自分はジャンルやシチュエーションより出演者や監督でAVを選ぶことが多い。しかし、DMM.R18(元FANZA)では作品のお気に入りは出来るけど出演者をフォローする機能がない。「検索条件を保存」 という機能があるがこれは10件のキューで上限を超えて追加されると古いものから削除されるため使い勝手が悪かった。

そこで制限なく出演者をフォロー出来るアプリが欲しかった。

スクリーンショット 2019-03-11 1.29.30.png

試しにTwitterで調べてみると同じこと考えてる人はそれなりにいるみたい。


作ったもの

og24715/DMM.pornstars https://github.com/og24715/DMM.pornstars


構成

DMM.pornstars

├── README.md
├── node_modules
├── chrome
│   ├── dist
│   └── src
│   ├── background.js
│   ├── detail.js
│   ├── favorites
│   │   ├── App.jsx
│   │   ├── component
│   │   │   ├── card
│   │   │   │   ├── index.js
│   │   │   └── navbar
│   │   │   └── index.jsx
│   │   ├── index.css
│   │   ├── index.html
│   │   └── index.js
│   └── manifest.json
├── package-lock.json
├── package.json
├── webpack.config.js
└── yarn.lock

パス
説明

chrome/
実質 Chrome 拡張用のプロジェクトディレクトリ。

chrome/dist/
webpack によってバンドルされた諸々が吐かれるディレクトリ。Chromeにはここを読ませる。静的ファイルも src/ に置いて copy-webpack-plugin を使って dist/ 配置されるようにしたので当たり前だけどここは触らない。

chrome/src/background.js
アイコンがクリックされたら一覧を表示するだけ。

chrome/src/detail.js
DMM.R18 で作品の画面を表示しているときに、出演者の名前の横にフォローボタンを表示するだけ。

chrome/src/favorites/
一覧画面。React使ってる。


ハマりどころ


CRA (create-react-app) を使いたい

やめたほうがよさそうです。

だいぶ前に試した記憶だと、CRAはSPAを作るときには非常に頼りになるスタートアップツールですが、react-scripts ejectをしない限り webpack の entry を複数設定することが出来ません。画面ごとに create-react-app {project_name} しなくてはらず地獄です。


local.storage.get の第一引数に文字列で与えたのに第2引数のコールバック関数への引数がキーバリューになる

これはドキュメントちゃんと読んでください。

local.storage.get は第一引数に与えられた文字列もしくは文字列配列のキーをもとにキーバリューのオブジェクトを第二引数に与えられたコールバック関数へ引数として与えます。

第一引数に文字列を与える意図としては、キーを決定したので対応するバリューを返して欲しいってことなんですが、第一引数が文字列だろうと配列だろうとキーバリューをオブジェクトを返します。

コードにすると

// こうじゃなくて

chrome.storage.local.get('following', following = [] => { /* noop */ }));
// こう
chrome.storage.local.get('following', ({ following = [] }) => { /* noop */ }));

こんな感じ。

今の所 following ってキーでしか値を保存していないんですが、キー一つ与えたところでその値は返って返ってこないってことです。

ブラウザ実装の Window.localStorage.getItem と挙動が違うのでドキュメント見ないで実装するとハマります。

localStorage.getItem() - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/Storage/getItem

chrome.storage - Google Chrome https://developer.chrome.com/apps/storage


静的ファイルを src/ に置きたい

dist/ は極力触りたくありませんでした。

今回のアプリで静的ファイルは拡張のマニフェストファイルである manifest.json と Reactのエントリーポイントとなる index.html があります。

これらは素の webapck を通しても dist/ へ配置されないので webpack-copy-plugin を使うしかなさそうです。

plugins: [

new CopyWebpackPlugin([
{ from: './chrome/src/favorites/index.html', to: 'favorites.html' },
{ from: './chrome/src/manifest.json' },
]),

たかがコピーするだけなのにプラグインを追加し無くてはならない歯がゆさに gulp 時代の混沌をに似たものを感じます。

なにかいい方法があれば教えてください。


性欲駆動開発

https://twitter.com/search?q=%E6%80%A7%E6%AC%B2%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA