Skip to content

Commit 3fc61f7

Browse files
zeroualzeroual
authored and
zeroual
committed
Minify the css and js in production environment
1 parent 59c6739 commit 3fc61f7

File tree

8 files changed

+230
-21
lines changed

8 files changed

+230
-21
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#mvn targer directory
99
target
10-
10+
dist
1111
.classpath
1212
.project
1313
.settings
@@ -17,4 +17,4 @@ bin
1717
# static dependencies
1818
bower_components
1919
#node modules
20-
node_modules
20+
node_modules

gulpfile.js

+90-9
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,117 @@
11
var gulp = require('gulp');
22
var Server = require('karma').Server;
33
var browserSync = require('browser-sync').create();
4+
var usemin = require('gulp-usemin'),
5+
cssnano = require('gulp-cssnano'),
6+
rev = require('gulp-rev'),
7+
htmlmin = require('gulp-htmlmin'),
8+
sourcemaps = require('gulp-sourcemaps'),
9+
ngAnnotate = require('gulp-ng-annotate'),
10+
uglify = require('gulp-uglify'),
11+
prefix = require('gulp-autoprefixer'),
12+
imagemin = require('gulp-imagemin'),
13+
flatten = require('gulp-flatten'),
14+
del = require('del'),
15+
runSequence = require('run-sequence');
16+
17+
var config = {
18+
app: 'src/main/webapp/',
19+
dist: 'src/main/webapp/dist/'
20+
};
21+
422
/**
523
* Run test once and exit
624
*/
7-
//TODO make browserSyn use server proxy
825
gulp.task('test', function (done) {
926
new Server({
1027
configFile: __dirname + '/src/test/javascript/karma.conf.js',
1128
singleRun: true
1229
}, done).start();
1330
});
1431

32+
/**
33+
* Run test once and watch changing
34+
*/
1535
gulp.task('test-watch', function (done) {
1636
new Server({
17-
configFile: __dirname + '/src/test/javascript/karma.conf.js',
37+
configFile: __dirname +'/src/test/javascript/karma.conf.js',
1838
singleRun: false
1939
}, done).start();
2040
});
2141

22-
// Static Server + watching js/css/html files
42+
/**
43+
* Run a static server and reload changing file
44+
*/
2345
gulp.task('serve', function () {
2446
browserSync.init({
2547
server: __dirname + '/src/main/webapp'
2648
});
2749
gulp.watch(__dirname + '/src/main/webapp/*').on('change', browserSync.reload);
2850
});
2951

30-
//TODO minify the css
31-
//build the front project
32-
gulp.task('build', []);
3352

34-
gulp.task('default', function () {
35-
// place code for your default task here
36-
});
53+
/**
54+
* build the front app for prod env
55+
*/
56+
gulp.task('build', function (cb) {
57+
runSequence('clean', 'usemin', 'copy-bs-fonts', cb);
58+
});
59+
60+
gulp.task('styles', [], function () {
61+
return gulp.src(config.app + 'assets/css/**/*.css')
62+
.pipe(browserSync.reload({stream: true}));
63+
});
64+
65+
/**
66+
* minimise images size
67+
*/
68+
gulp.task('images', function () {
69+
return gulp.src(config.app + 'assets/images/**')
70+
.pipe(imagemin({optimizationLevel: 5}))
71+
.pipe(gulp.dest(config.dist + 'assets/images'))
72+
.pipe(browserSync.reload({stream: true}));
73+
});
74+
75+
/**
76+
* copy bootstrap font into assets/fonts
77+
*/
78+
gulp.task('copy-bs-fonts', function () {
79+
return gulp.src([
80+
config.app + 'bower_components/bootstrap/fonts/*.*'])
81+
.pipe(flatten())
82+
.pipe(gulp.dest(config.dist + 'assets/fonts/'));
83+
});
84+
85+
/**
86+
* remove the old dist directory
87+
*/
88+
gulp.task('clean', function () {
89+
return del([config.dist]);
90+
});
91+
92+
/**
93+
* minify css and js
94+
*/
95+
gulp.task('usemin', ['styles', 'images'], function () {
96+
return gulp.src([config.app + '**/*.html', '!' + config.app + '@(dist|bower_components)/**/*.html'])
97+
.pipe(usemin({
98+
css: [
99+
prefix,
100+
'concat',
101+
cssnano,
102+
rev
103+
],
104+
html: [
105+
htmlmin.bind(htmlmin, {collapseWhitespace: true})
106+
],
107+
js: [
108+
sourcemaps.init,
109+
ngAnnotate,
110+
'concat',
111+
uglify.bind(uglify, {mangle: false}),
112+
rev,
113+
sourcemaps.write.bind(sourcemaps.write, '.')
114+
]
115+
}))
116+
.pipe(gulp.dest(config.dist));
117+
});

