Mac新OS「Sierra」で内蔵カメラが動かなくなった件
今回「Sierra」へのアップデートでは早くもいくつか辛酸を味わっていますが、FaceTimeカメラについてはようやく解決したのでメモを残しておきます。
以下、やってみたこと。
VDCAssistantのプロセス強制終了
カメラを握っているプロセスがあることで、他で利用できなくなっている可能性があるそうです。 以下のコマンドを実行後に再起動をおこないます。 わたしは上記では解決しませせんでした。
sudo killall VDCAssistant
Macで急にFaceTimeカメラが認識されなくなった時の対処法 - Qiita
SMCリセット
電源を切った状態からCtrl + Shift + Option と電源ボタンを押す。 こちらも改善には至りませんでした。
セーフモード再起動
ここで解決しました。 こちらは起動のアップルロゴ表示時にDキーを押して立ち上げます。 動きがカクカクしたセーフモードで起動しアプリ「PhotoBooth」でカメラをチェックすると、何事もなかったかのように動いていました。 その後、再起動をおこない通常モードで起動、この時点でカメラは正常動作していました。
カメラのアクセス権がどこかで握られていたか、設定のキャッシュが残っていたかなど定かではありませんが、類似の事象でお困りの方は上記のいずれかで改善されるかもしれないので試してみてください。 (他の情報があればコメント等いただければ幸いです)
React開発をwebpackでおこなう
概要
前回までの記事でgulpを利用しての開発を進めていましたが、いろいろ見聞してwebpackを使ってみることにしました。
利点を簡潔に言えば、jsをひとつに纏めるかファイル群としてストアするかの選択ができます。さらにwebpack-dev-serverと組み合わせれば、実ファイルを都度生成することなくローカルサーバーで試走が行えるので、タスクランナーとしてgulpと入れ替えても事足りると思います。
最低限のサンプル
以下のことをできる最低限の構成です。
- EcmaScript6、JSXのトランスパイル実行
- ローカルサーバーでの試走
全体構成
─ / └ src/ │ └ entry.jsx │ └ index.html └ .babelrc └ package.json └ web.config.js
コード本体
シンプルにベースのindex.htmlにentry.jsxをロードするだけのサンプルです。 動作すれば画面に「Hello World」が表示されます。
index.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Hello World</title> </head> <body> <div id="app"></div> <script src="./bundle.js"></script> </body> </html>
entry.jsx
import React from 'react'; import { render } from 'react-dom'; render(( <div> Hello World </div> ), document.getElementById('app'));
セッティング
以下のコンフィグで行われる処理は次のとおりです。
- entryファイルとしてsrc下のindex.html、entry.jsxを取り込む。
- jsxを起点にあとの処理でimportされるファイルは全て自動的にトランスパイル対象になる。
- htmlファイルは同名でそのまま出力する。
- jsxファイルはトランスパイルして出力する、ただしnode_modules下は対象外にする。
webpack.config.js
module.exports = { context: __dirname + '/src', entry: { jsx: "./entry.jsx", html: "./index.html", }, output: { path: __dirname + '/dist', filename: 'bundle.js', publicPath: '/', }, module: { loaders: [ { test: /\.html$/, loader: "file?name=[name].[ext]" }, { test: /\.jsx$/, exclude: /node_modules/, loader: 'babel' }, ] }, resolve: { extensions: ['', '.js', '.jsx'] }, };
補足
- loader指定する際はnpmパッケージ名末尾から「-loader」を省略して書けるので、上記に当てられている正確なパッケージ名はfile-loader・babel-loaderです。
- extensionsに記載された拡張子はjsx内のimport対象を探索する際のパターンになります。
import Test from './test'; // 上記の場合、「./test」「./test.js」「./test.jsx」のいずれかを探す。 // ファイルタイプ別で重複命名があるとエラーになってしまうので注意
.babelrc
{ "presets": ["react", "es2015"] }
loader設定時にオプション指定することもできるが、別ファイルを用意したほうが役割がはっきりするので分割しました。 webpackのコンフィグ側に記載する場合は以下のように記載できます。
: loaders: [ { test: /\.jsx$/, exclude: /node_modules/, loader: 'babel?presets[]=react&presets[]=es2015' }, ] :
package.json
- 上記コード、トランスパイラで必要なパッケージを纏めました。
- また、scriptsにはトランスパイル実行(ビルド)とローカルサーバー起動コマンドを記載してみました。
{ "name": "hello", "version": "1.0.0", "description": "", "main": "entry.jsx", "scripts": { "build": "webpack --progress --colors", "start": "webpack-dev-server --hot --inline --progress --colors" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.17.0", "babel-loader": "^6.2.5", "babel-preset-es2015": "^6.16.0", "babel-preset-react": "^6.16.0", "file-loader": "^0.9.0", "webpack": "^1.13.2", "webpack-dev-server": "^1.16.2" }, "dependencies": { "react": "^15.3.2", "react-dom": "^15.3.2" } }
実行コマンド
npm install npm run start npm run build
ローカルサーバーはデフォルト http://localhost:8080/ が起点となります。
【補足】ESLintもフックしておく
WebpackでESLintを実装しておくと、ビルドやウォッチのタイミングでチェックが行われるためきれいなコードが書けるかと思います。 こちらも有用なので、メモ代わりに載せておくことにしました。
導入手順
- ESLintを設定します。セットアップは公式ドキュメントが参考になります。
- webpack.config.jsに以下のとおり加筆します。
--- a/webpack.config.js +++ b/webpack.config.js @@ -10,6 +10,9 @@ module.exports = { publicPath: '/', }, module: { + preLoaders: [ + { test: /\.jsx$/, loader: "eslint" }, + ], loaders: [ { test: /\.html$/, loader: "file?name=[name].[ext]" }, { test: /\.jsx$/, exclude: /node_modules/, loader: 'babel' },
- eslint-loaderも忘れずにインストールします。
npm i -D eslint-loader
- Webpack実行時にエラーがあれば以下のように表示されます。
- 以下はbrowser環境変数をエスケープせずに"document"を参照するコードが内包されていた例
入門 React ―コンポーネントベースのWebフロントエンド開発
- 作者: Frankie Bagnardi,Jonathan Beebe,Richard Feldman,Tom Hallett,Simon HØjberg,Karl Mikkelsen,宮崎空
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/04/03
- メディア: 大型本
- この商品を含むブログ (2件) を見る
Reactjsのstate/propsの挙動を確認する極力シンプルなコード
以下の記事で紹介したサンプルコードです。 tak-taniguchi.hatenablog.com
概要
Reactのstate/propsの関係を簡潔に表すために書いてみました。 余計なコードをほとんど書いていないので、UIは見づらいですが動きがわかりやすいかと思います(笑)
- 動作に成功すると、ブラウザの左上に「0」が表示されます。
- 「0」をクリックすると数値が加算されていきます。
ファイル構成
─ / └index.html └bundle.js // index.jsxをbabelifyして作ってください └index.jsx // ソース本体
index.html
<!doctype html> <head> <meta charset="utf-8"> <title>react state/props sample</title> </head> <body> <div id="content"></div> <script src="./bundle.js"></script> </body> </html>
index.jsx
import React from 'react' import ReactDom, { render } from 'react-dom' /** * 親コンポーネントクラス */ var Parent = React.createClass({ getInitialState: function () { // this.state.counterを初期化しています return { counter: 0 } }, handleAdd: function () { // this.state.counterを加算するハンドラーです this.setState({ counter: this.state.counter + 1 }); }, render: function () { // 子コンポーネントを呼び出しています。 return ( <Child counter={this.state.counter} onClickHandler={this.handleAdd} /> ); } }); /** * 子コンポーネントクラス */ var Child = React.createClass({ render: function () { // this.props.onClickHandlerは親クラスhandleAdd()を参照 // this.props.counterは親クラスのstate.counterを参照 // onClick()が実行されると親クラスのstate.counterが加算されるため、子クラスのthis.props.counterも表示が変わる return ( <div onClick={this.props.onClickHandler}>{this.props.counter}</div> ); } }); render( <Parent />, $('#content')[0] );
フロントエンド初心者がReactによるSPAを構築するに至るメモ
はじめに
最近Javascriptを用いたフロントエンド開発に従事することになり、取り急ぎ敷居が低そうなReactjsに飛びつきました。 jqueryを弄る程度で知識的に止まっていたので、学習は相当ステップを刻むことになってしまいました…
最近ようやくたたき台的なものが書けてきました。 これを一度節目に、私くらいのレベルからReactを始める人のため、バックエンドエンジニアからの理解のため、そして何より自分が忘れないためにここまでの流れを一旦まとめます。
学習の変遷(やってみたこと)
1. Reactチュートリアル
https://facebook.github.io/react/docs/tutorial-ja-JP.html
JSXに触れる
- HTMLが書けるわけではなく、JSXというXML記法を書いていると理解(ココがわからないと多分ずっと気持ち悪い)
- HTMLタグ、属性はシンボル的にXMLで書けるけど、以下の属性は書き換えが必要(予約語だから)
- class → className / for → htmlFor
- 丸括弧でくくる。1ライナーでもくくったほうがいい。(あとでeslint(airbnb style)使うとそうなる)
return <div>ほげほげ</div> ↓ return ( <div>ほげほげ</div> );
- html→jsx変換、こんな便利ツールもある。(簡単なのですぐ要らなくなるが、最初は便利)
state/propsを理解する
- propsはプロパティ、stateが状態を表す。
- 親のstateをsetStateで更新し子のpropsが変更される、というのが基本的なアクション。
- サンプルは以下に用意しました。 tak-taniguchi.hatenablog.com
gulp導入
- jsxの利用で必ずbabelifyが必要になるので、さっさと導入したほうがいい。
- 以下は最低限な感じのgulpfile.jsサンプルです。(watchも導入したほうがいい)
var gulp = require('gulp'); var pkg = require('./package.json'); var browserify = require('browserify'); var babelify = require('babelify'); var source = require('vinyl-source-stream'); gulp.task('js', function() { browserify({ entries: './src/index.jsx', extensions: [".js", ".jsx"], debug: true }) .transform(babelify) .bundle() .pipe(source('bundle.js')) .pipe(gulp.dest('./public/assets/js/')); }); gulp.task('default', ['js']);
2. ES6で書き直してみる
参考にしたサイト
- こちらのサイトがまさにそれをおこなっていて、非常に参考になりました。
eslint
- eslintを導入しコードを機械的にチェックさせる。
- コーディングに安心感が出る。ソロ開発は検証者がいないので、変な書き方にきづけるよう入れておくと吉。
- わたしはVisualStudioCode(VSC)で開発を行っています。フリーな上、非常に使いやすいです。
- VSC + eslint
- VisualStudioCode
- eslintプラグイン(VSC内から追加)
- eslintrc.json / .eslintignore ファイルの作成
- jsを書いているディレクトリ下にて
eslint --init
を実行するとeslintrcが作られます。 - .eslintignoreは対象にしたくないファイル(gulpfile.jsなど)を記載できます。
- わたしの設定も晒しておきます。
- jsを書いているディレクトリ下にて
{ "env": { // (windowなど)特定のグローバル変数を許可したりします "browser": true, "node": true }, "extends": "airbnb", // React界隈ではairbnbのコードスタイルがわりとメジャーのようです "plugins": [ "react", "jsx-a11y", "import" ] }
ファイル構成の見直し、クラス分割
- クラス単位でのファイル分割
─src └jsx └components └Main.jsx // components/Mainと呼びだす └Todos └index.jsx // components/Todosと呼びだす └List.jsx // Todosページの構成要素 └Detail.jsx // Todosページの構成要素
─src └jsx └components └shared └Header.jsx └Footer.jsx
3. ルーティングの考慮
React Routerの導入
import React from 'react'; import { render } from 'react-dom'; import { Router, Route, IndexRoute, useRouterHistory } from 'react-router'; import { createHashHistory } from 'history'; import NotFound from './Components/Error/NotFound'; import Main from './Components/Main'; import Todos from './Components/Todos'; import TodosSummary from './Components/Todos/Summary'; const appHistory = useRouterHistory(createHashHistory)({ queryKey: false }); render(( <Router history={appHistory}> <Route path="Todos"> <IndexRoute name="Todos" component={Todos} /> <Route name="TodosSummary" path="summary" component={TodosSummary} /> </Route> <Route name="Main" path="/" component={Main} /> <Route name="NotFound" path="*" component={NotFound} /> </Router> ), document.getElementById('app'));
- 呼び出すjsxクラスを切り替え、ルーティングのような事ができる。
- 上記の場合はハッシュURLでのルーティングになる。(http://example.com/#/todos/summary/)
- ハッシュを利用しないこともできる。(http://example.com/todos/summary/)
- appHistory → browserHistory に置き換える。
- 当然、アプリケーション・サーバー等でルーティングをindexに向ける等の作業が必要。
利用した書籍
入門 React ―コンポーネントベースのWebフロントエンド開発
- 作者: Frankie Bagnardi,Jonathan Beebe,Richard Feldman,Tom Hallett,Simon HØjberg,Karl Mikkelsen,宮崎空
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/04/03
- メディア: 大型本
- この商品を含むブログ (2件) を見る
ここまでで感じているReact私見(長短)
- 良いと思ったところ
- 仮想DOMの安心感
- Viewに特化したわかりやすい処理系統
- JSXでテンプレートエンジン不要
- Flux、Redux、React Routerなどと柔軟に連携
- 問題を感じているところ
- デザイナーとの連携(テンプレートとロジックが近すぎるため)
- 連携が柔軟である上でのModel、Controllerの選定リスク(Redux衰退したらどうしようとか)
- テンプレートを内包していて容量的に重い
ひとまず締めくくります
わたしも絶賛勉強中ではありますが、上記の工程を積んでReactjsが使えるようになってきました。 次はReduxの導入・実装をおこなっていこうと思っています。
Ruby on Railsにおけるfrontend開発基盤を考えるメモ
概要
- Ruby on Railsにおけるフロントエンド開発にて、現段階(2016年7月時点)で必要そうな技術ベース、開発規約を調査しています。
- 唯一の方法策定ではなく、できるだけ多くの技術について俯瞰的に差異を調査します。
具体的な検討領域
フロントエンドと大分しましたが、具体的には以下のファイルが生成できればOKです。
- html(≒テンプレートエンジン)
- css
- javascript
- 上記を生成するための開発環境・タスクランナー
検討内容
html
テンプレートエンジン
- ERB
- Haml
- Slim
tilt
GitHub - rtomayko/tilt: Generic interface to multiple Ruby template engines
複数のテンプレートエンジンに対してController側が同一コーディングできるようにしてくれるWrapperのようです。
CSS
フレームワーク
レスポンシブデザインを簡単に導入できるが、後述のマークアップ作法に抵触するので利用検討要。
- Bootstrap
- Foundation
- Skeleton
メタ言語
- less / sass
マークアップ作法
- OOCSS / SMACSS / BEM
- CSSの構造化
- 参照記事
Javascript
シンタックスシュガー
- CoffeeScript
- TypeScript
フレームワーク
- Angular
- React
- Aurelia
- Vue.js
タスクランナー
AssetPipelineの要否
Railsが標準で実装しているSprocketsを利用するか否かという問題があります。 こちらを利用する最大のメリットはAssetPipelineによる静的ビルドかと思いますが、ファイル構成の作法のため他のフレームワークの実装がしづらい、または特性を活かしきれない可能性があります。
Sprocketsと決別し、gulpなどに置き換える方法も紹介されていました。
メジャーツール
- gulp
- Grunt
その他、参照記事
rubyのメソッド引数が値渡しという話
Rubyを書き始めてまだ2〜3週間ですが、メソッドで思わぬ挙動があったので記録しておきます。
挙動が想定外だった
def test_add(arr) arr += [1] puts 'B=' + arr.to_s end def test_push(arr) arr.push(1) puts 'D=' + arr.to_s end arr = [0, 2] puts 'A=' + arr.to_s test_add(arr) puts 'C=' + arr.to_s test_push(arr) puts 'E=' + arr.to_s # => A=[0, 2] # => B=[0, 2, 1] # => C=[0, 2] # => D=[0, 2, 1] # => E=[0, 2, 1] ※想定外
おや?っと思ったのはEなのですが、メソッド外でarrにtest_push()処理値が反映されていました。 Rubyのメソッドは「すべて値渡し」というふうに記憶していたからです。
オブジェクトIDによる確認
Rubyはすべての値がオブジェクトなので、オブジェクトIDを確認することにしました。
def test_add(arr) arr += [1] puts 'B=' + arr.object_id.to_s end def test_push(arr) arr.push(1) puts 'D=' + arr.object_id.to_s end arr = [0, 2] puts 'A=' + arr.object_id.to_s test_add(arr) puts 'C=' + arr.object_id.to_s test_push(arr) puts 'E=' + arr.object_id.to_s # => A=69943959716760 # => B=69943959716500 ※これだけ異なる # => C=69943959716760 # => D=69943959716760 # => E=69943959716760
値渡しと言いながら、メソッド内外で利用されているオブジェクトIDが同じでした。 一点興味深かったのがarr += [1]をおこなったタイミングで新規オブジェクトが作成されている点です。
Rubyのメソッド引数はオブジェクトIDを値渡ししている
見出しの通り解釈することにしました。 そもそも参照渡しという解釈はメモリ上のポインタの話をした際に出てくるものなので、そこと混同すると参照渡しじゃないのか、という話になってくるのかと思いました。
オブジェクトをコピーして操作する
こう書けば想定通りでした。
def test_add(arr) arr += [1] puts 'B=' + arr.to_s end def test_push(arr) arr = arr.dup.push(1) puts 'D=' + arr.to_s end arr = [0, 2] puts 'A=' + arr.to_s test_add(arr) puts 'C=' + arr.to_s test_push(arr) puts 'E=' + arr.to_s # => A=[0, 2] # => B=[0, 2, 1] # => C=[0, 2] # => D=[0, 2, 1] # => E=[0, 2] ※想定どおり
フロントエンド環境構築(node/nvm/npm/gulp)
以前のプロジェクトでgulpを利用していたのに、フロントエンド担当ではなかったため環境構築に携われませんでした。 正直よくわからないで使っていたので、自分で構築して何をやっていたのか考えてみます。 今回は「ドットインストール」を教材に習ったもののメモになります。
dotinstall.com ↑なので、普通にこっちをやったほうがいい。
やりたいこと
環境(ちょっとアレンジしています)
- ubuntu(v14.04.4)
- node(v5.12.0)
- nvm(v0.31.2)※nodeのバージョン管理
- npm(v3.8.6)※nodeのパッケージ管理(gulpもパッケージのひとつ)
nodeバージョンについて
- 現時点で最新はv6.2.2だったがパッケージ対応が追いついていないものもあり、v5系で最新のバージョンを選択しました。
- ちなみに、LTS(Long-Term Support)とstableについてもぶつかったのですが、こちらに説明がありました。
インストール
- nvmを利用してnode/npmをインストール
$ git clone git://github.com/creationix/nvm.git ~/.nvm $ echo 'if [[ -s ~/.nvm/nvm.sh ]] ; then source ~/.nvm/nvm.sh ; fi' >> ~/.bashrc $ source ~/.bashrc $ nvm --version 0.31.2 $ nvm ls-remote : // 利用可能なバージョンが羅列される $ nvm install v5.12.0 $ nvm use v5.12.0 Now using node v5.12.0 (npm v3.8.6) $ nvm alias default v5.12.0 default -> v5.12.0 $ node -v v5.12.0 $ npm -v 3.8.6
プロジェクト作成
$ mkdir project project $ cd project project $ npm init : // 以下、エンターでOK(package.jsonが作成される) project $ npm install --save-dev gulp project $ touch gulpfile.js // あとでgulp実行内容を書く
- こんなファイル構成になりました。
project/ |-- node_modules/ | | : | |-- gulp/ | |-- gulpfile.js |-- package.json
タスクランナー(gulp)の実装
- gulpfile.js
// src -> dist var gulp = require('gulp'); var pkg = require('./package.json'); var imagemin = require('gulp-imagemin'); var coffee = require('gulp-coffee'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var plumber = require('gulp-plumber'); var header = require('gulp-header'); var webserver = require('gulp-webserver'); // htmlファイルコピー gulp.task('html', function() { gulp.src('./src/index.html') .pipe(gulp.dest('./dist')); // htmlコピー }); // 画像ファイルコピー gulp.task('img', function() { gulp.src('./src/img/*.jpg') .pipe(imagemin()) // 画像圧縮 .pipe(gulp.dest('./dist/img')); // 画像コピー }); // JS作成 gulp.task('js', function() { gulp.src('./src/coffee/*.coffee') .pipe(plumber()) .pipe(coffee()) // JS変換 .pipe(concat('all.min.js')) // JS結合 .pipe(uglify()) // JS圧縮 .pipe(header('/* copyright <%= pkg.name %> */', {pkg: pkg})) // ヘッダー .pipe(gulp.dest('./dist/js')); }); // watch gulp.task('watch', function() { gulp.watch('./src/coffee/*.coffee', ['js']) gulp.watch('./src/*.html', ['html']) }); // webserver reload gulp.task('webserver', function() { gulp.src('./dist') .pipe( webserver({ host: '192.168.33.10', livereload: true }) ); }); gulp.task('default', ['html', 'img', 'js', 'watch', 'webserver']);
タスクランナーの実行
$ gulp
- 上記gulpfile.jsで実行される内容
画像ファイル名の難読化や、sassコンパイルなども同じ要領で追加していけると思います。 ざっくり何をやっているのか、どのようにやっているのかがわかりました。