Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular-Fullstack - grunt build not including javascript files

OK I post this question on Angular-Fullstack's issue list on gitHub so you can check it out there too to see if there are any additional posts that aren't on here. git hub question

Basically I'm getting the following output in the console:

GET http://localhost:8080/assets/images/loading.gif 404 (Not Found) (index):60
GET http://localhost:8080/app/assignment-meeting/prepare-senior/candidate/profile/_profile-ctrl.js  (index):102
GET http://localhost:8080/app/assignment-meeting/prepare-senior/candidate-list/candidates-list-controller.js  (index):100
GET http://localhost:8080/app/assignment-meeting/prepare-senior/candidate/_candidate-ctrl.js  (index):101
GET http://localhost:8080/app/assignment-meeting/prepare-senior/candidate/summary/_summary-ctrl.js  (index):103
GET http://localhost:8080/app/home/home-controller.js  (index):104
GET http://localhost:8080/components/services/candidate-services.js  (index):109
GET http://localhost:8080/components/auth/User.js  (index):106
GET http://localhost:8080/app/routes.js  (index):105
GET http://localhost:8080/components/directives/napi-ck-editor.js  (index):108
GET http://localhost:8080/components/auth/user-service.js  (index):107
GET http://localhost:8080/components/services/http-helper.js  (index):110
GET http://localhost:8080/components/services/menu-services.js 404 (Not Found) 

It seems like grunt build can't find my script files located within the injector sections of my index.html page. If I recopy the originally created index.html file that the generator created and copy all of the code above the "Google Analytics" section over, then it will work fine. I don't understand why it doesn't work as it doesn't seem to show there being any actual difference in the code. The page doesn't show a single line being different. The only thing that I thought might be causing the problem is that the line endings might be getting changed when I commit it to git and then it has issues. Truthfully I'm in the dark on this one. I post this question on a couple different forms so I'm tired of retyping it...so if you want to read my git hub post (link above), it might be better worded.

Thanks for the help.

Update:

Sorry I should have attached my grunt file so it could be read and noted that there's a grunt.registerTask called "build." I didn't attach it because I haven't really changed it from the default one made by angular-fullstack and figure other could simply view that as a reference...but attaching it is simpler and better:

'use strict';

