日経有料記事の類似記事を無料で読めるChrome拡張をES6+Webpackの最小構成でつくった


## **概要**

最近は<a href="http://b.hatena.ne.jp/entry/www.nikkei.com/article/DGXMZO91790190W5A910C1000000/" target="_blank">こんな記事</a>もあるようなので、日経有料記事の類似記事を無料で読むことができるChrome拡張アプリをつくった。形態素解析して、名詞を区切ってGoogleで類似記事を検索している。

* <a href="https://github.com/okmttdhr/nikkei-hacker" target="_blank">okmttdhr/nikkei-hacker</a>

使い方は、有料記事のページヘゆき、`全文表示`の隣に出現した`無料で読む`ボタンを押すだけである。インストールなど、詳細は<a href="https://github.com/okmttdhr/nikkei-hacker" target="_blank">Github</a>に書いた。

![スクリーンショット 2015-10-26 9.02.29.png](https://qiita-image-store.s3.amazonaws.com/0/22875/6c6aebf1-20e7-71f4-883f-4b4307b1a9ff.png)



## **構成**

たいしたコードは書いていないが、ES6+Webpackでモジュール化的なことだけはしている。

WebpackをES6で書くために、以下の様なファイルを準備

```js:webpack.config.js
require('babel/register');

module.exports = exports = [
  require('./config/webpack'),
];
```

以下の様な感じで普通にconfigを書く。eslintだけいれている。

```js:config/webpack.js
import config  from './index';

const globals = config.get('globals');
const paths   = config.get('utils_paths');

const webpackConfig = {
  entry: paths.src('entry'),
  output: {
    path: paths.project(config.get('dir_dist')),
    filename: 'main.js'
  },
  plugins: [],
  module: {
    preLoaders: [
      {
        test: /\.js$/,
        loader: 'eslint',
        include: paths.project(config.get('dir_src')),
      },
    ],
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
      },
    ],
  },
  eslint: {
    configFile: paths.project('.eslintrc'),
    failOnError: globals.__PROD__,
    emitWarning: globals.__DEV__,
  },
};

export default webpackConfig;
```

例えば、`選択されたテキストを形態素解析→返ってきたxmlをobjectに→名詞のみを集めて返す`、ということをしている部分では、以下のようにメソッドを作っている。

```js:query.js
import request from 'superagent';
import {parseString} from 'xml2js';
import Promise from 'bluebird';

import config from '../config/secret';

// 形態素解析
function yahooMaApi(text) {
  return new Promise(function (resolve, reject) {
    request
      .get('http://jlp.yahooapis.jp/MAService/V1/parse')
      .query({
        appid: config.get('appid'),
        results: 'ma',
        sentence: text,
      })
      .end(function(err, res) {
        if (err) return reject(err);
        return resolve(res);
      });
  });
}

// xmlをobjectにし、名詞のみを集めて返す
function xml2query(xml) {
  return new Promise(function (resolve, reject) {
    parseString(xml, function (err, res) {
      if (err) return reject(err);
      let query = '';
      const wordList = res.ResultSet.ma_result[0].word_list[0].word;
      wordList.map((item) => {
        if (item.pos[0] === '名詞') {
          query += item.surface[0] + '+';
        }
      });
      return resolve(query);
    });
  });
}

// 最終的な結果(eg.`名詞1+名詞2+名詞3+`)を返す
export function getQuery(text = null) {
  return yahooMaApi(text)
    .then((xml) => {
      return xml2query(xml.text);
    })
    .then((query) => {
      return query;
    });
}
```

これを以下のように呼び出した。

```js:entry.js
import {getQuery} from './query';

getQuery(text)
  .then((query) => {
    $('#nhLink').attr({'href': 'https://www.google.co.jp/#q=' + query + '&tbm=nws'});
  });
```

他ソースは<a href="https://github.com/okmttdhr/nikkei-hacker" target="_blank">Github</a>においてある。

## **まとめ**

今回のコードだけではなんとも言えないが、小規模から中規模まで？なら、ES6+Webpackだけあれば十分なのでは、と思った。小さいアプリでも薄いフレームワークをいれるにこしたことはないが、モジュールを頑張れば、つくれないこともない。

変に学習コストもないし、いれるデメリットがないので、今後のプロジェクトでは、ES6+WebpackがJavaScript最小構成のデフォルトとなる気がしている。