masalibの日記

システム開発、運用と猫の写真ブログです

reactとexpressをつなぐ

社内の勉強会でreactを勉強しています

サンプルをもとに作っているのですが
reactとexpressをつなぐ所が動かず・・・泣きそうになっています

何回目なのかわからないのですが1から作り直す事にしました

別のツールでつくれる事がわかりました

masalib.hatenablog.com

続きを読む

オリンピック会場が着々と作られているのね

先月ぐらいに渋谷のヒカリエにいきました
待ち時間があったのでちょっと写真をとりました


オリンピック会場が見えた・・・

ああ・・・着々と作らているのね

こんな景色がきれいな所だと仕事に手が付けられないような・・・
うちの会社は3階なので景色とか全然ないから
仕事が捗るね(笑)

都会はゴミゴミしているけど上から見ると爽快感があるね
夜だともっと綺麗なんだろうな〜

千葉のモノレールはカラフルだな

千葉駅に遊びに行ったのですが
その時にモノレールを乗ったのですが
駅メモのキャンペーンをおこなっていた

モノレールにラッピングしていて
ついつい撮ってしまった

モノレールから外を見ることはできるので
面白いつくりなっていた


駅メモ以外でもラッピングしているようなので
広告としていい感じですな

千葉のモノレールは2車両しかないので簡単なのかな??
ほとんどの車両にラッピングがされていた

puppeteerでイメージダウンロード

node.jsのスクレイピングといえばcheerio-httpcliでした
このモジュールは便利で画像の一括ダウンロードとかもできた

f:id:masalib:20180426213826j:plain

puppeteerはあまりダウンロードについては記載がなかった
いろいろ調べたらできた

ダウンロードすべきタグ(セレクター)がわかっている場合と
わからなくて兎にも角にも一括ダウンロードするやり方があるみたい

ダウンロードすべきタグ(セレクター)がわかっている時

const puppeteer = require('puppeteer');
const fs = require('fs');

(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    ignoreHTTPSErrors : true ,
  });
  const page = await browser.newPage();
  page.setViewport({ width: 1280, height: 926 });

  targetSelector = '#box2-inner > div.hatena-module.hatena-module-profile > div.hatena-module-body > a > img';

  await page.goto('http://masalib.hatenablog.com/');
  await page.waitForSelector(targetSelector);

  // Select the #svg img element and save the screenshot.
  const svgImage = await page.$(targetSelector);
  await svgImage.screenshot({
    path: 'Download/downimage.jpg',
    omitBac	kground: true,
  });
  await browser.close();
})();

わからないので一括ダウンロードする時

const fs = require('fs');
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  page.setViewport({ width: 1280, height: 926 });

  let counter = 0;
  page.on('response', async (response) => {
    const matches = /.*\.(jpg|png|svg|gif)$/.exec(response.url());
    if (matches && (matches.length === 2)) {
      const extension = matches[1];
      const buffer = await response.buffer();
      fs.writeFileSync(`Download/image-${counter}.${extension}`, buffer, 'base64');
      counter += 1;
    }
  });

  await page.goto('http://masalib.hatenablog.com/');
  await page.waitFor(10000);

  await browser.close();
})();

responseからURLを特定してダウンロードすることができるようになった
次はSPA(シングルページアプリケーション)での画像をとれるようにしたい
これができればインスタグラムの可愛い猫画像が大量にゲットできる

puppeteerでサブウィンドウから戻れない・・・

puppeteerでテストコードを記載しています
2018/04/26の時点はv1.3です

puppeteerとは
qiita.com


サブウィンドウとは
JavaScript/ウィンドウ/サブウィンドウを開く(クリック時) - TAG index

レガシーなシステムなのでサブウィンドウを使って選択させるような仕組みが多々あります
サブウィンドウを開いた時に
ブラウザのtargetcreatedイベントが発生するので
そちらでサブウィンドウの動作を記述するのですが
サブウィンドウから親ウィンドウに戻ることができないです

