1
\$\begingroup\$

I've recently started switching from JQuery to Angular and it's awesome at making my HTML expressive and easy to read but every reusable module I make has its own script which leads to a massive script loading area. I suppose I could closure compile them or something but is there a better way?

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Control Page</title>
    <link rel="stylesheet" href="assets/css/bootstrap.min.css">
    <link rel="stylesheet" href="assets/css/bootstrap-switch.min.css">
    <link rel="stylesheet" href="assets/css/bootstrap-theme.css">
    <link rel="stylesheet" href="assets/css/navbar.css">
    <link rel="stylesheet" href="assets/css/popup.css">

    <script src="assets/js/lib/jquery.min.js"></script>
    <script src="assets/js/lib/angular.min.js"></script>

    <script src="assets/js/lib/bootstrap.min.js"></script>
    <script src="assets/js/lib/ui-bootstrap-tpls.min.js"></script>
    <script src="assets/js/lib/angular-bootstrap-switch.min.js"></script>
    <script src="assets/js/lib/bootstrap-switch.min.js"></script>

    <script src="assets/modules/translate-filter.js"></script>
    <script src="assets/modules/review-box.js"></script>
    <script src="assets/modules/enable-switch.js"></script>
    <script src="assets/modules/navbar.js"></script>
    <script src="assets/modules/extension-interface.js"></script>
    <script src="assets/modules/status-monitor.js"></script>
    <script src="assets/modules/state-monitor.js"></script>

    <script src="assets/js/control-ui.js"></script>
</head>
<body data-ng-app="controlPage">

<div class="container-fluid" ng-controller="ControlPageCtrl">
    <extension-navbar></extension-navbar>
    <div class="jumbotron">
        <status-monitor-area></status-monitor-area>
        <hr>
        <div>
            <div class="row">
                <div class="col-xs-8">
                    <state-message></state-message>
                </div>
                <div class="col-xs-4">
                    <enable-switch></enable-switch>
                </div>
            </div>
            <state-progress-bar></state-progress-bar>
            <div ng-show="ratingStore.">
                <review-request></review-request>
            </div>
        </div>
    </div>
</div>

</body>
</html>
\$\endgroup\$
  • \$\begingroup\$ Are familiar with build workflows/task runners, e.g. Grunt or Gulp, or even codekit? \$\endgroup\$ – glennanthonyb Jun 18 '15 at 15:39
  • \$\begingroup\$ No. What can that do for me? \$\endgroup\$ – Josh Horowitz Jun 22 '15 at 4:52
1
\$\begingroup\$

For starters, they will take all your files based on a pattern and "compile" them down to a single file - no more adding lots of script references. That's just the tip of iceberg.

I happen to prefer Gulp. Take a look at the npm packages for gulp. For what you're trying to achieve, start with gulp-concat and gulp-livereload.

Follow the instructions here to get you started.

Here's an example that uses a watch to keep an eye on file changes, and, when detected, initiates a 'build' tasks, which will the livereload your page (requires the livereload plugin in chrome/firefox/whatever).

You will then only need a reference to the ./public/js/app.js file in your index.html file.

Note the build task uses two different globs, this is to ensure, in the case of AngularJS, that the module definition file is always the first thing in the concatenated file.

var gulp = require('gulp');
var concat = require('gulp-concat');
var livereload = require('gulp-livereload');

gulp.task('build', function() {
	return gulp.src(['src/**/*.module.js', 'src/**/*.js'])
		.pipe(concat('app.js'))
		.pipe(gulp.dest('./public/js'))
		.pipe(livereload());
});

gulp.task('default', ['build'], function() {
	livereload.listen({
    start: true
  });

 	gulp.watch('src/**/*.js', ['build']);
});

Like a said, this is just the tip of the iceberg. There are tons of examples of very powerful workflows using Gulp and Grunt out there.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I have some files in directories such as assets/js which have nothing to do with this specific page. Is there a way to create an app.js which only minifies the files that are called with <script src= and then create an app.html which only has <script src=app.js instead of all the other ones? \$\endgroup\$ – Josh Horowitz Jun 27 '15 at 21:56
  • \$\begingroup\$ I generally have at least two concatenated/compress JS files on a page - one for vendor files and the other for my code. There may also be files that need to be in the header - e.g. modernizr. Just create multiple build tasks in gulp with the appropriate gulp.src. \$\endgroup\$ – glennanthonyb Jun 29 '15 at 8:02
  • \$\begingroup\$ Even, you can manage the situation when the order of the included javascript files are matter. Eg. include jQuery before angular, to have the full version of Jquery, etc. Take a look at run-sequence, merge-stream, gulp-inject and stream-series modules of gulp. \$\endgroup\$ – SayusiAndo Aug 13 '15 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.