From b3ef50406548fdd2aa4c9bb05c00cca6d9b49e3e Mon Sep 17 00:00:00 2001 From: junichiro_kazama Date: Fri, 10 Feb 2017 11:39:44 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BE=9D=E5=AD=98=E3=83=A9=E3=82=A4=E3=83=96?= =?UTF-8?q?=E3=83=A9=E3=83=AA=E3=81=AE=E6=9B=B4=E6=96=B0=20fix=20#20=20fix?= =?UTF-8?q?=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 +++++------ gulpfile.babel.js | 39 ++++++------ package.json | 89 ++++++++++++++------------- source/html/{index.jade => index.pug} | 4 +- source/js/app.js | 6 +- source/js/main.js | 9 +-- source/js/platform/react-flux.js | 1 + source/js/platform/react-ui.js | 2 +- source/js/platform/react.js | 16 +++-- source/js/routes.js | 19 +++--- 10 files changed, 109 insertions(+), 113 deletions(-) rename source/html/{index.jade => index.pug} (76%) diff --git a/README.md b/README.md index 49dfe6b..ba7650f 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,7 @@ sample-ui-react 1. 「 `npm install -g gulp` 」 を実行して Gulp をインストール。 - Mac ユーザは 「 `sudo npm install -g gulp` 」 で。 1. コンソールで本ディレクトリ直下へ移動後、 「 `npm install` 」 を実行して Gulp ライブラリをインストール。 - - Windows ユーザは 「 npm install --msvs_version=2013 」 。理由は後述 - ---- - -標準で利用想定の [BrowserSync](http://www.browsersync.io/) は LiveReload よりも同期が早く開発生産性に大きく寄与しますが、 Windows ユーザの場合は [Python2.7](https://www.python.org/) と [Visual Studio 2013 Update N](https://www.visualstudio.com/downloads/download-visual-studio-vs) のインストールが必須となります。 -*※ `Express 2013 for Desktop` を推奨します。 ( 手元で試したところ `Community 2015` では正しく動きませんでした ) * + - node-sass あたりでビルドに失敗した場合は、 「 `npm uninstall node-sass` 」 を実行してから再度試してみてください。 ### 動作確認 @@ -33,17 +28,15 @@ sample-ui-react - application.yml の `extension.security.auth.enabled` を true にして起動すればログイン機能の確認も可能 1. コンソールで本ディレクトリ直下へ移動し、 「 `gulp` 」 を実行 - 確認用のブラウザが自動的に起動する。うまく起動しなかったときは 「 http://localhost:3000 」 へアクセス - - 画面が白く表示されてしまう時はブラウザの更新を押してみてください - - webpack のビルドが間に合っていない可能性が高いため ### 開発の流れ -基本的にテンプレート ( .jade / .scss / .js ( ES6 ) ) を Web リソース ( .html / .css / .js ) へ Gulp / Webpack でリアルタイム変換させながら開発をしていきます。 +基本的にテンプレート ( .pug / .scss / .js ( ES6 ) ) を Web リソース ( .html / .css / .js ) へ Gulp / Webpack でリアルタイム変換させながら開発をしていきます。 動作確認は Gulp で独自に Web サーバを立ち上げた後、ブラウザ上で行います。 #### 各種テンプレートファイルの解説 -- [Jade](http://jade-lang.com/) +- [Pug](https://github.com/pugjs/pug) - HTML を生成するテンプレートツール。公式サイト TOP にある簡素な記法が特徴。 - [Sass (SCSS)](http://sass-lang.com/) - CSS 表記を拡張するツール。変数や mixin 、ネスト表記などが利用可能。 @@ -88,8 +81,8 @@ public … deploy resources (auto generate) - style.css … from source/css fonts … icon font js - - bundler.js … from source/js (by Webpack) - - vendor.js … from vendor dist resource + - bundle.js … from source/js (by Webpack) + - vendor.bundle.js … from vendor dist resource index.html … from source/html source css … css template files [SCSS] @@ -117,18 +110,18 @@ source | ライブラリ | バージョン | 用途/追加理由 | | ----------------------- | -------- | ------------- | -| `superagent` | 1.7.+ | HTTP 連携ライブラリ | -| `react`               | 0.14.+ | アプリケーションの UI 機能を提供 | -| `react-dom`           | 0.14.+ | アプリケーションの UI 機能 ( DOM ) を提供 | -| `react-router` | 0.13.+ | React.js の SPA ルーティングサポート | +| `superagent` | 2.3.+ | HTTP 連携ライブラリ | +| `react`          | 15.4.+ | アプリケーションの UI 機能を提供 | +| `react-dom`        | 15.4.+ | アプリケーションの UI 機能 ( DOM ) を提供 | +| `react-router` | 3.0.+ | React.js の SPA ルーティングサポート | | `react-mixin` | 3.0.+ | Reactクラス利用時のMixin拡張 | -| `wolfy87-eventemitter` | 4.3.+ | イベント連携ライブラリ | -| `flux` | 2.1.+ | Facebook Flux ライブラリ | -| `lodash`              | 4.6.+ | 汎用ユーティリティライブラリ | -| `dateformat`          | 1.0.+ | 日時ライブラリ | -| `jquery` | 2.2.+ | DOM 操作サポート | +| `wolfy87-eventemitter` | 5.1.+ | イベント連携ライブラリ | +| `flux` | 3.1.+ | Facebook Flux ライブラリ | +| `lodash`          | 4.17.+ | 汎用ユーティリティライブラリ | +| `dateformat`       | 2.0.+ | 日時ライブラリ | +| `jquery` | 3.1.+ | DOM 操作サポート | | `bootstrap-sass` | 3.3.+ | CSS フレームワーク | -| `fontawesome` | 4.5.+ | フォントアイコンライブラリ | +| `fontawesome` | 4.6.+ | フォントアイコンライブラリ | ### License diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 94f0104..8bc1cba 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -24,7 +24,7 @@ const paths = { } const resource = { src: { - jade: `${paths.src.html}/**/*.jade`, + pug: `${paths.src.html}/**/*.pug`, webpack: { babel: `${paths.src.js}/**/*.(js|jsx)` }, @@ -32,11 +32,7 @@ const resource = { static: `${paths.src.static}/**/*` }, vendor: { - js: { - jquery: `${paths.node.modules}/jquery/dist/jquery.js`, - bootstrap: `${paths.node.modules}/bootstrap-sass/assets/javascripts/bootstrap.js`, - eventemitter: `${paths.node.modules}/wolfy87-eventemitter/EventEmitter.js` - }, + js: ['jquery', 'lodash', 'dateformat', "wolfy87-eventemitter", 'react', 'react-dom', "react-router", 'bootstrap-sass'], fontawesome: `${paths.node.modules}/font-awesome/fonts/**/*` } } @@ -61,7 +57,7 @@ gulp.task('default', ['build', 'server']) //## build for developer gulp.task('build', (callback) => - runSequence('clean', ['build:jade', 'build:sass', 'build:webpack', 'build:static'], callback) + runSequence('clean', ['build:pug', 'build:sass', 'build:webpack', 'build:static'], callback) ) //## build production @@ -85,13 +81,21 @@ gulp.task('revision', (callback) => // compile Webpack [ ES6(Babel) / Vue -> SPA(main.js) ] gulp.task('build:webpack', () => { process.env.NODE_ENV = (production == true) ? 'production' : 'development' - let plugins = [ new webpack.optimize.DedupePlugin() ] - if (production) plugins.push(new webpack.optimize.UglifyJsPlugin({compress: { warnings: false }})) + let plugins = [ + new webpack.optimize.DedupePlugin(), + new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js"), + new webpack.ProvidePlugin({jQuery: "jquery", $: "jquery"}) + ] + if (production) plugins.push(new webpack.optimize.UglifyJsPlugin({compress: { warnings: false }, sourceMap: false })) return gulp.src(resource.src.webpack.babel) .pipe($.plumber()) .pipe(webpackStream({ - entry: `${paths.src.js}/main.js`, - output: {filename: 'bundler.js'}, + devtool: '#source-map', + entry: { + app: `${paths.src.js}/main.js`, + vendor: resource.vendor.js + }, + output: {filename: 'bundle.js'}, watch: !production, module: { loaders: [ @@ -108,11 +112,11 @@ gulp.task('build:webpack', () => { .pipe(browserSync.stream()) }) -// compile Jade -> HTML -gulp.task('build:jade', () => { - return gulp.src(resource.src.jade) +// compile Pug -> HTML +gulp.task('build:pug', () => { + return gulp.src(resource.src.pug) .pipe($.plumber()) - .pipe($.jade()) + .pipe($.pug()) .pipe($.htmlhint()) .pipe($.htmlhint.reporter()) .pipe(gulp.dest(paths.dist.root)) @@ -132,11 +136,6 @@ gulp.task('build:sass', () => { // copy Static Resource gulp.task('build:static', () => { - const libs = resource.vendor.js - gulp.src(Object.keys(libs).map((key) => libs[key])) - .pipe($.concat("vendor.js")) - .pipe($.if(production, $.uglify())) - .pipe(gulp.dest(paths.dist.js)) gulp.src(resource.vendor.fontawesome) .pipe(gulp.dest(paths.dist.font)) return gulp.src(resource.src.static) diff --git a/package.json b/package.json index c6aee86..8e1548b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sample-ui-react", - "version": "0.2.2", + "version": "0.3.0", "description": "React.js Boilerplate", "main": "source/js/main.js", "scripts": { @@ -13,54 +13,55 @@ "type" : "git", "url" : "https://github.com/jkazama/sample-ui-react.git" }, + "dependencies": { + "bootstrap-sass": "~3.3.0", + "co": "~4.6.0", + "dateformat": "~2.0.0", + "font-awesome": "~4.6.0", + "jquery": "~3.1.0", + "lodash": "~4.17.0", + "superagent": "~2.3.0", + "react": "~15.4.0", + "react-dom": "~15.4.0", + "react-router": "~3.0.0", + "react-mixin": "~3.0.0", + "wolfy87-eventemitter": "~5.1.0", + "flux": "~3.1.0" + }, "devDependencies": { - "gulp": "~3.9.0", - "gulp-load-plugins": "~1.2.0", + "babel-core": "~6.18.0", + "babel-loader": "~6.2.0", + "babel-plugin-transform-runtime": "~6.15.0", + "babel-preset-es2015": "~6.14.0", + "babel-runtime": "~6.18.0", + "browser-sync": "~2.17.0", + "css-loader": "~0.25.0", "del": "~2.2.0", - "run-sequence": "~1.1.5", - "gulp-if": "2.0.0", - "gulp-slash": "1.1.3", - "gulp-order": "1.1.1", - "gulp-changed": "1.3.0", + "gulp": "~3.9.0", + "gulp-changed": "~1.3.0", "gulp-concat": "~2.6.0", - "gulp-plumber": "~1.0.1", - "gulp-jade": "~1.1.0", - "gulp-htmlhint": "~0.3.0", - "gulp-sass": "~2.1.1", - "gulp-pleeease": "~2.0.2", - "gulp-uglify": "~1.5.1", "gulp-cssmin": "~0.1.0", - "gulp-rev-all": "~0.8.22", - "webpack": "~1.12.14", - "webpack-stream": "~3.1.0", + "gulp-htmlhint": "~0.3.0", + "gulp-if": "~2.0.0", + "gulp-load-plugins": "~1.2.0", + "gulp-order": "~1.1.0", + "gulp-pleeease": "~2.0.0", + "gulp-plumber": "~1.1.0", + "gulp-pug": "~3.0.0", + "gulp-rev-all": "~0.8.0", + "gulp-sass": "~2.3.0", + "gulp-slash": "~1.1.0", + "gulp-uglify": "~1.5.0", "html-loader": "~0.4.0", - "template-html-loader": "~0.0.3", - "css-loader": "~0.23.1", + "node-sass": "~3.13.0", + "pug": "~2.0.0-beta6", + "pug-loader": "~2.3.0", + "run-sequence": "~1.2.0", + "sass-loader": "~4.0.0", "style-loader": "~0.13.0", - "sass-loader": "~3.1.2", - "node-sass": "~3.4.2", - "jade-loader": "~0.8.0", - "babel-loader": "~6.2.4", - "babel-core": "~6.9.0", - "babel-runtime": "~6.9.0", - "babel-plugin-transform-runtime": "~6.9.0", - "babel-preset-es2015 ": "~6.9.0", - "babel-preset-react ": "~6.5.0", - "browser-sync": "~2.11.0" - }, - "dependencies": { - "co": "~4.6.0", - "superagent": "~1.7.2", - "react": "~0.14.7", - "react-dom": "~0.14.7", - "react-router": "~0.13.5", - "react-mixin": "~3.0.3", - "wolfy87-eventemitter": "~4.3.0", - "flux": "~2.1.1", - "lodash": "~4.6.0", - "dateformat": "~1.0.12", - "jquery": "~2.2.1", - "bootstrap-sass": "~3.3.6", - "font-awesome": "~4.5.0" + "template-html-loader": "~0.0.3", + "webpack": "~1.13.0", + "webpack-stream": "~3.2.0", + "babel-preset-react ": "~6.22.0" } } diff --git a/source/html/index.jade b/source/html/index.pug similarity index 76% rename from source/html/index.jade rename to source/html/index.pug index 2ad4de3..e9d8dde 100644 --- a/source/html/index.jade +++ b/source/html/index.pug @@ -5,7 +5,7 @@ html(lang="ja") meta(content="IE=edge,chrome=1" http-equiv="X-UA-Compatible") title アプリケーション link(rel="stylesheet" href="/css/style.css") - script(src="/js/vendor.js") + script(src="/js/vendor.bundle.js") body #app - script(src="/js/bundler.js") + script(src="/js/bundle.js") diff --git a/source/js/app.js b/source/js/app.js index df94ea0..4dddcbe 100644 --- a/source/js/app.js +++ b/source/js/app.js @@ -1,17 +1,15 @@ import React from "react" -import Router from "react-router" +import {Router} from "react-router" import {Component} from "platform/react" import Header from "components/header" -const RouteHandler = Router.RouteHandler - export default class App extends Component { render() { return(
- + {this.props.children}
) } diff --git a/source/js/main.js b/source/js/main.js index 83c93a4..d199a3f 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -1,9 +1,10 @@ // for React Routing import React from "react" import ReactDOM from "react-dom" -import Router from "react-router" +import {Router, hashHistory} from "react-router" import Routes from "routes" -Router.run(Routes, function(Handler, state) { - ReactDOM.render(, document.getElementById('app')) -}) +ReactDOM.render( + {Routes}, + document.getElementById('app') +) diff --git a/source/js/platform/react-flux.js b/source/js/platform/react-flux.js index b341322..f903e13 100644 --- a/source/js/platform/react-flux.js +++ b/source/js/platform/react-flux.js @@ -4,6 +4,7 @@ import {Ajax} from "platform/plain" import Dispatcher from "dispatcher/dispatcher" import EventTypes from "constants/event" +import EventEmitter from "wolfy87-eventemitter" // array to object[key: key] export function KeyMirror(arrays) { diff --git a/source/js/platform/react-ui.js b/source/js/platform/react-ui.js index e3ab729..192de1d 100644 --- a/source/js/platform/react-ui.js +++ b/source/js/platform/react-ui.js @@ -81,7 +81,7 @@ export class Text extends Input { let classRow = this.props.row ? 'l-row ' : '' let className = `form-control ${classRow}${this.props.className}` let input = ( - + ) let message = this.error() if (message) { diff --git a/source/js/platform/react.js b/source/js/platform/react.js index ff25bd6..e1a9410 100644 --- a/source/js/platform/react.js +++ b/source/js/platform/react.js @@ -1,6 +1,6 @@ import React from "react" import ReactDOM from "react-dom" -import Router from "react-router" +import {Router, Link, Navigation} from "react-router" import ReactMixin from 'react-mixin' import Param from "variables" @@ -8,8 +8,8 @@ import {Ajax} from "platform/plain" import * as ReactUI from "platform/react-ui" export class Component extends React.Component { - constructor(props) { - super(props) + constructor(props, context) { + super(props, context) let state = { message: {} } @@ -19,11 +19,11 @@ export class Component extends React.Component { this.initialize() } static router() { return Router } - static routerLink() { return this.router().Link } + static routerLink() { return Link } initState() { return {} } initialize() { /* nothing. */ } forward(path) { - this.transitionTo(path) + this.context.router.transitionTo(path) } updateState(data) { if (!this.mounted) return @@ -91,4 +91,8 @@ export class Component extends React.Component { this.mounted = false } } -ReactMixin.onClass(Component, Router.Navigation) +ReactMixin.onClass(Component, Navigation) +Component.contextTypes = { + router: React.PropTypes.object +} + diff --git a/source/js/routes.js b/source/js/routes.js index b2b1ecb..f6a2a2e 100644 --- a/source/js/routes.js +++ b/source/js/routes.js @@ -1,6 +1,5 @@ import React from "react" -import Router from "react-router" -let {Route, DefaultRoute, NotFoundRoute} = Router +import {Router, Route, IndexRoute} from 'react-router'; import App from "app" import Login from "components/login" @@ -11,14 +10,14 @@ import Asset from "components/asset" let Routes = function() { return ( - - - - - - - - + + + + + + + + ) }