r3plica
r3plica

Reputation: 13367

AngularJS yo grunt serve problems resolving templates

I swapped to yo angular to help with my SPA. In the most part it works fine. I had to update a lot of packages and in some places remove depreciated versions. The problem I have now is that while using grunt serve there are a few references that are either missing or pointing to the wrong directory.

The first one of these is my custom datepicker control template. It overrides the bootstrap version with my own. Like I have mentioned, when built and deployed it works fine, but when testing it uses the default bootstrap template.

The second issue is with font-awesome. Same issue, when built and deployed it works fine. But when testing it doesn't find the files.

My Grunt file looks like this:

// Generated on 2017-12-03 using generator-angular 0.16.0
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {

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

  // Automatically load required Grunt tasks
  require('jit-grunt')(grunt, {
    useminPrepare: 'grunt-usemin',
    ngtemplates: 'grunt-angular-templates',
    cdnify: 'grunt-google-cdn'
  });

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

  var modRewrite = require('connect-modrewrite');
  var serveStatic = require('serve-static');

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

    // Project settings
    yeoman: appConfig,

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/app/**/*.js'],
        tasks: ['newer:jshint:all', 'newer:jscs:all'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      jsTest: {
        files: ['test/spec/**/*.js'],
        tasks: ['newer:jshint:test', 'newer:jscs:test', 'karma']
      },
      sass: {
        files: ['<%= yeoman.app %>/styles/**/*.{scss,sass}'],
        tasks: ['sass:server', 'autoprefixer']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/**/*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // 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: 35729
      },
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']),                        
              serveStatic('.tmp'),
              connect().use(
                '/bower_components',
                serveStatic('./bower_components')
              ),
              connect().use(
                '/app/styles',
                serveStatic('./app/styles')
              ),
              serveStatic(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              serveStatic('.tmp'),
              serveStatic('test'),
              connect().use(
                '/bower_components',
                serveStatic('./bower_components')
              ),
              serveStatic(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: {
        src: [
          'Gruntfile.js',
          //'<%= yeoman.app %>/app/{,*/}*.js'
        ]
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/spec/{,*/}*.js']
      }
    },

    // Make sure code styles are up to par
    jscs: {
      options: {
        config: '.jscsrc'
      },
      all: {
        src: [
          'Gruntfile.js',
          '<%= yeoman.app %>/{,*/}*.js'
        ]
      },
      test: {
        src: ['test/spec/{,*/}*.js']
      }
    },

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

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

    // Automatically inject my components into index.html
    injector: {
      options: {
        template: '<%= yeoman.app %>/index.html'
      },
      scripts: {
        options: {
          transform: function (filePath) {
              return '<script src="' + filePath.replace('/src/', '') + '"></script>';
          }
        },
        files: {
          '<%= yeoman.app %>/index.html': [
            '<%= yeoman.app %>/app/app.module.js',
            '<%= yeoman.app %>/app/**/*module.js',
            '<%= yeoman.app %>/app/**/*constants.js',
            '<%= yeoman.app %>/app/**/*service.js',
            '<%= yeoman.app %>/app/**/*routes.js',
            '<%= yeoman.app %>/app/**/*.js'
          ]
        }
      },
      styles: {
        options: {
          transform: function (filePath) {
              return '<link rel="stylesheet" href="' + filePath.replace('/.tmp/', '') + '" />';
          }
        },
        files: {
          '<%= yeoman.app %>/index.html': [
            '.tmp/styles/**/*.css'
          ]
        }
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        exclude: [
          /jquery/,
          /markerclustererplus/,
          /google-maps-utility-library-v3-/,
          /js-rich-marker/,
          /angular-mocks/,
          /bootstrap-sass-official/          
        ],
        ignorePath:  /\.\.\//
      },
      test: {
        devDependencies: true,
        src: '<%= karma.unit.configFile %>',
        ignorePath:  /\.\.\//,
        fileTypes:{
          js: {
            block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
              detect: {
                js: /'(.*\.js)'/gi
              },              
              replace: {
                js: '\'{{filePath}}\','
              }
            }
          }
      }
    }, 

    // Compiles Sass to CSS and generates necessary files if requested
    sass: {
      options: {
          includePaths: [
              'bower_components'
          ]
      },
      dist: {
          files: [{
              expand: true,
              cwd: '<%= yeoman.app %>/styles',
              src: ['*.scss'],
              dest: '.tmp/styles',
              ext: '.css'
          }]
      },
      server: {
          files: [{
              expand: true,
              cwd: '<%= yeoman.app %>/styles',
              src: ['*.scss'],
              dest: '.tmp/styles',
              ext: '.css'
          }]
      }
  },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= yeoman.dist %>/scripts/{,*/}*.js',
          '<%= yeoman.dist %>/styles/{,*/}*.css',
          '<%= yeoman.dist %>//images/**/*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= yeoman.dist %>/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.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>',
        flow: {
          html: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      js: ['<%= yeoman.dist %>/scripts/{,*/}*.js'],
      options: {
        assetsDirs: [
          '<%= yeoman.dist %>',
          '<%= yeoman.dist %>/images',
          '<%= yeoman.dist %>/styles'
        ],
        patterns: {
          js: [[/(images\/[^''""]*\.(png|jpg|jpeg|gif|webp|svg))/g, 'Replacing references to images']]
        }
      }
    },

    // The following *-min tasks will produce minified files in the dist folder
    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/app/app.js': [
    //         '<%= yeoman.dist %>/app/app'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '**/*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

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

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

    ngtemplates: {
      dist: {
        options: {
          module: 'sapphire',
          htmlmin: '<%= htmlmin.dist.options %>',
          usemin: 'scripts/scripts.js'
        },
        cwd: '<%= yeoman.app %>',
        src: [
          'app/**/*.html',
          'uib/**/*.html'
        ],
        dest: '.tmp/templateCache.js'
      }
    },

    // ng-annotate tries to make the code safe for minification automatically
    // by using the Angular long form for dependency injection.
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: '*.js',
          dest: '.tmp/concat/scripts'
        }]
      }
    },

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

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '*.html',
            'web.config',
            '/images/{,*/}*.{webp}',
            'styles/fonts/{,*/}*.*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }, {
          expand: true,
          cwd: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/',
          src: '*',
          dest: '<%= yeoman.dist %>/fonts'
        },
        {
          expand: true,
          cwd: 'bower_components/components-font-awesome/fonts/',
          src: '*',
          dest: '<%= yeoman.dist %>/fonts'
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

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

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


  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

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

  grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve:' + target]);
  });

  grunt.registerTask('test', [
    'clean:server',
    'wiredep',
    'injector',
    'concurrent:test',
    'postcss',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'wiredep',
    'injector',
    'useminPrepare',
    'concurrent:dist',
    'postcss',
    'ngtemplates',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    //'htmlmin'
  ]);

  grunt.registerTask('default', [
    'newer:jshint',
    'newer:jscs',
    'test',
    'build'
  ]);
};

