Pārlūkot izejas kodu

Feature: using webpack instead of wro

fecaille 9 gadi atpakaļ
vecāks
revīzija
fe4cfcc962

+ 3 - 0
.babelrc

@@ -0,0 +1,3 @@
+{
+  "presets": ["es2015", "react"]
+}

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 .classpath
 .project
 .settings
+node_modules
 src/main/resources/static/js/.module-cache
 src/test/resources/static/js/compiled
 src/test/resources/static/js/.module-cache

+ 31 - 0
package.json

@@ -0,0 +1,31 @@
+{
+  "name": "catalog-ui",
+  "version": "1.0.0",
+  "description": "BFF demo",
+  "dependencies": {
+  	"bootstrap": "^3.3.6",
+    "jquery": "^2.2.2",
+    "marked": "^0.3.5",
+    "react": "^0.14.7",
+    "react-dom": "^0.14.7"
+  },
+  "devDependencies": {
+    "babel-core": "^6.7.4",
+    "babel-loader": "^6.2.4",
+    "babel-preset-es2015": "^6.6.0",
+    "babel-preset-react": "^6.5.0",
+    "css-loader": "^0.23.1",
+    "extract-text-webpack-plugin": "^1.0.1",
+    "file-loader": "^0.8.5",
+    "postcss-loader": "^0.8.2",
+    "style-loader": "^0.13.1",
+    "url-loader": "^0.5.7",
+    "webpack": "^1.12.2",
+    "webpack-dev-server": "^1.14.1"
+  },
+  "scripts": {
+  	"dev": "webpack-dev-server --hot --inline --devtool eval --progress --colors --content-base build --port 9999",
+  	"dev-build": "webpack -d --display-modules",
+    "watch": "webpack --watch -d"
+  }
+}

+ 21 - 151
pom.xml

@@ -24,15 +24,6 @@
 		<maven.deploy.skip>true</maven.deploy.skip>
 		<project.scm.id>jazzhub</project.scm.id>
 		<docker.image.prefix>opensaas</docker.image.prefix>
-
-		<jasmine.version>2.4.1</jasmine.version>
-		<jasmine-ajax.version>3.2.0</jasmine-ajax.version>
-
-		<bootstrap.version>3.3.6</bootstrap.version>
-		<jquery.version>2.2.1</jquery.version>
-		<react.version>0.14.7</react.version>
-		<marked.version>0.3.2-1</marked.version>
-		<marked-lib.version>0.3.2</marked-lib.version>
 	</properties>
 
 	<dependencies>
@@ -57,27 +48,6 @@
 			<artifactId>spring-boot-devtools</artifactId>
 			<optional>true</optional>
 		</dependency>
