Gulpでcntl+cが効かない場合の対処法

Gakuです。
最近react+reduxあたりをちょろちょろ触っておりまして、それに付随しgulpもがっつり触っています。
その際、gulpコマンドを実行後、終了させるためにcntl+cを押しても反応しない問題に遭遇したので、その対処法を備忘録として残したいと思います。

現象

gulpfile.jsをgulpコマンドで実行し、終了しようとcntl+cを押しても反応しない。

[18:46:03] Using gulpfile ~\develop\projects\ToDoTool\electronapp\gulpfile.js
[18:46:03] Starting 'compile'...
[18:46:03] Finished 'compile' after 19 ms
[18:46:03] Starting 'electronstart'...
[18:46:03] Finished 'electronstart' after 4.42 ms
[18:46:03] Starting 'watch'...
[18:46:03] Finished 'watch' after 21 ms
[18:46:03] Starting 'default'...
[18:46:03] Finished 'default' after 2.28 μs
[gulp] compiled: 398 ms
[18:46:08] Starting 'compile'...
[18:46:08] Finished 'compile' after 11 ms
[gulp] compiled: 132 ms
[18:46:16] Starting 'compile'...
[18:46:16] Finished 'compile' after 5.21 ms
[gulp] compiled: 139 ms


←ここでcntl+cを押してもgulpが終了してくれない。

gulpfile.js

gulpfileはこんな感じで記述しています。

var gulp         = require('gulp');
var exec         = require('child_process').exec;
var babel        = require('gulp-babel');
var es2015       = require('babel-preset-es2015');
var react        = require('babel-preset-react');
var duration     = require('gulp-duration');

//設定
var props = {
  jsfilepath : 'src/scripts/**/*.{js,jsx}',
  outputdir  : 'src/dist'
};

//bebelで変換
gulp.task('compile',function(){
  exec('pwd');
  gulp.src(props.jsfilepath)
    .pipe(babel({
        presets: [es2015,react]
    }))
    .pipe(duration('compiled'))
    .pipe(gulp.dest(props.outputdir));
});

//electronの実行
gulp.task('electronstart', function(){
  exec('electron .', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
  });
});

//ファイル変更監視
gulp.task('watch',function(){
  gulp.watch(props.jsfilepath,['compile']);
});

gulp.task('default', ['compile','electronstart','watch']);

問題の対処法

この問題はwindows10環境でelectronアプリを起動した際に発生しました。
原因としては詳細に追求できていないのですが、gulp.watchが常駐しているため、cntl+cを押してもgulp.watchの処理が上書きされて終了できない状態になっていると推測します。
対処法としては、monitorctrlcというpackageを利用し、強制的にcntl+cを実行できるようにすると解消することが可能です。
[blogcard url=”https://github.com/pandell/node-monitorctrlc”][/blogcard]

monitorctrlcのインストール

npm install monitorctrlc --save

monitorctrlcの組み込み方

gulpfile.jsにmonitorctrlcをimportし、gulp.watchを記述するタスクにmonitorctrlc関数を記述します。

var gulp         = require('gulp');
var exec         = require('child_process').exec;
var babel        = require('gulp-babel');
var es2015       = require('babel-preset-es2015');
var react        = require('babel-preset-react');
var duration     = require('gulp-duration');
var monitorCtrlC = require('monitorctrlc'); //ここと

//設定
var props = {
  jsfilepath : 'src/scripts/**/*.{js,jsx}',
  outputdir  : 'src/dist'
};

//bebelで変換
gulp.task('compile',function(){
  exec('pwd');
  gulp.src(props.jsfilepath)
    .pipe(babel({
        presets: [es2015,react]
    }))
    .pipe(duration('compiled'))
    .pipe(gulp.dest(props.outputdir));
});

//electronの実行
gulp.task('electronstart', function(){
  exec('electron .', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
  });
});

//ファイル変更監視
gulp.task('watch',function(){
  monitorCtrlC();  //ここを追加
  gulp.watch(props.jsfilepath,['compile']);
});

gulp.task('default', ['compile','electronstart','watch']);

