How to serve frontend using frontend maven plugin in gradle based project? - spring

I have read some online blogs that states adding this plugin builds Angular frontend so it would be easier to serve angular content from a spring boot path - resources/static folder. But couldn't find any example for gradle projects.
I have a gradle project which consists of modules for backend and frontend and trying to host it on same server port. I added :
compile group: 'com.github.eirslett', name: 'frontend-maven-plugin', version: '1.6'
Then ran ng build in frontend dir to build ng components. I see some.js files and following index.html generated :
<html lang="en">
<head>
<meta charset="utf-8">
<title>Welcome App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>
From my understanding adding above dependency just take care of install npm and node dependencies but won't build ng components. So I manually ran ng build and the those files gets generated in resources/static directory(as I changed outputPath in angular.json). But unable to serve them from tomcat startup.
I just have 3 ng components where the main login component uri should be accessible at "/" and routing works fine and handled by angular(ng serve shows UI pages) but just not when in spring-boot path so as to deploy on same server port as backend.
imports: [
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
{
// empty path is the default page for app; redirects to Login component
path: '',
component: LgnComponent
},
{
path: 'test',
component: TestComponent
},
{
path: 'sale',
component: SaleComponent
}
])
My only problem is http://localhost:8080/ displays no UI(login etc.)
I mean to ask are there any additional steps beyond adding this
dependency to build.gradle in order to easily serve them?
I guess I don't know what URI to use to access frontend on 8080. Because angular routing works fine and was able to access on localhost:4200/ and from the main login page to localhost:4200/test and /sale .
Please help, I have been struggling/banging my head on this issue for sometime now.

Building your frontend application in Gradle with the frontend-maven-plugin is not relevant, because this plugin is designed for Maven, not Gradle. You may take a look at the Siouan Frontend Gradle plugin, that will allow you to trigger your frontend application build directly from Gradle. From the official website:
It is inspired by the frontend-maven-plugin.
This other answer to a similar question provides an example of how to use this plugin. Here's a minimal configuration example to build your frontend application:
// build.gradle
plugins {
id 'org.siouan.frontend' version '1.1.2'
}
frontend {
// Replace with your Node version.
nodeVersion = '10.15.3'
// Replace 'build' by the name of your script in your project's 'package.json' file.
assembleScript = 'run build'
}
Having your freshly built frontend application served by your Spring Boot backend and correctly packaged in your final archive are different problems. You'll find a working example of a Angular + Spring Boot + Gradle application by generating a demo application with JHipster and its JHipster Online service. This will also show you where the different artifacts are generated to be served either by the backend or the frontend development server.
EDIT
The plugin's homepage now provides some usage guidelines, that may help 'packaging' a frontend and a Java backend together.

The plugin seems a bit outdated.
I am using the gradle node plugin. You add the build command to package.json and then execute the script via the plugin:
package.json:
{
"name": "stuff",
"version": "0.1.4",
"license": "MIT",
"scripts": {
"buildProd": "ng build -prod"
}
...
}
build.gradle:
//execute buildProd script from project.json
task buildClient(type: NpmTask, dependsOn: [npmInstall]) {
args = ['run-script', 'buildProd']
}
task copyClient(type: Copy, dependsOn: [buildClient]) {
from 'dist'
into "${buildDir}/resources/main/static"
}
//build & copy client before processResources
processResources.dependsOn copyClient

Related

How to include a js file kept in static folder in thymeleaf html

I am using Spring Tool Suite to build spring boot application and using thymeleaf as template engine.
The folder structure is as follows:
src/main/resources/static
src/main/resources/templates
The HTML file is kept in src/main/resources/templates
and the javacript file is kept in src/main/resources/static
To include the javascript file in my html I have added the below line:
<script type="text/javascript" th:src="#{../static/js/policyCreations.js}"></script>
but I am getting bellow error in chrome console:
GET http://localhost:8082/static/js/policyCreations.js net::ERR_ABORTED 404
can anyone help me to resolve the issue
According to the official doc:
Spring Boot will automatically add static web resources located within any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
So all the files located in the static folder can be referenced directly without specifying the static folder name.
Like:
<script type="text/javascript" th:src="#{/js/policyCreations.js}"></script>

