Explorar el Código

Prepare ES6 migration

fecaille hace 9 años
padre
commit
74cc6e5b3a

+ 3 - 0
.eslintrc

@@ -0,0 +1,3 @@
+{
+  "extends": "airbnb"
+}

+ 10 - 4
package.json

@@ -2,7 +2,7 @@
   "name": "springboot-react-webpack-demo",
   "version": "1.0.0",
   "dependencies": {
-  	"bootstrap": "^3.3.6",
+    "bootstrap": "^3.3.6",
     "jquery": "^2.2.2",
     "marked": "^0.3.5",
     "react": "^0.14.7",
@@ -10,10 +10,15 @@
   },
   "devDependencies": {
     "babel-core": "^6.7.4",
+    "babel-eslint": "^6.0.2",
     "babel-loader": "^6.2.4",
     "babel-preset-es2015": "^6.6.0",
     "babel-preset-react": "^6.5.0",
     "css-loader": "^0.23.1",
+    "eslint": "^2.5.3",
+    "eslint-config-airbnb": "^6.2.0",
+    "eslint-loader": "^1.3.0",
+    "eslint-plugin-react": "^4.2.3",
     "extract-text-webpack-plugin": "^1.0.1",
     "file-loader": "^0.8.5",
     "html-loader": "^0.4.3",
@@ -27,8 +32,9 @@
     "webpack-dev-server": "^1.14.1"
   },
   "scripts": {
-  	"watch": "NODE_ENV=development webpack-dev-server --hot --inline",
-  	"dev-build": "NODE_ENV=development webpack --d --progress --colors",
-  	"prod-build": "webpack -d -p --colors"
+    "dev-build": "NODE_ENV=development webpack --d --progress --colors",
+    "lint": "eslint --ignore-pattern **/nashorn-*.js --ext .js,.jsx src/main/resources/static/js/**",
+    "prod-build": "webpack -d -p --colors",
+    "watch": "NODE_ENV=development webpack-dev-server --hot --inline"
   }
 }

+ 0 - 135
src/main/resources/static/js/app.jsx

@@ -1,135 +0,0 @@
-'use strict';
-
-var React		= require('react'),
-	marked		= require('marked'),
-	$			= require('jquery');
-
-var Comment = React.createClass({
-	rawMarkup: function() {
-		var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
-		return { __html: rawMarkup };
-	},
-	render: function() {
-		return (
-			<div className="comment">
-				<h2 className="commentAuthor">
-					{this.props.author}
-				</h2>
-				<span dangerouslySetInnerHTML={this.rawMarkup()} />
-			</div>
-		);
-	}
-});
-
-var CommentForm = React.createClass({
-	getInitialState: function() {
-		return {author: '', text: ''};
-	},
-	handleAuthorChange: function(e) {
-		this.setState({author: e.target.value});
-	},
-	handleTextChange: function(e) {
-		this.setState({text: e.target.value});
-	},
-	handleSubmit: function(e) {
-		e.preventDefault();
-		var author = this.state.author.trim();
-		var text = this.state.text.trim();
-		if( !text || !author ) {
-			return;
-		}
-		this.props.onCommentSubmit({author: author, text: text})
-		this.setState({author: '', text: ''});
-	},
-	render: function() {
-		return (
-			<form className="commentForm" onSubmit={this.handleSubmit}>
-				<input
-					type="text"
-					placeholder="Your name"
-					value={this.state.author}
-					onChange={this.handleAuthorChange}
-				/>
-				<input
-					type="text"
-					placeholder="Say something..."
-					value={this.state.text}
-					onChange={this.handleTextChange}
-				/>
-				<input type="submit" value="Post" />
-			</form>
-		);
-	}
-});
-
-var CommentBox = React.createClass({
-	getInitialState: function() {
-		return {data: this.props.data || []};
-	},
-	loadCommentsFromServer: function() {
-		$.ajax({
-			url: this.props.url,
-			dataType: 'json',
-			cache: false,
-			success: function(data) {
-				this.setState({data: data});
-			}.bind(this),
-			error: function(xhr, status, err) {
-				console.error(this.props.url, status, err.toString());
-			}.bind(this)
-		});
-	},
-	handleCommentSubmit: function(comment) {
-		var comments = this.state.data;
-		comment.id = Date.now();
-		var newComments = comments.concat([comment]);
-		this.setState({data: newComments});
-		$.ajax({
-			url: this.props.url,
-			method: 'POST',
-			dataType: 'json',
-			data: comment,
-			success: function(data) {
-				this.setState({data: data});
-			}.bind(this),
-			error: function(xhr, status, err) {
-				this.setState({data: comments});
-				console.error(this.props.url, status, err.toString());
-			}.bind(this)
-		});
-	},
-	componentDidMount: function() {
-		this.loadCommentsFromServer();
-		setInterval(this.loadCommentsFromServer, this.props.pollInterval);
-	},
-	render: function() {
-		return (
-			<div className="commentBox">
-				<h1>Comments</h1>
-				<CommentList data={this.state.data}/>
-				<CommentForm onCommentSubmit={this.handleCommentSubmit}/>
-			</div>
-		);
-	}
-});
-var CommentList = React.createClass({
-	render: function() {
-		var commentNodes = this.props.data.map( function(comment) {
-			return (
-				<Comment author={comment.author} key={comment.id}>{comment.text}</Comment>
-			);
-		});
-		return (
-			<div className="commentList">
-				{commentNodes}
-			</div>
-		)
-	}
-});
-
-module.exports = {
-	CommentBox: CommentBox,
-	CommentList: CommentList,
-	CommentForm: CommentForm,
-	Comment: Comment
-};