これでばっちりcntl+cの終了コマンドを実行することが可能です。

[18:47:57] Using gulpfile ~\develop\projects\ToDoTool\electronapp\gulpfile.js
[18:47:57] Starting 'compile'...
[18:47:57] Finished 'compile' after 20 ms
[18:47:57] Starting 'electronstart'...
[18:47:57] Finished 'electronstart' after 4.75 ms
[18:47:57] Starting 'watch'...
[18:47:57] Finished 'watch' after 18 ms
[18:47:57] Starting 'default'...
[18:47:57] Finished 'default' after 2 μs
[gulp] compiled: 366 ms



[20:18:48] '^C', exiting

material-uiでmuiThemeを入れろ!と怒られた時の対処法

Gakuです。
material-uiを入れると下記警告で怒られると思います。その際の対処法を記載します。

Warning: Failed Context Types: Required context `muiTheme` was not specified in `AppBar`.

無題

warningのくせして何も描画されません(´・ω・`)

material-uiのissueを漁っているとこんな記事がありました。
[blogcard url=https://github.com/callemall/material-ui/issues/686][/blogcard]

material-uiにはtheme機能が実装されているので、ちゃんと指定してあげないといけないみたいです。

main.jsxやindex.jsなどのmainとなるファイルを下記のように編集してあげれば良いです。

import React from 'react'
import ReactDOM from 'react-dom'
import Header from'./AppBar.jsx'
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

class TestBox extends React.Component {
  constructor(props) {
    super(props);
  }

  getChildContext() {
      return { muiTheme: getMuiTheme(baseTheme) };
  }

  render() {
    return(
      <div>
        <Header />
        <p>hoge</p>
      </div>
    );
  }
}

TestBox.childContextTypes = {
    muiTheme: React.PropTypes.object.isRequired,
};

ReactDOM.render(
    <TestBox />,
    document.getElementById('content')
);

無題

きれいになりました(´・ω・`)

material-uiでprops系のエラーが出たときの対象法

Gakuです。
CSSフレームワークのmaterial-uiを使っているのですが、導入した直後、以下のような警告が出ました。

Warning: Unknown props `rounded`, `zDepth`, `circle`, `transitionEnabled` on <div> tag.
Warning: Unknown props `tooltipPosition`, `onKeyboardFocus`, `onTouchTap` on <button> tag.
Warning: Unknown prop `hoverColor` on <span> tag.

無題

ぐぬぬ、ちゃんと設定できている気がするんだけど。。。(´・ω・`)

いろいろ探していたら、material-uiのissueとして挙がっていました。

[blogcard url=https://github.com/callemall/material-ui/issues/4594][/blogcard]

なんか、reactのv15.2.0入れているとダメみたいで、次期material-uiのリリースで対応するぉって書いているみたい。
とりあえず、reactの前バージョンであるreact-v0.14.8にダウングレードしてみる。

"author": "gaku",
  "license": "ISC",
  "devDependencies": {
    "babelify": "^6.4.0",
    "browserify": "^13.0.1",
    "gulp": "^3.9.1",
    "react": "^0.14.8",     //ここと
    "react-dom": "^0.14.8", //ここ
    "vinyl-source-stream": "^1.1.0"
  },

無題

すっきりっしゅ(´・ω・`)b

reactでelectronなes6で最小構成構築

Gakuです。
electron+react+es6で最小構成な感じのものを作ったので備忘録を。