module.exports = function (grunt) {

    // Configurable paths for the application
    var appConfig = {
        app: require('./bower.json').appPath || 'client',
        dist: 'src/main/webapp'
    };

    // Load grunt tasks automatically, when needed
    require('jit-grunt')(grunt, {
        useminPrepare: 'grunt-usemin',
        ngtemplates: 'grunt-angular-templates',
        cdnify: 'grunt-google-cdn',
        protractor: 'grunt-protractor-runner',
        injector: 'grunt-asset-injector'
    });

//    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        pkg: grunt.file.readJSON('package.json'),
        yeoman: {
            // configurable paths
            client: require('./bower.json').appPath || 'client',
            dist: 'src/main/webapp'
        },
        watch: {
            bower: {
                files: ['bower.json'],
                tasks: ['wiredep']
            },
            injectJS: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.js',
                    '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '!<%= yeoman.client %>/{app,components}/**/*.mock.js',
                    '!<%= yeoman.client %>/app/app.js'],
                tasks: ['injector:scripts']
            },
            injectCss: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.css'
                ],
                tasks: ['injector:css']
            },
            jsTest: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '<%= yeoman.client %>/{app,components}/**/*.mock.js'
                ],
                tasks: ['newer:jshint:all', 'karma']
            },
            injectSass: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
                tasks: ['injector:sass']
            },
            sass: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}'],
                tasks: ['sass', 'autoprefixer']
            },
            gruntfile: {
                files: ['Gruntfile.js']
            },
            livereload: {
                files: [
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.css',
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.html',
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
                    '!{.tmp,<%= yeoman.client %>}{app,components}/**/*.spec.js',
                    '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js',
                    '<%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
                ],
                options: {
                    livereload: true
                }
            }
        },

        // The actual grunt server settings
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    open: true,
                    middleware: function (connect) {
                        return [
                            connect.static('.tmp'),
                            connect().use(
                                '/client/bower_components',
                                connect.static('./client/bower_components')
                            ),
                            connect.static(appConfig.app)
                        ];
                    }
                }
            },
            test: {
                options: {
                    port: 9001,
                    middleware: function (connect) {
                        return [
                            connect.static('.tmp'),
                            connect.static('test'),
                            connect().use(
                                '/client/bower_components',
                                connect.static('./client/bower_components')
                            ),
                            connect.static(appConfig.app)
                        ];
                    }
                }
            },
            dist: {
                options: {
                    open: true,
                    base: '<%= yeoman.dist %>'
                }
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '<%= yeoman.client %>/.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: [
                '<%= yeoman.client %>/{app,components}/**/*.js',
                '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
                '!<%= yeoman.client %>/{app,components}/**/*.mock.js'
            ],
            test: {
                src: [
                    '<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '<%= yeoman.client %>/{app,components}/**/*.mock.js'
                ]
            }
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [{
                    dot: true,
                    src: [
                        '.tmp',
                        '<%= yeoman.dist %>/*',
                        '!<%= yeoman.dist %>/.git*',
                        '!<%= yeoman.dist %>/.openshift',
                        '!<%= yeoman.dist %>/Procfile'
                    ]
                }]
            },
            server: '.tmp'
        },

        // Add vendor prefixed styles
        autoprefixer: {
            options: {
                browsers: ['last 1 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/',
                    src: '{,*/}*.css',
                    dest: '.tmp/'
                }]
            }
        },


        // Automatically inject Bower components into the app
        wiredep: {
            target: {
                src: '<%= yeoman.client %>/index.html',
                ignorePath: '<%= yeoman.client %>/',
                exclude: [/bootstrap-sass-official/, /bootstrap.js/, '/json3/', '/es5-shim/', /bootstrap.css/, /font-awesome.css/ ]
            }
        },

        // Renames files for browser caching purposes
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/public/{,*/}*.js',
                        '<%= yeoman.dist %>/public/{,*/}*.css',
                        '<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
                        '<%= yeoman.dist %>/public/assets/fonts/*'
                    ]
                }
            }
        },

        // Reads HTML for usemin blocks to enable smart builds that automatically
        // concat, minify and revision files. Creates configurations in memory so
        // additional tasks can operate on them
        useminPrepare: {
            html: ['<%= yeoman.client %>/index.html'],
            options: {
                dest: '<%= yeoman.dist %>/public',
                flow: {
                    html: {
                        steps: {
                            js: ['concat', 'uglifyjs'],
                            css: ['cssmin']
                        },
                        post: {}
                    }
                }
            }
        },
        cssmin: {
            options: {
                root: 'client'
            }
        },
        // Performs rewrites based on rev and the useminPrepare configuration
        usemin: {
            html: ['<%= yeoman.dist %>/public/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/public/{,*/}*.css'],
            js: ['<%= yeoman.dist %>/public/{,*/}*.js'],
            options: {
                assetsDirs: [
                    '<%= yeoman.dist %>/public',
                    '<%= yeoman.dist %>/public/assets/images'
                ],
                // This is so we update image references in our ng-templates
                patterns: {
                    js: [
                        [/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
                    ]
                }
            }
        },

        // The following *-min tasks produce minified files in the dist folder
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.client %>/assets/images',
                    src: '{,*/}*.{png,jpg,jpeg,gif}',
                    dest: '<%= yeoman.dist %>/public/assets/images'
                }]
            }
        },