And my source index.html file looks like this:

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title ng-bind="'Sapphire | ' + $state.current.data.pageTitle"></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
  <base href="/">
  <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
  <!-- build:css(.) styles/vendor.css -->
  <!-- bower:css -->
  <link rel="stylesheet" href="bower_components/angular-loading-bar/build/loading-bar.css" />
  <link rel="stylesheet" href="bower_components/angular-ui-select/dist/select.css" />
  <link rel="stylesheet" href="bower_components/ng-notify/src/styles/ng-notify.css" />
  <link rel="stylesheet" href="bower_components/components-font-awesome/css/font-awesome.css" />
  <!-- endbower -->
  <!-- endbuild -->
  <!-- build:css(.tmp) styles/core.css -->
  <!-- injector:css -->
  <link rel="stylesheet" href="styles/core.css" />
  <link rel="stylesheet" href="styles/print.css" />
  <!-- endinjector -->
  <!-- endbuild -->
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
</head>

<body ng-app="sapphire" ng-controller="IdleController">
  <!--[if lte IE 8]>
      <p class="browsehappy"></script> to improve your experience.</p>
    <![endif]-->

  <div class="cssload" ajax-loader>
    <div class="cssload-spin-box"></div>
  </div>

  <div snow="{ 'start': '01/12', end: '15/01' }" options="$options">
    <div class="page-header" ng-include="'app/includes/header.html'"></div>
    <section class="page metro" ui-view metro ng-if="!forbidden"></section>

    <div class="alert alert-danger" ng-cloak ng-if="forbidden">
      <p>
        </script>.</p>
    </div>
  </div>

  <script src='//maps.googleapis.com/maps/api/js?key=AIzaSyBj2GP_dnRkgrupIRMqe3nI8ZJlT4wmYPU'></script>

  <!-- build:js(.) scripts/vendor.js -->
  <!-- bower:js -->
  <script src="bower_components/angular/angular.js"></script>
  <script src="bower_components/angular-animate/angular-animate.js"></script>
  <script src="bower_components/angular-barcode/dist/angular-barcode.min.js"></script>
  <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
  <script src="bower_components/angular-cookies/angular-cookies.js"></script>
  <script src="bower_components/angular-simple-logger/dist/angular-simple-logger.js"></script>
  <script src="bower_components/lodash/lodash.js"></script>
  <script src="bower_components/angular-google-maps/dist/angular-google-maps.js"></script>
  <script src="bower_components/angular-loading-bar/build/loading-bar.js"></script>
  <script src="bower_components/angular-resource/angular-resource.js"></script>
  <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
  <script src="bower_components/angular-simple-cache/dist/simpleCache.js"></script>
  <script src="bower_components/angular-touch/angular-touch.js"></script>
  <script src="bower_components/angular-ui-mask/dist/mask.js"></script>
  <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
  <script src="bower_components/angular-ui-select/dist/select.js"></script>
  <script src="bower_components/newrelic-timing/newrelic-timing.js"></script>
  <script src="bower_components/newrelic-timing/newrelic-timing-angular.js"></script>
  <script src="bower_components/ng-idle/angular-idle.js"></script>
  <script src="bower_components/ng-notify/src/scripts/ng-notify.js"></script>
  <script src="bower_components/vkbeautify/vkBeautify.js"></script>
  <!-- endbower -->
  <!-- endbuild -->

  <!-- build:js({.tmp,src}) scripts/scripts.js -->
  <!-- injector:js -->
  <script src="app/app.module.js"></script>
  <!-- removed for brevity -->
  <!-- endinjector -->
  <!-- endbuild -->
</body>

</html>

As I am new to the angular generator, there have been some issues getting things to work, but like i have mentioned most of it is fine. I know there is a lot of code there but I am hoping that someone has had a similar issue and know exactly what the solution is.

Upvotes: 1

Views: 183

Answers (0)

Related Questions