Gulp - How to control processing order with gulp -concat

I am trying to create combined JavaScript and CSS resources into a single file using gulp -concat using something like this:

var concatjs = gulp .src(['app/js/app.js','app/js/*Controller.js', 'app/js/*Service.js']) .pipe(concat('app.js')) .pipe(gulp.dest('build')); 

I get a bundled file with this, but the order of the javascript files embedded in the combined output file is random - in this case, the controllers appear in front of the original app.js file, which causes problems when trying to download an Angular application waiting for app.js to load any of the associated resources. Likewise, for CSS resources that combine ultimately in random order, and again, order is somewhat important - i.e. bootstrap must be loaded before the theme and any custom stylesheets.

How can I customize the concatenation process so that the order remains intact?

Update Thus, it turns out that the order above really works, explicitly indicating the order of the files in the array of file specifications. Therefore, in this case, the most important thing is to first specify app / js / app.js, and then leave the rest of the scripts in which order does not matter in any order.

The reason I did not see this behavior (Duh!) Is because Gulp Watch was launched, and the gulpfile.js update didn’t actually affect the output. Restarting Gulp updated the script. Neophyte Error ...

Other thoughts: Still interesting, is this the right place to indicate the assembly order? It seems you are now stuffing the application logic (boot order) into a script assembly that does not seem to be correct. Are there other approaches to solving this issue?

+6
source share
2 answers

For an angular application similar to your example (and dependency management), I usually use this syntax: gulp.src(['app\js\app.js', 'app\js\**\*.js']) .

You can also use only gulp.src('app\js\**\*.js') if your app.js file is the first in alphabetical order.

I see your thought about moving the order of the download file to the assembly script: I had the same feeling until I started using gulp-inject to inject links to unminified files in my index.html during development and injecting related, minified and versions in production index file. Using this solution to order glob throughout my entire development cycle has done so for me so much that I no longer think about it.

Finally, a possible solution for this “order smell” can use browserify , but for me it’s just complicating the architecture of the angular application: in the end, as you said, you just need one specific file to be called before all the others.

+5
source

For my js, I use a specific structure / naming convention that helps. I divided it into directories using a function, where each “function” is then treated as a separate encapsulated module.

So, for my projects, I have

 app/js/ - app.js - app.routes.js - app.config.js /core/ - core.js - core.controllers.js - core.services.js /test/ - .spec.js test files for module here /feature1/ - feature1.js - feature1.controllers.js /feature2/ - feature2.js - feature2.controllers.js ... 

Thus, each directory has a file with the same name, which simply has an initial module definition in it, which is all that app.js has in it for the entire application. So for feature1.js

 angular.module('feature1', []) 

and then subsequent files in the module extract the module and add things to it (controllers / services / factories, etc.).

 angular.module('feature1') .controller(....) 


In any case, I get to the point ...

Since I have a predefined structure and know that a particular file should go first for each module, I can use the function below to sort everything in order before it is processed using gulp.

This function depends on npm install file and npm install path

 function getModules(src, app, ignore) { var modules = []; file.walkSync(src, function(dirPath, dirs, files) { if(files.length < 1) return; var dir = path.basename(dirPath) module; if(ignore.indexOf(dir) === -1) { module = dirPath === src ? app : dir; files = files.sort(function(a, b) { return path.basename(a, '.js') === module ? -1 : 1; }) .filter(function(value) { return value.indexOf('.') !== 0; }) .map(function(value) { return path.join(dirPath, value); }) modules = modules.concat(files); } }) return modules; } 

It scans the directory structure passed to it, takes the files from each directory (or module) and sorts them in the correct order, ensuring that the module definition file is always the first. It also ignores any directories that appear in the ignore array, and removes all hidden files starting with "."

Use will be

 getModules(src, appName, ignoreDirs); 
  • src is the directory you want to unsubscribe from
  • appName is the name of your app.js file - so "application"
  • ignoreDirs is an array of directory names that you would like to ignore.

So

 getModules('app/js', 'app', ['test']); 

And it returns an array of all the files in your application in the correct order, which can then be used as follows:

 gulp.task('scripts', function() { var modules = getModules('app/js', 'app', ['test']); return gulp.src(modules) .pipe(concat('app.js')) .pipe(gulp.dest('build')); }); 
+3
source

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


All Articles