//        htmlmin: {
//            dist: {
//                options: {
//                    collapseWhitespace: true,
//                    conservativeCollapse: true,
//                    collapseBooleanAttributes: true,
//                    removeCommentsFromCDATA: true,
//                    removeOptionalTags: true
//                },
//                files: [{
//                    expand: true,
//                    cwd: '<%= yeoman.dist %>',
//                    src: ['*.html', 'app/**/*.html'],
//                    dest: '<%= yeoman.dist %>'
//                }]
//            }
//        },
//        uglify: {
//           dist: {
//             files: {
//               '<%= yeoman.dist %>/scripts/scripts.js': [
//                 '<%= yeoman.dist %>/scripts/scripts.js'
//               ]
//             }
//           }
//        },

        svgmin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.client %>/assets/images',
                    src: '{,*/}*.svg',
                    dest: '<%= yeoman.dist %>/public/assets/images'
                }]
            }
        },

        // Allow the use of non-minsafe AngularJS files. Automatically makes it
        // minsafe compatible so Uglify does not destroy the ng references
        ngAnnotate: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '.tmp/concat',
                    src: '*/**.js',
                    dest: '.tmp/concat'
                }]
            }
        },

        // Package all the html partials into a single javascript payload
        ngtemplates: {
            options: {
                // This should be the name of your apps angular module
                module: 'napiRest',
                htmlmin: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeEmptyAttributes: true,
                    removeRedundantAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true
                },
                usemin: 'app/app.js'
            },
            main: {
                cwd: '<%= yeoman.client %>',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/templates.js'
            },
            tmp: {
                cwd: '.tmp',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/tmp-templates.js'
            }
        },

        // Replace Google CDN references
        cdnify: {
            dist: {
                html: ['<%= yeoman.dist %>/public/*.html']
            }
        },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.client %>',
                    dest: '<%= yeoman.dist %>/public',
                    src: [
                        '*.{ico,png,txt}',
                        '.htaccess',
                        'bower_components/**/*',
                        'assets/images/{,*/}*.{webp}',
                        'assets/fonts/**/*',
                        'index.html'
                    ]
                }, {
                    expand: true,
                    cwd: '.tmp/images',
                    dest: '<%= yeoman.dist %>/public/assets/images',
                    src: ['generated/*']
                }, {
                    expand: true,
                    dest: '<%= yeoman.dist %>',
                    src: [
                        'package.json'
                    ]
                }]
            },
            styles: {
                expand: true,
                cwd: '<%= yeoman.client %>',
                dest: '.tmp/',
                src: ['{app,components}/**/*.css']
            }
        },

        // Run some tasks in parallel to speed up the build process
        concurrent: {
            server: [
                'sass'
            ],
            test: [
                'sass'
            ],
            dist: [
                'sass',
                'imagemin',
                'svgmin'
            ]
        },

        // Test settings
        karma: {
            unit: {
                configFile: 'karma.conf.js',
                singleRun: true
            }
        },

        mochaTest: {
            options: {
                reporter: 'spec'
            },
            src: ['server/**/*.spec.js']
        },

        protractor: {
            options: {
                configFile: 'protractor.conf.js'
            },
            chrome: {
                options: {
                    args: {
                        browser: 'chrome'
                    }
                }
            }
        },


        // Compiles Sass to CSS
        sass: {
            server: {
                options: {
                    loadPath: [
                        '<%= yeoman.client %>/bower_components',
                        '<%= yeoman.client %>/app',
                        '<%= yeoman.client %>/components'
                    ],
                    compass: false
                },
                files: {
                    '.tmp/app/app.css' : '<%= yeoman.client %>/app/app.scss'
                }
            }
        },

        injector: {
            options: {

            },
            // Inject application script files into index.html (doesn't include bower)
            scripts: {
                options: {
                    transform: function(filePath) {
                        filePath = filePath.replace('/client/', '');
                        filePath = filePath.replace('/.tmp/', '');
                        return '<script src="' + filePath + '"></script>';
                    },
                    starttag: '<!-- injector:js -->',
                    endtag: '<!-- endinjector -->'
                },
                files: {
                    '<%= yeoman.client %>/index.html': [
                        ['{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
                            '!{.tmp,<%= yeoman.client %>}/app/app.js',
                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js',
                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js']
                    ]
                }
            },

            // Inject component scss into app.scss
            sass: {
                options: {
                    transform: function(filePath) {
                        filePath = filePath.replace('/client/app/', '');
                        filePath = filePath.replace('/client/components/', '');
                        return '@import \'' + filePath + '\';';
                    },
                    starttag: '// injector',
                    endtag: '// endinjector'
                },
                files: {
                    '<%= yeoman.client %>/app/app.scss': [
                        '<%= yeoman.client %>/{app,components}/**/*.{scss,sass}',
                        '!<%= yeoman.client %>/app/app.{scss,sass}'
                    ]
                }
            },

            // Inject component css into index.html
            css: {
                options: {
                    transform: function(filePath) {
                        filePath = filePath.replace('/client/', '');
                        filePath = filePath.replace('/.tmp/', '');
                        return '<link rel="stylesheet" href="' + filePath + '">';
                    },
                    starttag: '<!-- injector:css -->',
                    endtag: '<!-- endinjector -->'
                },
                files: {
                    '<%= yeoman.client %>/index.html': [
                        '<%= yeoman.client %>/{app,components}/**/*.css'
                    ]
                }
            }
        }
    });

    // Used for delaying livereload until after server has restarted
    grunt.registerTask('wait', function () {
        grunt.log.ok('Waiting for server reload...');

        var done = this.async();

        setTimeout(function () {
            grunt.log.writeln('Done waiting!');
            done();
        }, 3000);
    });


    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'wait', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'injector:sass',
            'concurrent:server',
            'injector',
            'wiredep',
            'autoprefixer',
            'connect:livereload',
            'wait',
            'watch'
        ]);
    });

    grunt.registerTask('server', function () {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve']);
    });

    grunt.registerTask('test', function(target) {
        if (target === 'client') {
            return grunt.task.run([
                'clean:server',
                'injector:sass',
                'concurrent:test',
                'injector',
                'autoprefixer',
                'karma'
            ]);
        }

        else if (target === 'e2e') {
            return grunt.task.run([
                'clean:server',
                'injector:sass',
                'concurrent:test',
                'injector',
                'wiredep',
                'autoprefixer',
                'connect:test',
                'protractor'
            ]);
        }

        else grunt.task.run([
                'test:client'
            ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'injector:sass',
        'concurrent:dist',
        'injector',
        'wiredep',
        'useminPrepare',
        'autoprefixer',
        'ngtemplates',
        'concat',
        'ngAnnotate',
        'copy:dist',
        'cdnify',
        'cssmin',
        'uglify',
        'rev',
        'usemin'
    ]);

    grunt.registerTask('default', [
        'newer:jshint',
        'test',
        'build'
    ]);
};
like image 214
BryceHayden Avatar asked Oct 10 '14 02:10

BryceHayden


2 Answers

I've encountered xactly the same problem here. After hours of file by file comparison. I've finally solved it. So I thought I would share what has worked for me.

I'm working on windows, and simply change the line ending to Unix style for "index.html" in my text editor (I'm using sublime text by the way) solve the problem. "Windows" line ending make the script bug it seems.

Hope that will help.

Meg4mi

like image 108
user2865790 Avatar answered Oct 20 '22 00:10

user2865790


It's because of grunt-injector line endings. See this issue.

To avoid that you could configure grunt injector to work with default grunt line endings:

injector: {
   options: {
      lineEnding: grunt.util.linefeed
   },
   ...
}

Doing that, you will have to configure your Git line endings setting in case you work on different platforms. Assuming you are on Windows and pulling a file from Linux, you will obtain after the injection process a mixed LF and CR/LF file (LF in all the HTML file and CR/LF bewteen <!-- injector:js --> tags) and the grunt-build plugin will not work.

You can use this Sublime Text plugin to see line endings on your file.

like image 23
Shingaz Avatar answered Oct 19 '22 23:10

Shingaz