package.json

+13-1
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@
1313
"devDependencies": {
1414
"bower": "~1.6.5",
1515
"browser-sync": "^2.10.0",
16+
"del": "^2.2.2",
1617
"gulp": "^3.9.0",
18+
"gulp-autoprefixer": "^3.1.0",
19+
"gulp-cssnano": "^2.1.2",
20+
"gulp-flatten": "^0.3.1",
21+
"gulp-htmlmin": "^2.0.0",
22+
"gulp-imagemin": "^3.0.3",
23+
"gulp-ng-annotate": "^2.0.0",
24+
"gulp-rev": "^7.0.0",
25+
"gulp-sourcemaps": "^1.6.0",
26+
"gulp-uglify": "^1.5.3",
27+
"gulp-usemin": "^0.3.23",
1728
"jasmine-core": "^2.3.4",
1829
"karma": "^0.13.22",
1930
"karma-cli": "~0.1.1",
2031
"karma-jasmine": "~0.3.6",
2132
"karma-ng-html2js-preprocessor": "^0.2.0",
2233
"karma-phantomjs-launcher": "^1.0.0",
23-
"phantomjs-prebuilt": "^2.1.7"
34+
"phantomjs-prebuilt": "^2.1.7",
35+
"run-sequence": "^1.2.2"
2436
}
2537
}

src/main/java/com/otchi/infrastructure/config/InfrastructureConfig.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.common.eventbus.EventBus;
44
import com.otchi.domain.events.DomainEvents;
55
import com.otchi.domain.events.PostCommentedEventHandler;
6+
import com.otchi.infrastructure.web.WebConfigurer;
67
import com.otchi.infrastructure.config.database.DatabaseConfig;
78
import com.otchi.infrastructure.config.storage.BlobStorageConfig;
89
import com.otchi.infrastructure.eventBus.GuavaDomainEventsBus;
@@ -14,7 +15,7 @@
1415

1516