Import css files in client app created in dotnet core angular-5 application on VS2017

I have started a new .Net Core + Angular 5 application using VS2017's create project wizard.
I want to use primeng component library in this project.
It has some css files inside its node_modules/primeng/ folder, which I need to import in my angular app for better UI.
I tried following code as shown there website but it is not working:
<link rel="stylesheet" type="text/css" href="/node_modules/primeng/resources/themes/omega/theme.css" />
<link rel="stylesheet" type="text/css" href="/node_modules/primeng/resources/primeng.min.css" />
In my another app made on VSCode I used following code to add these files in .angular-cli.json:
"styles": [
"styles.css",
"../node_modules/primeng/resources/themes/omega/theme.css"
"../node_modules/primeng/resources/primeng.min.css"
],
But in this project made on VS2017 I am not able to find any sutable location to inject these files.
In your webpack.config.vendor.js file you have to add the module you want to bundle as vendor. if you install primeng and primeicons as npm dependencies you can use the following code. Put then in the nonTreeShakableModules so it doesn't get strip when you publish you app.
const nonTreeShakableModules = [
'es6-promise',
'es6-shim',
'event-source-polyfill',
'primeicons/primeicons.css',
'primeng/resources/themes/omega/theme.css',
'primeng/resources/primeng.min.css'
];
You may have to modify also some rules to include images of primeicons. In the same file add gif to the test node
module: {
rules: [
{ test: /\.(png|gif|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
]
},
Then make sure you include the vendor.css file in your template/layout and you should be good to go!
<link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true">
To re-bundle the vendor files you may have to delete the dist folders in wwwroot and Clientapp and just rebuild your project

Cannot find module after creating and adding plugin in Nativescript

Using the latest version of Nativescript I've created a plugin as per the documentation and after running tns plugin add ../nativescript-keychain I get the message Successfully installed plugin nativescript-keychain.
I can also see that it's been added to the node_modules directory of my app but require("nativescript-keychain") doesn't work as I get the error Cannot find module 'nativescript-keychain'
My plugin package.json looks like
{
"name": "nativescript-keychain",
"version": "0.0.1",
"nativescript": {
"platforms": {
"ios": "2.2.1"
}
}
}
There are several reasons why this might occur; it would be helpful if you provided a repo to see all the code.
package.json doesn't have a link to the source, typically you have a main: "somefile" key.
Did you do tns run ios --emulator after you installed the plugin, you have to rebuild the app before it will take effect, plugins can't be synced via livesync...
Is the code TypeScript or JavaScript, if it is TypeScript it needs to be transpiled to JS before you can add it to your demo application. TNS will NOT compile any TS code in the plugins. Plugins have to ship with the final JS code.
You need typings for TS to use the auto-complete and not throw warnings about what methods are available.

bowerInstall task alternative for Java?

I'm working on a SpringMVC project and currently I'm organising the project structure for the "client" module. I'm using the webjars and wro4j projects with are great, to organise my JavaScript dependencies and concatenate and minimise my CSS/JS code.
What I miss is something exists in the "JavaScript" world that allows to use some HTML code depending on your environment. I'm talking about something like bowerInstall task.
What I would like is to have in my JSP code:
* the includes to my JS files one by one, when working in "development" profile
* a single file, as concatenation and minification, when working in "production" profile.
Next lines are from a HTML file in a Yeoman based project:
...
<!-- build:css styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="../bower_components/highlightjs/styles/monokai.css" />
<link rel="stylesheet" href="../bower_components/seiyria-bootstrap-slider/dist/css/bootstrap-slider.css" />
<!-- endbower -->
<!-- endbuild -->
...
When the grunt task runner is executed, if I'm working in dev mode it does not much but if we are in "prod" mode all the previous CSS are substituted by a line like:
<link rel="stylesheet" href="styles/vendor.css" />
Is this possible in Java??
Is this possible in Java?? No.
However, you may try a couple of options.
Google Pagespeed - Check filter-css-combine documentation. Quick and dirty option, if you have an old project running on production.
Grunt task - Search for grunt-concat-css.
If you are using Bower and Yeoman, you would most probably know Grunt. Just hook on the grunt task to maven ( Search allegro/grunt-maven-plugin) or Gradle (Search com.moowork.grunt) before your WAR task.
this is not a comprehensive answer. Just pointers in the right direction.

How can Modernizr 3.x modules be required?

I am trying to require specific Modernizr tests into a browserify project but i must be doing something wrong.
I use the deamdify transform when building using browserify.
Modernizr is required as an NPM package directly from the source repo's master. The reason this happens is because pending v3.x will be available through npm and the latest bower packages do not offer the sources, only prebuilt versions.
I want to be flexible with what Modernizr modules i include in my application so for my needs, having an extra build-modernizr step is not acceptable. I want to have a single build step, browserify.
The problem is that deamdify fails to recognize the required Moderizr modules as AMD and does not resolve their dependencies or wrap them in AMD containers...
I have setup a repo that illustrates the problem:
https://github.com/thanpolas/browserify-modernizr
Nope, you aren't doing anything wrong. Its just not set up to work like that quite yet. Its a bit of a custom AMD.
#robw has been working on a new build system that I believe would show you to do what you are looking for.
update: the new build system is finally in effect - using master as of 2/8/2015 you can require tests
Though you said that having an extra build-modernizr step is not acceptable for you (I provided answer for that case) but still I want to add another answer for the case when using browserify and Modernizr with gulp.
gulp-modernizr can crawl through specified files, find Modernizr usages and make custom Modernizr build:
npm install --save-dev gulp-modernizr
Define gulp task in gulpfile.js:
var modernizr = require('gulp-modernizr')
gulp.task('modernizr', function () {
return gulp.src('src/**/*.js')
.pipe(modernizr())
.pipe(gulp.dest('build'));
});
This task generates build/modernizr.js that contains only tests used in your source code. When added to html file with <script> tag this file sets Modernizr instance to window.Modernizr property. So you can use it like:
if (window.Modernizr.filereader) {
// your code here
}
Using modernizr as module.
If you want to use modernizr as module (see this issue for discussion) than create src/modernizr.js file:
module.exports = window.Modernizr;
And expose this file as module with name modernizr:
var browserify = require('browserify');
var source = require('vinyl-source-stream');
gulp.task('browserify', ['modernizr'], function() {
var b = browserify({ entries: 'src/index.js' });
b.require('src/modernizr.js', {expose: 'modernizr'});
return b.bundle()
.pipe(source('index.js'))
.pipe(gulp.dest('build'));
});
Now you can use it in your source code:
var modernizr = require('modernizr');
if (modernizr.filereader) {
...
}
Injecting build/modernizr.js and build/index.js scripts in index.html.
Suppose you have src/index.html:
<!DOCTYPE html>
<html class='no-js' lang=''>
<head>
<meta charset='UTF-8'>
<title>Example</title>
<!-- inject:head:js -->
<!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>
The following gulp task will inject build/modernizr.js in head section and build/index.js in body section and place resulting file to build/index.html:
var inject = require('gulp-inject');
gulp.task('html', ['browserify'], function() {
return gulp.src('src/index.html')
.pipe(inject(gulp.src('build/modernizr.js', { read: false }),
{ ignorePath: 'build', addRootSlash: true, starttag: '<!-- inject:head:{{ext}} -->'}))
.pipe(inject(gulp.src('build/index.js', { read: false }),
{ ignorePath: 'build', addRootSlash: true}))
.pipe(gulp.dest('build'));
});
With browsernizr you can specify what tests you need in your source code.
Install:
npm install --save browsernizr
Use:
// pick what tests you need
require('browsernizr/test/css/rgba');
require('browsernizr/test/file/filesystem');
require('browsernizr/test/websockets');
// make sure to do this after importing the tests
require('browsernizr');
// or if you need access to the modernizr instance:
var Modernizr = require('browsernizr');
browserify will include required tests in bundle.

Resources