electronはインストール済みのこと。
まだの人はこの記事を参照してください。
[blogcard url=http://160.16.72.126/?p=338][/blogcard]

準備

最終的なファイル構成

.
├── app
│   ├── build
│   │   └── app.js
│   ├── client
│   │   └── main.jsx
│   ├── index.html
│   └── index.js
├── gulpfile.js
└── package.json

もろもろ導入

npm init
npm install babel
npm install babelify@6.4.0 --save-dev
npm install react --save-dev
npm install react-dom --save-dev
npm install gulp browserify vinyl-source-stream --save-dev

いろいろファイル作成

{
  "name": "electron_test4",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "gulp browserify & electron ./app"
  },
  "author": "gaku",
  "license": "ISC",
  "devDependencies": {
    "babelify": "^6.4.0",
    "browserify": "^13.0.1",
    "gulp": "^3.9.1",
    "react": "^15.1.0",
    "react-dom": "^15.1.0",
    "vinyl-source-stream": "^1.1.0"
  }
}
const electron = require('electron');
// Module to control application life.
const {app} = electron;
// Module to create native browser window.
const {BrowserWindow} = electron;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({width: 800, height: 600});

  // and load the index.html of the app.
  win.loadURL(`file://${__dirname}/index.html`);

  // Open the DevTools.
  win.webContents.openDevTools();

  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    win = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <div id="content"></div>
    <script src="./build/app.js"></script>
  </body>
</html>
var babelify = require('babelify');
var gulp = require('gulp');
var browserify = require('browserify');
var source = require("vinyl-source-stream");

gulp.task('browserify', function(){
  var b = browserify({entries: ['./app/client/main.jsx']})
    .transform(babelify)
    .bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./app/build'));
});
import React from 'react'
import ReactDOM from 'react-dom'

class TestBox extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return(
      <p>hoge</p>
    );
  }
}

ReactDOM.render(
  <TestBox />,
  document.getElementById('content')
);

実行♪

npm start

おわりに

う〜ん。まだまだ友達になれない。特にbabel部分がよくわかってなくて絶賛はまった。。。
npm startも微妙だし。。。
ここからいろいろ触って勉強しようと思います。
reduxは当分触らないことに決めた(reactわかってないのにredux行っても利点がわからないため)
とりあえず勉強あるのみ( ;´Д`)

Electronアプリケーションをreactで構成してみる。

どうもGakuです。
今回はElectronアプリケーションをreactを使って構成してみたいと思います。
reactいいよreact!まだ掴みきれてないけど( ;´Д`)