サブウィンドウを開いた時の処理

	//ブラウザのタブが開くと実行される所
   browser.on('targetcreated', async (target) => {
        console.log(`Created target type ${target.type()} url ${target.url()}`);
        if (target.url() == subwindowurl){
            var page2 = await target.page();
            var inputElement2 = await page2.$('body > center > form > table > tbody > tr > td:nth-child(4) > input[type="button"]');
            await inputElement2.click();	
            page2.close();
            return;
		} else if (target.type() !== 'page') {
            return;
        } else {
            var page = await target.page();
        }
    });

サブウィンドウを閉じた時の処理

	//ブラウザのタブ閉じられる時のイベント
   browser.on('targetdestroyed', async (target) => {
        console.log(`targetdestroyed target type ${target.type()} url ${target.url()}`);
        if (target.url() == subwindowurl){
			console.log('testtargetdestroyed');
			pages = await browser.pages();	
			pages.forEach(function (pageobj) {
				if (pageobj.url() == parrentURL){
					console.log(pageobj.url() );
					//ここが動かない
					// var inputElement2 = await pageobj.$('body > center > form > table > tbody > tr > td:nth-child(4) > input[type="button"]');
					// await pageobj.click();	
				}
			});
            return;
		} else if (target.type() !== 'page') {
            return;
        } else {
            return;
        }
    });


ここでハマるわけにはいかないので
時間をまって逃げた

	await inputElement.click();	//
	console.log("popup start");

	await page.waitFor(4000);
	console.log("popupがたぶん終了しているので作成開始" );
	var inputElement = await page.$('body > center > form > table > tbody > tr:nth-child(7) > th > input[type="button"]:nth-child(1)');
	await inputElement.click();
	console.log("作成終了" );


あああ・・・イケてない

reactでスプレッド演算子(...)を利用するとエラーになる

reactでサンプルソースを見ながら作っているのですが
...の部分でSyntaxErrorになってしまう

ERROR in ./src/reducers/authReducer.js
Module build failed: SyntaxError: Unexpected token (14:8)

  12 |     case SET_CURRENT_USER:
  13 |       return {
> 14 |         ...state,
     |         ^
  15 |         isAuthenticated: !isEmpty(action.payload),
  16 |         user: action.payload,
  17 |       };

全然理解できていなくて泣けてくる

この「...」のことをスプレッド演算子というらしい

スプレッド演算子とは

関数呼び出しでは 0 個以上の引数として、Array リテラルでは 0 個以上の要素として、Object リテラルでは 0 個以上の key-value のペアとして、Array や String などの iterable オブジェクトをその場で展開します。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
より引用

コンソールログにでる内容はどちらも同じになる
なるほどね

reactのコンパイルエラーは下記のサイトだと
qiita.com

babel-preset-stage-2をインストールしろって書いてある・・・
でもwebapckはv3の書き方みたいでそのままだとエラーになった

調べてみると公式にかいてあった
www.npmjs.com

.babelrc
{
  "presets": ["stage-2"]
}

.babelrcに追加したらコンパイルが通るようになった

機能を作るより環境とかではまっている・・・勉強会だからいいけど業務に使うならもっと勉強しないといけないな

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

react routerの「破壊的な変更」にハマる

会社の勉強会でreactを使ったシステムを使っています

誰もreactの事に精通しているわけではないので
githubのサンプルをもとに機能をつくっています

react routerというパッケージを使って
URLによってコンポーネントを切り替える機能をつくっているのですが
参考にしたサンプルソースはreact route v3ですが
現在はreact route v4がメジャーバージョンです


react route v3 → react route v4にバージョンアップした時に「破壊的な変更」をおこなったそうなのでv3のソースは動きません

qiita.com


使いやすくなったとはいえ、動かないのかよ

react系のパッケージはバージョンアップによって「破壊的な変更」が起きるみたいなので
サンプルソースをみる時にバージョンを確認が必須かも
楽しいけど、環境まわりでハマりたくないな~

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)