📜 ⬆️ ⬇️

Build AngularJs Bundle Apps With Gulp

Good afternoon.


I'll tell you about a great gulp plugin for building your web application into one large asset that can travel separately to any host in a convenient way, and if you use continuous deployment, you can collect assets directly in Jenkins for example.


So first, let's start by listing all the necessary plugins:


var gulp = require('gulp'), clean = require('gulp-clean'), //   dist inject = require('gulp-inject'), //          dev  bundle = require('gulp-bundle-assets'), //     config = require('load-gulp-config'), //  json       htmlreplace = require('gulp-html-replace'); //      json    html 

bundle-assets is a great plugin because it allows you to create a separate dist directory with all the fonts, pictures, styles, etc. that are necessary for the application to work. An example of using the plugin can be viewed at the link .


In short, at the output we get the following bundle.result.json , all source lines are already minimized and can be located anywhere you want:


 { "main": { "styles": "<link href='main-8e6d79da08.css' media='screen' rel='stylesheet' type='text/css'/>", "scripts": "<script src='main-5f17cd21a6.js' type='text/javascript'></script>" }, "vendor": { "scripts": "<script src='vendor-d66b96f539.js' type='text/javascript'></script>", "styles": "<link href='vendor-23d5c9c6d1.css' media='screen' rel='stylesheet' type='text/css'/>" } } 

All you need is to create a bundle.config file that will be read by the plugin. Here is the config in our project:


 module.exports = { bundle: { main: { scripts: [ 'js/app.js', //   AngularJs  'js/investigator/**/*.js' //    ], styles: ['css/investigator/**/*.css'] //    }, vendor: { scripts: [ 'js/plugin/jquery-touch/jquery.ui.touch-punch.min.js', ... //      'js/plugin/filesaver/FileSaver.js' ], styles: [ 'css/**/*.css' ] } }, copy: [ 'img/**/*.{png,svg,ico,jpeg,jpg,gif}', 'manifest.json', 'includes/**/*.html', 'fonts/**/*.{woff,svg,ttf,eot}', 'i18n/**/*.json', ..., //     index.html  . 'js/investigator/countries/countries.json' ] }; 

And the build-bundle task, which will put it all into a 'distribution'


 gulp.task('clean', function() { return gulp.src('dist') .pipe(clean({force: true})) .pipe(gulp.dest('')); }); gulp.task('build-bundles', ['clean'], function () { return gulp.src('bundle.config.js') .pipe(bundle()) .pipe(bundle.results('./')) .pipe(gulp.dest('./dist')); }); 

And after running the task, we get at the exit, such a great build that can be sent to your host:
image


But! In case of development with the client framework (AngularJs in my case), this plugin does not allow embedding the output files into your html.


Here is a description of how to implement links to the output source on the server side using Hogan (hjs).


Therefore I will describe the method of embedding these sources with the same Gulp using gulp-html-replace. In short, we should consider our bundle.result.json described above, and tell the html-replace what to implement and where. Know 'where?' the plugin will be after we add the necessary markup to our index.html.


First task:


 gulp.task('build-release', ['build-bundles'], function () { var bundleResult = config.util.readJSON('bundle.result.json'); //   bundle-assets gulp.src(['index.html']) .pipe(htmlreplace({ js: { src: null, // null .    bundle-assets   link   tpl: bundleResult.main.scripts //         }, jsvendor: { src: null, tpl: bundleResult.vendor.scripts }, css: { src: null, tpl: bundleResult.main.styles }, cssvendor: { src: null, tpl: bundleResult.vendor.styles } })) .pipe(gulp.dest('dist/')); }); 

and here is one of the injects in index.html


 <!-- build:js --> <script src="js/app.js"></script> <!-- inject:js --> <script src="/js/investigator/common.js"></script> <script src="/js/investigator/apiVersion/apiVersionController.js"></script> <script src="/js/investigator/apiVersion/apiVersionService.js"></script> //... many many project controllers, directives etc <!-- endinject --> <!-- endbuild --> 

As you can see here, the build commentary: js tag is used in Gulp Task we have the corresponding object. By analogy, you should have tags for vendor and for sss:, and.
Files previously collected in bundle-assets will be embedded in place of these tags.


Also note that there is a tag inside the tag. I use it to implement all controllers, directives and all the other own project files separately:


 gulp.task('inject-separately', function () { var targets = gulp.src(['index.html'], { base: '' }); var sources = gulp.src(['js/investigator/**/*.js', 'css/investigator/**/*.css'], { read: false }); return targets.pipe(inject(sources)) .pipe(gulp.dest('')); }); 

The advantage of this approach is that you do not need to use watch. Personally, I watch. I often like to save the file after I finish writing some thought, and there are a lot of source codes in the project and sometimes I notice a delay in building the build, and besides, in any case, you have very little, but still to wait.


On many projects I have come across an approach in which on the prod server, there was an assembly of minified bundles, and in dev development everything merged into one file but without minification. In any case, the build goes and there is a slight delay, and besides, with this approach, I will get an error like:


 ```NullRefException at main.js.1234:12``` 

and by inserting the change files, the changes are immediately picked up by the browser and I get the exact file name and line number of the program text where the exception occurred.


The only thing that when creating a new file in the project, you need to run inject-separate again.


')

Source: https://habr.com/ru/post/334488/


All Articles