Feature: using webpack instead of wro

This commit is contained in:
fecaille
2016-03-31 09:36:13 +02:00
parent 1c00864580
commit fe4cfcc962
14 changed files with 200 additions and 264 deletions

3
.babelrc Normal file
View File

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

1
.gitignore vendored
View File

@@ -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
package.json Normal file
View File

@@ -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"
}
}

206
pom.xml
View File

@@ -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>
@@ -88,105 +58,48 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>0.0.29</version>
<configuration>
<workingDirectory>${project.build.directory}</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v5.6.0</nodeVersion>
<npmVersion>3.7.1</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run-script dev-build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<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>
<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>
</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>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/wro</outputDirectory>
<resources>
<resource>
<directory>src/main/wro</directory>
<filtering>true</filtering>
</resource>
</resources>
</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>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<extension>jsx</extension>
<sourcePath>
${project.basedir}/src/main/resources/static/js
</sourcePath>
<targetPath>
${project.build.directory}/classes/static/js
</targetPath>
</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>
</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>
<!-- Release -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -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>

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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
};

View File

@@ -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} />
);
};
};

View File

@@ -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
};

View File

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

View File

@@ -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);

View File

@@ -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

View File

@@ -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
webpack.config.js Normal file
View File

@@ -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;