Material-UI使ってみた作業ログです。
目標は表題の組み合わせでエラー発生させずにMaterial-UIのコンポーネントを設置することです。
環境作成
最近、環境は全部VirtualBox上に作っています。
ホストに作ってしまうと、しばらく使わない言語とか何入れてたっけ?となったり依存関係壊れてたりいろいろ面倒なのですが、VM上だと壊し放題なのが嬉しい。
参考サイト:
(というかほとんどそのままいただいたので、解説も読みたい場合はリンク先をおすすめ)
Vagrant+node.js+express4+MongoDBで簡単なWebアプリを構築
※以下VirtualBoxとVagrantのインストール済の前提。
OSインストール
環境を作成するディレクトリに移動したら
$ vagrant init
でVagrantfileを作り、以下設定。
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
config.vm.box = "puphpet/centos65-x64"
config.vm.hostname = "node.local"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.synced_folder "localのworkspace", "/var/www/html"
end
仮想環境を立ち上げる。
(プラグインでhostsの書き換えを自動化するとかなり便利)
$ vagrant plugin install vagrant-hostsupdater
$ vagrant up
各種インストール
nodeの設定
$ vagrant ssh
$ curl -L git.io/nodebrew | perl - setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ nodebrew install-binary v5.10.1
$ nodebrew use v5.10.1
node -vと打って、v5.10.1が表示されたら完了。
nginxを設定
$ sudo yum install -y nginx
$ sudo service nginx start
$ sudo chkconfig nginx on
$ sudo vi /etc/nginx/conf.d/virtual.conf
virtual.confは以下のように設定。
server {
listen 80;
server_name node.local;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
ここまででとりあえずの設定は終了なので、(ついでにmongoDBとかも入れた上で)Box化しておくと便利。
Material-UIを使ってみる
React+Redux+Expressな環境を作る
参考サイト:
サイト2のgithubのからソースをそのまま頂戴しました。
めちゃくちゃ助かりました。。
$ cd /var/www/html
で作業ディレクトリに移動してreact-router-reduxブランチのソースを落とします。
そのままnpm installすると落ちるので以下の作業を実施。
$ npm install -g rimraf
$ npm install isomorphic-fetch
Vagrantfileに設定したlocalのworkspaceに移動して、app/routes.jsxを以下のように修正。
// import Route from 'react-router';
import { Route } from 'react-router';
※以下のエラーに悩まされたときの解決策として、こちらで発見しました。
Warning: React.createElement: type sh
ould not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).
Material-UIを追加
node_module追加
package.jsonに以下を追加します。
"dependencies": {
"material-ui": "^0.14.4",
"react-tap-event-plugin": "^0.2.0",
"inline-style-prefixer": "^1.0.3",
※最初material-uiのバージョン0.13.4を入れてDatePickerを使うと以下のエラーが出たので検索したところ、バージョン固有の問題っぽかったので最新バージョンに上げた。
Invalid prop onDismiss
of type boolean
supplied to Dialog
, expected function
. Check the render method of DatePickerDialog
作業完了したら、
$ npm install
でnode_moduleを追加・build
$ npm start
http://node.local/
にアクセス。無事表示されたら環境設定は完了。
Material-UIを使う
ReduxとかReactについては追々ちゃんと勉強することにして、とりあえずMaterial-UIを動かす。
ディレクトリ構造をちょっと変更してimportのパスも変えておく。
/app
├── components
├── MainSection.jsx・・追加
└── Header.jsx ・・追加
├── containers
├── App.jsx・・移動
├── Items.jsx・・移動
├── Users.jsx・・移動
└── Material.jsx ・・追加
└── reducer
以下、追加変更内容。
import React from 'react';
import { Route } from 'react-router';
import App from './containers/App';
import Items from './containers/Items';
import Users from './containers/Users';
import Material from './containers/Material';
export default (
<Route path="/" component={App}>
<Route path="items" component={Items} />
<Route path="users" component={Users} />
<Route path="material" component={Material} />
</Route>
);
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import Header from '../components/Header';
import MainSection from '../components/MainSection';
class Material extends Component {
static propTypes = {
onDismiss: React.PropTypes.func,
};
render() {
return (
<div>
<Header />
<MainSection />
</div>
);
}
}
export default Material;
import React, { PropTypes, Component } from 'react';
import mui, {AppBar} from 'material-ui';
import themeDecorator from 'material-ui/lib/styles/theme-decorator';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
class Header extends Component {
render() {
return (
<header className="header">
<h1>AppBar Component</h1>
<AppBar title="React + Redux + Material UI Boilerplate" />
</header>
);
}
}
export default themeDecorator(getMuiTheme(null, { userAgent: 'all' }))(Header);
import React, { Component, PropTypes } from 'react';
import mui, {CircularProgress,
Tabs,
Tab,
DatePicker
} from 'material-ui';
import themeDecorator from 'material-ui/lib/styles/theme-decorator';
import getMuiTheme from 'material-ui/lib/styles/getMuiTheme';
class MainSection extends Component {
render() {
return (
<div>
<h1>Progress Component</h1>
<CircularProgress mode="indeterminate" size={1.5} />
<CircularProgress mode="indeterminate" color={"red"} size={2} />
<br/>
<h1>Tab Component</h1>
<Tabs>
<Tab label="Tab One" value="0" />
<Tab label="Tab Two" value="1" />
<Tab label="Tab Three" value="2" />
</Tabs>
<br/>
<h1>DatePicker Component</h1>
<DatePicker hintText="Portrait Dialog" />
<br/>
</div>
);
}
}
export default themeDecorator(getMuiTheme(null, { userAgent: 'all' }))(MainSection);
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router'
import configureStore from './configureStore';
import routes from './routes'
import injectTapEventPlugin from "react-tap-event-plugin";
const store = configureStore(window.APP_STATE);
//Needed for React Developer Tools
window.React = React;
//Needed for onTouchTap
//Can go away when react 1.0 release
//Check this repo:
//https://github.com/zilverline/react-tap-event-plugin
injectTapEventPlugin();
ReactDOM.render(
<Provider store={store}>
<Router history={browserHistory}>
{routes}
</Router>
</Provider>,
document.getElementById('app'))
以下のエラーがなかなか消えなくて苦労したのですが、{ userAgent: 'all' }を入れることでとりあえず解消されました。
warning.js:45 Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) th:100%;display:flex;min-height:64px;pad
(server) th:100%;display:flex,-webkit-flex,-ms-fl
おわりに
まだ何にも分かっていないけどスタートラインにはぎりぎり立てたので、いろいろ作りながら探っていきたいと思います。
とりあえずで以下は勉強しなきゃ。。
追記
React+Redux+Material-UI、その後勉強しました。
この記事描いたころ何も理解していなかったなあと反省しきりです。。
罪滅ぼしに検索画面を作る入門記事とか書いたので、よかったら以下どうぞです。