Electronは導入済みの前提で記述していきます。
まだ導入していない方は下記記事を参考に構築してみてください。
[blogcard url=http://160.16.72.126/?p=338]ELECTRONを導入してみる![/blogcard]

導入

もろもろの導入

package.jsonの存在するフォルダへ遷移し、下記コマンドでbabelを導入します。

npm install babel babel-register babel-preset-react babel-preset-es2015 --save-dev

同様にreact,redux,gulp,browserify,reactify,vinyl-source-streamも導入します。

npm install react --save-dev
npm install react-dom --save-dev
npm install redux --save-dev
npm install gulp browserify reactify vinyl-source-stream --save-dev

package.jsonのscript部分を下記のように編集する。

"scripts": {
  "start": "electron ./app"
},

.babelrcを作成しreactを使用する設定を記述する。

{
  "presets": [
    "es2015",
    "stage-0",
    "react"
  ],
  "plugins": [
    "add-module-exports"
  ]
}

とりあえず動かしてみる

app/index.jsとapp/index.htmlを作成し下記のように編集します。
※下記コードはここらへんからパクってきただけなので、理解はしていない。
[blogcard url=”https://github.com/electron/electron/blob/master/docs/tutorial/quick-start.md”][/blogcard]

const electron = require('electron');
const {app} = electron;
const {BrowserWindow} = electron;
let win;

function createWindow() {
  win = new BrowserWindow({width: 800, height: 600});
  win.loadURL(`file://${__dirname}/index.html`);

  win.webContents.openDevTools();

  win.on('closed', () => {
    win = null;
  });
}

app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using node <script>document.write(process.versions.node)</script>,
    Chrome <script>document.write(process.versions.chrome)</script>,
    and Electron <script>document.write(process.versions.electron)</script>.
  </body>
</html>

下記コマンドでとりあえず動かしてみる

npm start

スクリーンショット 2016-06-19 10.53.36

いい感じっすね〜*・゜゚・*:.。..。.:*・'(*゚▽゚*)’・*:.。. .。.:*・゜゚・*

reactで動かしてみる

gulpファイルを下記のように作成します。

var gulp = require('gulp');
var browserify = require('browserify');
var source = require("vinyl-source-stream");
var reactify = require('reactify');

gulp.task('browserify', function(){
  var b = browserify({
    entries: ['./app/main.jsx'],
    transform: [reactify]
  });
  return b.bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./app/build'));
});

index.htmlを再度下記のように編集する。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <div id="content"></div>
    <script src="./build/app.js"></script>
  </body>
</html>

main.jsxを作成し下記のように編集する。

var React = require('react');
var ReactDOM = require('react-dom')

//コンポーネントを定義
var Index = React.createClass({
  render:function(){
    return (
        <p>hoge</p>
    );
  }
});

//id='content'の要素にコンポーネント「Index」を挿入してレンダリング
ReactDOM.render(
  <Index />,
  document.getElementById('content')
);

package.jsonのscript部分を再度下記のように編集する。

"scripts": {
  "start": "gulp browserify & electron ./app"
},

最後に実行

npm start

スクリーンショット 2016-06-19 11.40.46

うごく!うごくぞぉおお!〜*・゜゚・*:.。..。.:*・'(*゚▽゚*)’・*:.。. .。.:*・゜゚・*

最終的なファイル構成はこんな感じになるはず

.
├── app
│   ├── build
│   │   └── app.js
│   ├── index.html
│   ├── index.js
│   └── main.jsx
├── node_module
├── gulpfile.js
├── npm-debug.log
└── package.json

追伸

次回はreduxでいろいろ作ってみようかと思います。( ´ ▽ ` )ノ
いつもここまではいいんだよ。
こっからredux入ると鬼畜の極みなんだよな。。。
ただ、reactは使いこなせるようになりたい(´Д` )

以上です。

Electronを導入してみる!

どうもGakuです。

ちまたで流行りのElectronを導入し、実行ファイルを作成するところまでできたので備忘録として残します。

導入

electronのインストール

electronをインストールする前に、まだnodeを導入していない場合は下記コマンドで導入する。

brew install node

nodeのインストールが完了したらelectronを下記コマンドでインストールします。

npm -g install electron-prebuilt

おう。Very Eagy And Very Cool( ;´Д`)

アプリの作成

簡単なHello Worldアプリケーションを作成してみます。
開発用のフォルダを作成しnpm initします。

mkdir electron_test
cd electron_test
npm init

そしたらentry point(デフォルトならindex.js)のファイルを作成し、下記のように記述します。

"use strict";

const electron = require("electron");
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;

// 全てのウィンドウが閉じたら終了
app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// Electronの初期化完了後に実行
app.on('ready', function() {
  // メイン画面の表示。ウィンドウの幅、高さを指定できる
  mainWindow = new BrowserWindow({width: 800, height: 600});
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  // ウィンドウが閉じられたらアプリも終了
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

index.htmlを作成しHello Worldを記述します。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Sample</title>
</head>
<body>
  <p>Hello World</p>
</body>
</html>

ここまでできたら、上の階層へ戻って下記コマンドで実行します。

cd ./
electron electron_test/

スクリーンショット 2016-06-19 8.07.19

パッケージングする

このままではelectronコマンドを実行しなければ、作成したアプリを起動することができません。
そこで、windowsとmac上で実行可能なようパッケージングします。
とりあえず、下記コマンドでパッケージングツールを導入します。

npm i electron-packager -g

導入が完了したら、下記コマンドでwindowsとmacで起動可能な実行ファイルを作成します。

electron-packager ./ electron_test --platform=darwin,win32 --arch=x64 --version=0.36.1

ダブルクリックで実行可能なファイルが作成されます。

おう。Very Eagy And Very Cool( ;´Д`)

追伸

簡単にWebアプリーケーションを作る感覚でデスクトップアプリケーションを作成することができました。
こ・れ・わ。。。
デスクトップアプリケーションもiOSアプリケーションもAndroidアプリケーションもぜ〜んぶWebの技術で全て統一される世界になってきたなと。
これからの時代、WEBフロント技術取らないとエンジニアは死ぬぞ!まじで!って若干思った( ;´Д`)
まぁ、勉強しないやつが淘汰される世界は好きです。死ねばいい。

今度はreactあたり使っていろいろ触ってみようと思います。