-		<!-- Webjars -->
-		<dependency>
-			<groupId>org.webjars</groupId>
-			<artifactId>bootstrap</artifactId>
-			<version>${bootstrap.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.webjars</groupId>
-			<artifactId>jquery</artifactId>
-			<version>${jquery.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.webjars</groupId>
-			<artifactId>react</artifactId>
-			<version>${react.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.webjars</groupId>
-			<artifactId>marked</artifactId>
-			<version>${marked.version}</version>
-		</dependency>
 	</dependencies>
 
 	<build>
@@ -89,103 +59,46 @@
 		</resources>
 		<plugins>
 			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
-			<plugin>
-				<groupId>com.fizzed</groupId>
-				<artifactId>fizzed-watcher-maven-plugin</artifactId>
-				<version>1.0.6</version>
+				<groupId>com.github.eirslett</groupId>
+				<artifactId>frontend-maven-plugin</artifactId>
+				<version>0.0.29</version>
 				<configuration>
-					<watches>
-						<watch>
-							<excludes>
-								<exclude>src/main/resources/static/js/bundle</exclude>
-								<exclude>src/main/resources/static/js/jsx</exclude>
-							</excludes>
-							<recursive>false</recursive>
-							<directory>src/main/resources/static/js</directory>
-						</watch>
-						<watch>
-							<exclude>src/main/resources/static/css/bundle</exclude>
-							<recursive>false</recursive>
-							<directory>src/main/resources/static/css</directory>
-						</watch>
-						<watch>
-							<directory>src/main/wro</directory>
-						</watch>
-					</watches>
-					<goals>
-						<goal>process-resources</goal>
-					</goals>
+					<workingDirectory>${project.build.directory}</workingDirectory>
 				</configuration>
-			</plugin>
-			<!-- Resource optimization -->
-			<plugin>
-				<artifactId>maven-resources-plugin</artifactId>
 				<executions>
 					<execution>
-						<!-- Serves *only* to filter the wro.xml so it can get an absolute 
-							path for the project -->
-						<id>copy-resources</id>
-						<phase>validate</phase>
+						<id>install node and npm</id>
 						<goals>
-							<goal>copy-resources</goal>
+							<goal>install-node-and-npm</goal>
 						</goals>
 						<configuration>
-							<outputDirectory>${basedir}/target/wro</outputDirectory>
-							<resources>
-								<resource>
-									<directory>src/main/wro</directory>
-									<filtering>true</filtering>
-								</resource>
-							</resources>
+							<nodeVersion>v5.6.0</nodeVersion>
+							<npmVersion>3.7.1</npmVersion>
 						</configuration>
 					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>uk.co.codezen</groupId>
-				<artifactId>react-jsxtransformer-maven-plugin</artifactId>
-				<version>1.0</version>
-				<executions>
 					<execution>
-						<id>Compile resources</id>
-						<phase>process-resources</phase>
+						<id>npm install</id>
 						<goals>
-							<goal>compile</goal>
+							<goal>npm</goal>
 						</goals>
 						<configuration>
-							<extension>jsx</extension>
-							<sourcePath>
-								${project.basedir}/src/main/resources/static/js
-							</sourcePath>
-							<targetPath>
-								${project.build.directory}/classes/static/js
-							</targetPath>
+							<arguments>install</arguments>
 						</configuration>
 					</execution>
-				</executions>
-			</plugin>
-			<plugin>
-				<groupId>ro.isdc.wro4j</groupId>
-				<artifactId>wro4j-maven-plugin</artifactId>
-				<version>1.7.9</version>
-				<executions>
 					<execution>
-						<phase>process-resources</phase>
 						<goals>
-							<goal>run</goal>
-						</goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>generate-resources</phase>
+                        <configuration>
+                            <arguments>run-script dev-build</arguments>
+                        </configuration>
 					</execution>
 				</executions>
-				<configuration>
-					<wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
-					<cssDestinationFolder>${project.build.directory}/classes/static/css</cssDestinationFolder>
-					<jsDestinationFolder>${project.build.directory}/classes/static/js</jsDestinationFolder>
-					<wroFile>${project.build.directory}/wro/wro.xml</wroFile>
-					<extraConfigFile>${project.basedir}/src/main/wro/wro.properties</extraConfigFile>
-				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
 			</plugin>
 			<!-- Release -->
 			<plugin>
@@ -212,49 +125,6 @@
 				</configuration> -->
 			</plugin>
 		</plugins>
-
-		<pluginManagement>
-			<plugins>
-				<plugin>
-					<groupId>org.eclipse.m2e</groupId>
-					<artifactId>lifecycle-mapping</artifactId>
-					<version>1.0.0</version>
-					<configuration>
-						<lifecycleMappingMetadata>
-							<pluginExecutions>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>ro.isdc.wro4j</groupId>
-										<artifactId>wro4j-maven-plugin</artifactId>
-										<versionRange>[1.7.9,)</versionRange>
-										<goals>
-											<goal>jshint</goal>
-											<goal>run</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore></ignore>
-									</action>
-								</pluginExecution>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>uk.co.codezen</groupId>
-										<artifactId>react-jsxtransformer-maven-plugin</artifactId>
-										<versionRange>[1.0,)</versionRange>
-										<goals>
-											<goal>compile</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore></ignore>
-									</action>
-								</pluginExecution>
-							</pluginExecutions>
-						</lifecycleMappingMetadata>
-					</configuration>
-				</plugin>
-			</plugins>
-		</pluginManagement>
 	</build>
 	
 	<profiles>

+ 0 - 50
src/main/java/com/opengroupe/cloud/saas/util/React.java

@@ -1,50 +0,0 @@
-package com.opengroupe.cloud.saas.util;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.List;
-
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-
-import com.opengroupe.cloud.saas.domain.Comment;
-
-import jdk.nashorn.api.scripting.NashornScriptEngine;
-
-public class React {
-
-    private ThreadLocal<NashornScriptEngine> engineHolder = new ThreadLocal<NashornScriptEngine>() {
-        @Override
-        protected NashornScriptEngine initialValue() {
-            NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager().getEngineByName("nashorn");
-            try {
-                nashornScriptEngine.eval(read("static/js/nashorn-polyfill.js"));
-                nashornScriptEngine.eval(read("META-INF/resources/webjars/react/0.14.7/react.min.js"));
-                nashornScriptEngine.eval(read("META-INF/resources/webjars/marked/0.3.2/marked.js"));
-//                nashornScriptEngine.eval(read("classpath:static/js/react-bootstrap.js"));
-//                nashornScriptEngine.eval(read("classpath:static/js/comments.js"));
-                nashornScriptEngine.eval(read("static/js/app.js"));
-                nashornScriptEngine.eval(read("static/js/app.render.js"));
-            } catch (ScriptException e) {
-                throw new RuntimeException(e);
-            }
-            return nashornScriptEngine;
-        }
-    };
-
-    public  String renderCommentBox(List<Comment> comments) {
-        try {
-            Object html = engineHolder.get().invokeFunction("renderServer", comments);
-            return String.valueOf(html);
-        }
-        catch (Exception e) {
-            throw new IllegalStateException("failed to render react component", e);
-        }
-    }
-
-    private Reader read(String path) {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(path);
-        return new InputStreamReader(in);
-    }
-}

+ 2 - 4
src/main/java/com/opengroupe/cloud/saas/web/ViewController.java

@@ -24,10 +24,8 @@ public class ViewController {
 	@Bean
 	JavaScriptEngine nashornEngine() {
 		return new JavaScriptEngine().polyfillToNashorn()
-				.loadFromClassPath("META-INF/resources/webjars/react/0.14.7/react.min.js")
-				.loadFromClassPath("META-INF/resources/webjars/marked/0.3.2/marked.js")
-				.loadFromClassPath("static/js/app.js")
-				.loadFromClassPath("static/js/app.render.js");
+				.loadFromClassPath("static/js/vendors.bundle.js")
+				.loadFromClassPath("static/js/app.bundle.js");
 	}
 	
 	@Autowired

+ 14 - 1
src/main/resources/static/js/app.jsx

@@ -1,5 +1,10 @@
 'use strict';
 
+var React		= require('react'),
+	ReactDOM	= require('react-dom'),
+	marked		= require('marked'),
+	$			= require('jquery');
+
 var Comment = React.createClass({
 	rawMarkup: function() {
 		var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
@@ -57,6 +62,7 @@ var CommentForm = React.createClass({
 		);
 	}
 });
+
 var CommentBox = React.createClass({
 	getInitialState: function() {
 		return {data: this.props.data || []};
@@ -120,4 +126,11 @@ var CommentList = React.createClass({
 			</div>
 		)
 	}
-});
+});
+
+module.exports = {
+	CommentBox: CommentBox,
+	CommentList: CommentList,
+	CommentForm: CommentForm,
+	Comment: Comment
+};

+ 15 - 4
src/main/resources/static/js/app.render.jsx

@@ -1,4 +1,14 @@
-var renderClient = function (comments) {
+"use strict";
+
+var React			= require('react'),
+	ReactDOM		= require('react-dom'),
+	ReactDOMServer	= require('react-dom/server'),
+	CommentBox		= require('./app.jsx').CommentBox;
+
+
+require('bootstrap/dist/css/bootstrap.css');
+
+global.renderClient = function (comments) {
     var data = comments || [];
     ReactDOM.render(
 		<CommentBox data={data} url="/api/comments" pollInterval={2000}/>,
@@ -6,9 +16,10 @@ var renderClient = function (comments) {
 	);
 };
 
-var renderServer = function (comments) {
+global.renderServer = function (comments) {
     var data = Java.from(comments);
-    return React.renderToString(
+    return ReactDOMServer.renderToString(
     	<CommentBox data={data} url="/api/comments" pollInterval={2000} />
     );
-};
+};
+

+ 7 - 5
src/main/resources/static/js/nashorn-polyfill.js

@@ -1,6 +1,8 @@
-var global = this;
+var global = window = this;
 
-var console = {};
-console.debug = print;
-console.warn = print;
-console.log = print;
+var console = {
+	debug: print,
+	warn: print,
+	log: print,
+	error: print
+};

+ 7 - 0
src/main/resources/static/js/vendors.js

@@ -0,0 +1,7 @@
+"use strict";
+
+var React		= require('react'),
+	ReactDOM	= require('react-dom'),
+	$			= require('jquery');
+
+require('bootstrap/dist/css/bootstrap.css');

+ 6 - 8
src/main/resources/templates/index.html

@@ -1,10 +1,10 @@
 <!DOCTYPE html>
 <html xmlns:th="http://www.thymeleaf.org">
 <head lang="en">
-<meta charset="UTF-8" />
-<title>Comments channel</title>
-<link rel="stylesheet" href="/css/react-bootstrap.css" />
-<link rel="stylesheet" href="/css/comments.css" />
+	<meta charset="UTF-8" />
+	<title>Comments channel</title>
+	<link rel="stylesheet" href="/css/vendors.bundle.js.css" />
+	<link rel="stylesheet" href="/css/comments.css" />
 </head>
 <body>
 
@@ -16,10 +16,8 @@
 
 	<div th:replace="fragments/footer"></div>
 
-	<script src="/js/react-bootstrap.js"></script>
-	<script src="/js/comments.js"></script>
-	<script src="/js/app.js"></script>
-	<script src="/js/app.render.js"></script>
+	<script src="/js/vendors.bundle.js"></script>
+	<script src="/js/app.bundle.js"></script>
 	<script th:inline="javascript">
         var initialData = JSON.parse(/*[[${data}]]*/ '[]');
         renderClient(initialData);

+ 0 - 8
src/main/wro/wro.properties

@@ -1,8 +0,0 @@
-debug=true
-# Available processors : http://wro4j.readthedocs.org/en/stable/AvailableProcessors/
-#preProcessors=lessCssImport
-#postProcessors=less4j,cssMin
-# explicitly invalidates the cache each 5 seconds
-cacheUpdatePeriod=1
-# check for changes each 5 seconds and invalidates the cache only when a change is detected
-resourceWatcherUpdatePeriod=1

+ 0 - 16
src/main/wro/wro.xml

@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<groups xmlns="http://www.isdc.ro/wro">
-	<group name="react-bootstrap">
-		<css>webjar:bootstrap/@bootstrap.version@/css/bootstrap.css</css>
-		
-		<js>webjar:jquery/@jquery.version@/jquery.js</js>
-		<js>webjar:react/@react.version@/react-with-addons.js</js>
-		<js>webjar:react/@react.version@/react-dom.js</js>
-	</group>
-	
-	<group name="comments">
-		<css>file:src/main/resources/static/css/comments.css</css>
-		
-		<js>webjar:marked/@marked-lib.version@/marked.js</js>
-	</group>
-</groups>

+ 76 - 0
webpack.config.js

@@ -0,0 +1,76 @@
+var path				= require('path'),
+	webpack				= require('webpack'),
+	CommonsChunkPlugin	= require("webpack/lib/optimize/CommonsChunkPlugin"),
+	ExtractTextPlugin	= require("extract-text-webpack-plugin");
+
+var source_dir = __dirname + '/src/main/resources/static/js',
+	node_dir = __dirname + '/node_modules';
+
+var config = {
+    entry: {
+    	app: [source_dir + '/app.render'],
+    	vendors: [source_dir + '/vendors']
+    },
+    resolve: {
+    	extensions: ['', '.js', '.jsx', '.css']
+    },
+    devtool: 'sourcemaps',
+    cache: true,
+    debug: true,
+    output: {
+        path: './target/classes/static/js',
+        filename: '[name].bundle.js',
+        
+    },
+    plugins: [
+        new ExtractTextPlugin("../css/[name].css"),
+        new CommonsChunkPlugin("vendors.bundle.js", ["app", "vendors"]),
+    ],
+    module: {
+        loaders: [
+			{
+			    test: /\.jsx?$/,
+			    exclude: /(node_modules)/, 
+			    loader: 'babel',
+			    query: {
+			    	cacheDirectory: true,
+			        presets: ['es2015', 'react']
+			    }
+			},
+			{ 
+				test: /\.css$/, 
+				loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader") 
+			},
+            { 
+				test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff(2)?$|\.ttf$|\.wav$|\.mp3$/, 
+				loader: require.resolve("file-loader") + "?name=../[path][name].[ext]"
+			},
+			{ 
+            	test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, 
+            	loader: "file" 
+            },
+			{ 
+            	test: /\.(woff|woff2)$/, 
+            	loader:"url?prefix=font/&limit=5000" 
+            },
+			{ 
+            	test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, 
+            	loader: "url?limit=10000&mimetype=application/octet-stream" 
+            },
+			{ 
+            	test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, 
+            	loader: "url?limit=10000&mimetype=image/svg+xml" 
+            },
+            {
+            	test: path.join(__dirname, '.'),
+            	exclude: /(node_modules)/,
+            	loader: 'babel-loader'
+            }
+        ]
+    },
+    postcss: function () {
+        return [];
+    }
+};
+
+module.exports = config;