UI Local Build Setup on Commerce Cloud v2 1811 (Hybris)
A simple step-by-step approach to optimize UI development effort
Problem Statement:
As a Commerce Cloud v2 1811 (Hybris) UI developer, you might have faced an issue where even to test simple .less, .js changes done in source files, you would need to run command ant all or ant <custom>b2cutilstorefront_compileuisrc for the server run-time files to get updated as described at https://help.sap.com/viewer/4c33bf189ab9409e84e589295c36d96e/1811/en-US/8ac7e55f86691014a6a9c4f72246…. This process generally takes anywhere between 20 seconds to 2 minutes every time you make a change. Another way for quick testing is to directly make the changes in files that are present in run-time directories of the web server. The problem is here is that you burden your short-term memory as you’d need to remember all the changes that you had done under run-time directories and then manually copy-paste changes from run-time files to source files. This increases the risk of manual error. With UI Local Build Setup, by modifying Out of the Box Grunt configuration, you can
-
- save your (development) time and speed up time-to-delivery
-
- avoid manual errors if you’re used to copy-pasting changes from run-time files to source files
-
- avoid stressing your memory to remember changes done in run-time files.
A step-by-step approach is given below to help optimize UI development effort.
Note: Setup done on:
-
- Mac OS (Catalina v10.15.2)
-
- NodeJS v13.3.0; npm 6.13.1
Similar steps can be done on Windows OS.
1. Update Gruntfile.js
Path to existing Gruntfile.js:
<projectRootFolder>/hybris/bin/custom/<custom util>/<custom util storefront>/web/Gruntfile.js
For Chrome browser to load changes done in any of .less, .js, .jsp and .tag files and to work with NodeJS version 13, add support for grunt-browser-sync
and grunt-contrib-copy
by making the changes as shown below to the existing Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
less: {
files: ['webroot/WEB-INF/_ui-src/shared/less/variableMapping.less','webroot/WEB-INF/_ui-src/shared/less/generatedVariables.less',
'webroot/WEB-INF/_ui-src/responsive/lib/ybase-*/less/*', 'webroot/WEB-INF/_ui-src/**/themes/**/less/*.less'],
tasks: ['less'],
},
fonts: {
files: ['webroot/WEB-INF/_ui-src/**/themes/**/fonts/*'],
tasks: ['sync:syncfonts'],
},
ybasejs: {
files: ['webroot/WEB-INF/_ui-src/responsive/lib/ybase-0.1.0/js/**/*.js'],
tasks: ['copy'],
},
jquery: {
files: ['webroot/WEB-INF/_ui-src/responsive/lib/common/**.js'],
tasks: ['copy'],
},
},
less: {
default: {
files: [
{
expand: true,
cwd: 'webroot/WEB-INF/_ui-src/',
src: '**/themes/**/less/style.less',
dest: 'webroot/_ui/',
ext: '.css',
rename:function(dest,src){
var nsrc = src.replace(new RegExp("/themes/(.*)/less"),"/theme-$1/css");
return dest+nsrc;
}
}
]
},
},
sync : {
syncfonts: {
files: [{
expand: true,
cwd: 'webroot/WEB-INF/_ui-src/',
src: '**/themes/**/fonts/*',
dest: 'webroot/_ui/',
rename:function(dest,src){
var nsrc = src.replace(new RegExp("/themes/(.*)"),"/theme-$1");
return dest+nsrc;
}
}]
},
syncybase: {
files: [{
cwd: 'webroot/WEB-INF/_ui-src/responsive/lib/ybase-0.1.0/js/',
src: '**/*.js',
dest: 'webroot/_ui/responsive/common/js',
}]
},
syncjquery: {
files: [{
expand: true,
cwd: 'webroot/WEB-INF/_ui-src/responsive/lib',
src: 'jquery*.js',
dest: 'webroot/_ui/responsive/common/js',
}]
}
},
copy: {
main: {
files: [
// includes files within path and its sub-directories
{
expand: true,
cwd: 'webroot/WEB-INF/_ui-src/responsive/lib/ybase-0.1.0/js/',
src: '**/*.js',
dest: 'webroot/_ui/responsive/common/js'
},
{
expand: true,
cwd: 'webroot/WEB-INF/_ui-src/responsive/lib/common',
src: '**/*.js',
dest: 'webroot/_ui/responsive/common/js'
}
]
}
},
browserSync: {
default_options: {
bsFiles: {
src: [
"**/*.js",
"**/*.css",
"**/*.jsp",
"**/*.tag",
]
},
options: {
watchTask: true,
proxy: "https://local.dev:9002/customb2cutilstorefront",
reloadDelay: 2000
}
}
},
});
// Plugins
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-browser-sync');
grunt.loadNpmTasks('grunt-contrib-copy');
// Default task(s). Run 'grunt watch' to start the watching task or add 'watch' to the task list and run 'grunt'.
grunt.registerTask('default', ['less', 'sync']);
// Browser sync task
grunt.registerTask("server", ['browserSync', 'watch']);
};
Please note that you would need to make changes to property
proxy: "https://local.dev:9002/customb2cutilstorefront",
2. Update package.json
Update package.json (located under the same folder as that of Gruntfile.js) that contains grunt-browser-sync
and grunt-contrib-copy
{
"name": "customb2cutilstorefront",
"version": "0.0.0",
"description": "grunt config for the accelerator",
"private": true,
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "grunt"
},
"author": "",
"license": "ISC",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-less": "^1.0.1",
"grunt-contrib-watch": "^0.6.1",
"plugin": "^0.3.3"
},
"dependencies": {
"grunt-browser-sync": "^2.2.0",
"grunt-sync": "0.0.8"
}
}
3. Install Dependencies
In your terminal, navigate to <projectRootFolder>/hybris/bin/custom/<custom util>/<custom util storefront>/web which contains files – package.json and Gruntfile.js
Make sure grunt-cli
[https://gruntjs.com/using-the-cli] is installed on your system. Run command,
npm install
to install required dependencies.
4. Run server and view changes immediately
In your terminal, navigate to <projectRootFolder>/hybris/bin/custom/<custom util>/<custom util storefront>/web which contains files – package.json and Gruntfile.js
Run command,
grunt server
to run browsersync server. By default, a new Chrome browser window should open up with URL: https://localhost:3000/customb2cutilstorefront
Now, any UI related changes that you do in source .js, .less, .tag, .jsp files should get auto-updated in the opened browser window without you manually copy-pasting files from UI files from source directory such as WEB-INF/_ui-src/ to runtime directory such as /_ui/
Summing it up
With a UI Local Build Setup similar to the one as shown above, you can dramatically increase your development productivity.
With the above setup in place, no more
-
- Running ant all or ant <custom>b2cutilstorefront_compileuisrc which takes anywhere between 30s to 2 min for even simple changes to .js /.less
-
- Manual errors while copy-pasting files from run-time to source
-
- Remembering changes done to files in run-time
Based on your development environment, you might face a few initial issues to set this up. Once done, though, you’re sure to reap benefits in the long term.
Request to post your comments to correct/enrich the steps mentioned above to help UI developers.