+ 18 - 23
src/main/resources/static/js/app.render.jsx

@@ -1,32 +1,27 @@
-"use strict";
-
-
 import React from 'react';
 import ReactDOM from 'react-dom';
 import ReactDOMServer from 'react-dom/server';
-import App from './app.jsx';
-import $ from 'jquery';
-
+import CommentBox from './comment_box.jsx';
 
-require('bootstrap/dist/css/bootstrap.css');
-require('../css/comments.css');
-require('../css/comments.less');
+import 'bootstrap/dist/css/bootstrap.css';
+import '../css/comments.css';
+import '../css/comments.less';
 
-global.renderClient = function (comments) {
-    var data = comments || [];
-    ReactDOM.render(
-		<App.CommentBox data={data} url="/api/comments" pollInterval={2000}/>,
-		document.getElementById('content')
-	);
+global.renderClient = function renderClient(comments) {
+  const data = comments || [];
+  ReactDOM.render(
+	<CommentBox data={data} url="/api/comments" pollInterval={2000} />,
+	document.getElementById('content')
+  );
 };
 
-global.renderServer = function (comments) {
-    var data = Java.from(comments);
-    return ReactDOMServer.renderToString(
-    	<App.CommentBox data={data} url="/api/comments" pollInterval={2000} />
-    );
+global.renderServer = function renderServer(comments) {
+  const data = Java.from(comments);
+  return ReactDOMServer.renderToString(
+	<CommentBox data={data} url="/api/comments" pollInterval={2000} />
+  );
 };
 
-if( !global.nashorn ) {
-	renderClient(initialData);
-};
+if (!global.nashorn) {
+  global.renderClient(global.initialData);
+}

+ 23 - 0
src/main/resources/static/js/comment.jsx

@@ -0,0 +1,23 @@
+import React from 'react';
+import marked from 'marked';
+
+class Comment extends React.Component {
+  rawMarkup() {
+    const rawMarkup = marked(this.props.children.toString(), { sanitize: true });
+    return { __html: rawMarkup };
+  }
+  render() {
+    return (
+      <div className="comment">
+        <h2 className="commentAuthor">
+          {this.props.author}
+        </h2>
+        <span dangerouslySetInnerHTML={this.rawMarkup()} />
+      </div>
+    );
+  }
+}
+Comment.propTypes = {
+  author: React.PropTypes.string,
+  children: React.PropTypes.node,
+};

+ 65 - 0
src/main/resources/static/js/comment_box.jsx

@@ -0,0 +1,65 @@
+import React from 'react';
+import $ from 'jquery';
+import CommentForm from './comment_form.jsx';
+import CommentList from './comment_list.jsx';
+
+class CommentBox extends React.Component {
+  componentDidMount() {
+    this.loadCommentsFromServer();
+    setInterval(this.loadCommentsFromServer, this.props.pollInterval);
+  }
+  getInitialStatefunction() {
+    return { data: this.props.data || [] };
+  }
+  loadCommentsFromServer() {
+    $.ajax({
+      url: this.props.url,
+      dataType: 'json',
+      cache: false,
+      success: function success(data) {
+        this.setState({ data });
+      }.bind(this),
+      error: function error(xhr, status, err) {
+        console.error(this.props.url, status, err.toString());
+      }.bind(this),
+    });
+  }
+  handleCommentSubmit(comment) {
+    const comments = this.state.data;
+    const copy = comment;
+    copy.id = Date.now();
+    const newComments = comments.concat([copy]);
+    this.setState({ data: newComments });
+    $.ajax({
+      url: this.props.url,
+      method: 'POST',
+      dataType: 'json',
+      data: comment,
+      success: function success(data) {
+        this.setState({ data });
+      }.bind(this),
+      error: function error(xhr, status, err) {
+        this.setState({ data: comments });
+        console.error(this.props.url, status, err.toString());
+      }.bind(this),
+    });
+  }
+  render() {
+    return (
+      <div className="commentBox">
+        <h1>Comments</h1>
+        <CommentList data={this.state.data} />
+        <CommentForm onCommentSubmit={this.handleCommentSubmit} />
+      </div>
+    );
+  }
+}
+CommentBox.propTypes = {
+  data: React.PropTypes.shape({
+    id: React.PropTypes.number,
+    author: React.PropTypes.string,
+    text: React.PropTypes.string,
+  }),
+  pollInterval: React.PropTypes.numbe,
+  url: React.PropTypes.string,
+};

+ 47 - 0
src/main/resources/static/js/comment_form.jsx

@@ -0,0 +1,47 @@
+import React from 'react';
+
+class CommentForm extends React.Component {
+  getInitialState() {
+    return { author: '', text: '' };
+  }
+  handleAuthorChange(e) {
+    this.setState({ author: e.target.value });
+  }
+  handleTextChange(e) {
+    this.setState({ text: e.target.value });
+  }
+  handleSubmit(e) {
+    e.preventDefault();
+    const author = this.state.author.trim();
+    const text = this.state.text.trim();
+    if (!text || !author) {
+      return;
+    }
+    this.props.onCommentSubmit({ author, text });
+    this.setState({ author: '', text: '' });
+  }
+  render() {
+    return (
+      <form className="commentForm" onSubmit={this.handleSubmit}>
+        <input
+          type="text"
+          placeholder="Your name"
+          value={this.state.author}
+          onChange={this.handleAuthorChange}
+        />
+        <input
+          type="text"
+          placeholder="Say something..."
+          value={this.state.text}
+          onChange={this.handleTextChange}
+        />
+        <input type="submit" value="Post" />
+      </form>
+    );
+  }
+}
+CommentForm.propTypes = {
+  author: React.PropTypes.string,
+  text: React.PropTypes.string,
+  onCommentSubmit: React.PropTypes.func,
+};

+ 4 - 6
src/main/resources/static/js/vendors.js

@@ -1,7 +1,5 @@
-"use strict";
+import 'react';
+import 'react-dom';
+import 'jquery';
 
-require('react');
-require('react-dom');
-require('jquery');
-
-require('bootstrap/dist/css/bootstrap.css');
+import 'bootstrap/dist/css/bootstrap.css';

+ 8 - 1
webpack.config.js

@@ -39,6 +39,13 @@ var config = {
         publicPath: 'http://localhost:' + dev_port + '/'
     },
     module: {
+    	preLoaders: [
+			{
+				test: /\.jsx$|\.js$/,
+				loader: 'eslint-loader',
+				include: __dirname + '/src/main/resources/static/js'
+			}
+       ],
         loaders: [
 			{
 			    test: /\.jsx?$/,
@@ -83,7 +90,7 @@ var config = {
         return [];
     },
     htmlLoader: {
-    	removeAttributeQuotes: false,
+    	removeAttributeQuotes: false
     }
 };