1617
@Configuration
17-
@Import({SecurityConfig.class, DatabaseConfig.class, SocialConfig.class, BlobStorageConfig.class,
18+
@Import({WebConfigurer.class, SecurityConfig.class, DatabaseConfig.class, SocialConfig.class, BlobStorageConfig.class,
1819
ThymeleafConfig.class, MailerConfig.class, WebsocketConfig.class})
1920
@ComponentScan({"com.otchi.api"})
2021

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.otchi.infrastructure.web;
2+
3+
4+
import javax.servlet.*;
5+
import javax.servlet.http.HttpServletRequest;
6+
import java.io.IOException;
7+
8+
/**
9+
* This filter is used in production, to serve static resources generated by "gulp build".
10+
*/
11+
public class StaticResourcesProductionFilter implements Filter {
12+
13+
14+
@Override
15+
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
16+
HttpServletRequest httpRequest = (HttpServletRequest) request;
17+
String contextPath = ((HttpServletRequest) request).getContextPath();
18+
String requestURI = httpRequest.getRequestURI();
19+
requestURI = substringAfter(requestURI, contextPath);
20+
if (requestURI.equals("/")) {
21+
requestURI = "/index.html";
22+
}
23+
String newURI = "/dist" + requestURI;
24+
request.getRequestDispatcher(newURI).forward(request, response);
25+
}
26+
27+
private String substringAfter(String str, String separator) {
28+
int pos = str.indexOf(separator);
29+
return pos == -1 ? "" : str.substring(pos + separator.length());
30+
}
31+
32+
@Override
33+
public void init(FilterConfig filterConfig) throws ServletException {
34+
// Nothing to initialize
35+
}
36+
37+
@Override
38+
public void destroy() {
39+
// Nothing to destroy
40+
}
41+
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.otchi.infrastructure.web;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
6+
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
7+
import org.springframework.boot.context.embedded.MimeMappings;
8+
import org.springframework.boot.context.embedded.ServletContextInitializer;
9+
import org.springframework.context.annotation.Configuration;
10+
import org.springframework.core.env.Environment;
11+
12+
import javax.inject.Inject;
13+
import javax.servlet.DispatcherType;
14+
import javax.servlet.FilterRegistration;
15+
import javax.servlet.ServletContext;
16+
import javax.servlet.ServletException;
17+
import java.util.Arrays;
18+
import java.util.EnumSet;
19+
20+
import static com.otchi.infrastructure.config.Constants.SPRING_PROFILE_PRODUCTION;
21+
22+
@Configuration
23+
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
24+
25+
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
26+
27+
@Inject
28+
private Environment env;
29+
30+
@Override
31+
public void onStartup(ServletContext servletContext) throws ServletException {
32+
log.info("Web application configuration, using profiles: {}", Arrays.toString(env.getActiveProfiles()));
33+
EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
34+
if (env.acceptsProfiles(SPRING_PROFILE_PRODUCTION)) {
35+
initStaticResourcesProductionFilter(servletContext, disps);
36+
}
37+
log.info("Web application fully configured");
38+
}
39+
40+
/**
41+
* Initializes the static resources production Filter.
42+
*/
43+
private void initStaticResourcesProductionFilter(ServletContext servletContext,
44+
EnumSet<DispatcherType> disps) {
45+
46+
log.debug("Registering static resources production Filter");
47+
FilterRegistration.Dynamic staticResourcesProductionFilter =
48+
servletContext.addFilter("staticResourcesProductionFilter",
49+
new StaticResourcesProductionFilter());
50+
51+
staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/");
52+
staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/index.html");
53+
staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/assets/*");
54+
staticResourcesProductionFilter.addMappingForUrlPatterns(disps, true, "/scripts/*");
55+
staticResourcesProductionFilter.setAsyncSupported(true);
56+
}
57+
58+
@Override
59+
public void customize(ConfigurableEmbeddedServletContainer container) {
60+
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
61+
mappings.add("html", "text/html;charset=utf-8");
62+
mappings.add("json", "text/html;charset=utf-8");
63+
container.setMimeMappings(mappings);
64+
}
65+
66+
67+
}

src/main/webapp/app/social/stream/views/feed.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
99
<span>
1010
<strong>Notice : </strong>
11-
No feeds found . You must be new. Or quiet >_<
11+
No feeds found . You must be new. Or quiet :(
1212
</span>
1313
</div>
1414
<div ng-repeat="feed in feeds">

src/main/webapp/index.html

+13-7
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon">
1111
<link rel="icon" href="assets/images/favicon.ico" type="image/x-icon">
1212
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro' rel='stylesheet' type='text/css'>
13-
<!-- Bootstrap core CSS -->
13+
<!-- build:css assets/css/vendor.css -->
14+
<!-- bower:css -->
1415
<link href="bower_components/bootstrap/dist/css/bootstrap.css" rel="stylesheet">
1516
<link href="bower_components/angular-bootstrap/ui-bootstrap-csp.css" rel="stylesheet">
16-
<link rel="stylesheet" href="bower_components/ngToast/dist/ngToast.css">
17+
<link href="bower_components/ngToast/dist/ngToast.css" rel="stylesheet">
18+
<!-- endbower -->
19+
<!-- endbuild -->
20+
<!-- build:css assets/css/main.css -->
1721
<link rel="stylesheet" href="assets/css/cards.css">
1822
<link rel="stylesheet" href="assets/css/buttons.css">
1923
<link rel="stylesheet" href="assets/css/inputs.css">
@@ -23,7 +27,7 @@
2327
<link rel="stylesheet" href="assets/css/notifications.css">
2428
<link rel="stylesheet" href="assets/css/feeds.css">
2529
<link rel="stylesheet" href="assets/css/main.css">
26-
30+
<!-- endbuild -->
2731

2832
</head>
2933

@@ -35,9 +39,8 @@
3539

3640
</div>
3741
</div>
38-
<!-- Bootstrap core JavaScript
39-
================================================== -->
40-
<!-- Placed at the end of the document so the pages load faster -->
42+
<!-- build:js scripts/vendor.js -->
43+
<!-- bower:js -->
4144
<script src="bower_components/jquery/dist/jquery.js"></script>
4245
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
4346
<script src="bower_components/angular/angular.js"></script>
@@ -53,7 +56,10 @@
5356
<script src="bower_components/ng-file-upload/ng-file-upload.min.js"></script>
5457
<script src="bower_components/sockjs-client/dist/sockjs.min.js"></script>
5558
<script src="bower_components/stomp-websocket/lib/stomp.min.js"></script>
59+
<!-- endbower -->
60+
<!-- endbuild -->
5661

62+
<!-- build:js({.tmp,src/main/webapp}) scripts/app.js -->
5763
<script type="text/javascript" src="app/authentication/authentication.js"></script>
5864
<script type="text/javascript" src="app/components/toaster/toaster.js"></script>
5965
<script type="text/javascript" src="app/social-authentication/social-authentication.js"></script>
@@ -99,9 +105,9 @@
99105
<script type="text/javascript" src="app/social-authentication/directives/social-auth-button.directive.js"></script>
100106
<script type="text/javascript" src="app/social-authentication/controllers/social-register.controller.js"></script>
101107

102-
103108
<script type="text/javascript" src="app/components/navbar/navbar.controller.js"></script>
104109
<script type="text/javascript" src="app/components/toaster/toaster.js"></script>
105110
<script type="text/javascript" src="app/components/toaster/services/toaster.service.js"></script>
111+
<!-- endbuild -->
106112
</body>
107113
</html>

0 commit comments

Comments
 (0)