javascript - grunt 构建后 Angular 模块不可用

标签 javascript angularjs gruntjs yeoman

我对 angular、grunt、bower、node 和所有这些东西还很陌生,我在尝试使用 grunt 构建我的项目时遇到了问题。

我使用了 angular-php yeoman 生成器,它基于 generator-angular,我一直在使用 grunt serve 进行开发,没有任何问题。

当我尝试使用grunt build 构建用于生产的项目时,问题就来了。该过程运行正常,但是当我尝试加载应用程序时,我在控制台中收到此错误:

vendor.d4e4dfe8.js:10420 Uncaught Error: [$injector:modulerr] Failed to instantiate module lossanroquerApp due to:
Error: [$injector:modulerr] Failed to instantiate module uiGmapgoogle-maps due to:
Error: [$injector:nomod] Module 'uiGmapgoogle-maps' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.5.7/$injector/nomod?p0=uiGmapgoogle-maps
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:10420:12
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:12427:17
    at ensure (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12351:38)
    at module (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12425:14)
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14960:22
    at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
    at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14961:40
    at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
    at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
http://errors.angularjs.org/1.5.7/$injector/modulerr?p0=uiGmapgoogle-maps&p…0(http%3A%2F%2Flocalhost%3A8888%2Fscripts%2Fvendor.d4e4dfe8.js%3A14944%3A5)
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:10420:12
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14983:15
    at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
    at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
    at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14961:40
    at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
    at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
    at createInjector (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14866:19)
    at doBootstrap (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12103:20)
    at bootstrap (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12124:12)
http://errors.angularjs.org/1.5.7/$injector/modulerr?p0=lossanroquerApp&p1=…(http%3A%2F%2Flocalhost%3A8888%2Fscripts%2Fvendor.d4e4dfe8.js%3A12124%3A12)

我调查了为什么会发生这种情况,并且我知道 angular 试图在定义/加载模块之前加载它。我检查了 vendor.js 文件以防模块丢失,但模块在脚本文件中。此外,我还禁用了缩小和丑化任务,以确保没有任何损坏。

这个错误发生在各种模块中,因为我试图更改 index.html 中脚本的顺序,当我修复一个时,它发生在另一个上。

这是我的实际索引。

<!doctype html>
<html class="no-js">
  <head>
    <meta charset="utf-8">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <!-- 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/textAngular/dist/textAngular.css" />
    <link rel="stylesheet" href="bower_components/angular-tooltips/dist/angular-tooltips.min.css" />
    <!-- endbower -->
    <!-- endbuild -->
    <!-- build:css(.tmp) styles/main.css -->
    <link rel="stylesheet" href="styles/main.css">
    <link rel="stylesheet" href="styles/welcome.css">
    <link rel="stylesheet" href="styles/generic.css">
    <link rel="stylesheet" href="styles/player.css">
    <link rel="stylesheet" href="styles/news.css">
    <link rel="stylesheet" href="styles/tour.css">
    <link rel="stylesheet" href="styles/discography.css">
    <link rel="stylesheet" href="styles/gallery.css">
    <link rel="stylesheet" href="styles/video.css">
    <!-- endbuild -->

      <base href="/">
  </head>
  <body ng-app="lossanroquerApp">
      <div class="background-image" ng-class="[{true: 'bgtransition'}[welcome], {true: 'unblurred'}[fromWelcome]]"></div>
    <!--[if lt IE 7]>
      <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
    <![endif]-->

    <!-- Add your site or application content here -->
    <div id="mainView" class="{{pageClass}} fromWelcome-{{fromWelcome}}" transitionend="cleanFromWelcome" ui-view></div>
    <div class="playerMainContainer" ng-include="'views/player.html'" ></div>


    <!-- Google Analytics: change UA-XXXXX-X to be your site's ID -->
     <script>
       (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
       (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
       m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
       })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

       ga('create', 'UA-XXXXX-X');
       ga('send', 'pageview');
    </script>

    <!--[if lt IE 9]>
    <script src="bower_components/es5-shim/es5-shim.js"></script>
    <script src="bower_components/json3/lib/json3.min.js"></script>
    <![endif]-->

    <!-- build:js(.) scripts/vendor.js -->
    <!-- bower:js -->
    <script src="bower_components/jquery/dist/jquery.js"></script>
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/json3/lib/json3.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/affix.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/alert.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/button.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/carousel.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/collapse.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/dropdown.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tab.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/transition.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/scrollspy.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/modal.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tooltip.js"></script>
    <script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/popover.js"></script>
    <script src="bower_components/angular-resource/angular-resource.js"></script>
    <script src="bower_components/angular-cookies/angular-cookies.js"></script>
    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
    <script src="bower_components/angular-animate/angular-animate.js"></script>
    <script src="bower_components/angular-touch/angular-touch.js"></script>
    <script src="bower_components/angular-route/angular-route.js"></script>
    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
    <script src="bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js"></script>
    <script src="bower_components/animation-frame/AnimationFrame.js"></script>
    <script src="bower_components/lodash/lodash.js"></script>
    <script src="bower_components/shifty/dist/shifty.min.js"></script>
    <script src="bower_components/underscore/underscore.js"></script>
    <script src="bower_components/rekapi/dist/rekapi.min.js"></script>
    <script src="bower_components/spark-scroll/src/spark-scroll.js"></script>
    <script src="bower_components/angular-fontawesome/dist/angular-fontawesome.js"></script>
    <script src="bower_components/rangy/rangy-core.js"></script>
    <script src="bower_components/rangy/rangy-classapplier.js"></script>
    <script src="bower_components/rangy/rangy-highlighter.js"></script>
    <script src="bower_components/rangy/rangy-selectionsaverestore.js"></script>
    <script src="bower_components/rangy/rangy-serializer.js"></script>
    <script src="bower_components/rangy/rangy-textrange.js"></script>
    <script src="bower_components/textAngular/dist/textAngular.js"></script>
    <script src="bower_components/textAngular/dist/textAngular-sanitize.js"></script>
    <script src="bower_components/textAngular/dist/textAngularSetup.js"></script>
    <script src="bower_components/amplitude/js/amplitude.js"></script>
    <script src="bower_components/angular-socialshare/dist/angular-socialshare.min.js"></script>
    <script src="bower_components/angular-tooltips/dist/angular-tooltips.min.js"></script>
    <script src="bower_components/angular-simple-logger/dist/angular-simple-logger.js"></script>
    <script src="bower_components/markerclustererplus/src/markerclusterer.js"></script>
    <script src="bower_components/google-maps-utility-library-v3-markerwithlabel/dist/markerwithlabel.js"></script>
    <script src="bower_components/google-maps-utility-library-v3-infobox/dist/infobox.js"></script>
    <script src="bower_components/google-maps-utility-library-v3-keydragzoom/dist/keydragzoom.js"></script>
    <script src="bower_components/js-rich-marker/src/richmarker.js"></script>
    <script src="bower_components/angular-google-maps/dist/angular-google-maps.js"></script>
    <script src="bower_components/angular-youtube-api-factory/dist/angular-youtube-api-factory.min.js"></script>
    <script src="bower_components/ng-youtube-embed/src/ng-youtube-embed.js"></script>
    <!-- endbower -->
      <script src="node_modules/angulargrid/angulargrid.min.js"></script>
    <!-- endbuild -->


        <!-- build:js({.tmp,app}) scripts/scripts.js -->
        <script src="scripts/app.js"></script>
        <script src="scripts/controllers/main.js"></script>
        <script src="scripts/controllers/about.js"></script>
        <script src="scripts/controllers/welcome.js"></script>
        <script src="scripts/directives/transitionend.js"></script>
        <script src="scripts/controllers/home.js"></script>
        <script src="scripts/controllers/player.js"></script>
        <script src="scripts/services/newsservice.js"></script>
        <script src="scripts/directives/mobileonly.js"></script>
        <script src="scripts/controllers/news.js"></script>
        <script src="scripts/services/shows.js"></script>
        <script src="scripts/controllers/tour.js"></script>
        <script src="scripts/controllers/discography.js"></script>
        <script src="scripts/services/albums.js"></script>
        <script src="scripts/directives/initamplitudeonlast.js"></script>
        <script src="scripts/controllers/gallery.js"></script>
        <script src="scripts/controllers/video.js"></script>
        <script src="scripts/controllers/bio.js"></script>
        <script src="scripts/controllers/contact.js"></script>
        <script src="scripts/directives/loading.js"></script>
        <script src="scripts/services/gallery.js"></script>
        <!-- endbuild -->
</body>
</html>

我的 app.js:

'use strict';

angular
  .module('lossanroquerApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
    'ui.router',
    'gilbox.sparkScroll',
    'picardy.fontawesome',
    '720kb.socialshare',
    '720kb.tooltips',
    'uiGmapgoogle-maps',
    'infinite-scroll',
    'angularGrid',
    'jtt_youtube',
    'ngYoutubeEmbed'
  ])
  .config(function ($stateProvider, $urlRouterProvider, $locationProvider
    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    }).hashPrefix('!');


    $urlRouterProvider.otherwise('/home');

    $stateProvider
      .state('main', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      });
  });

angular.module('infinite-scroll').value('THROTTLE_MILLISECONDS', 250);

还有我的 Gruntfile.js

// Generated on 2016-06-21 using generator-angular-php 0.6.3
'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) {

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

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

  // grunt-connect-proxy middleware to serve PHP
  var proxyMiddleware = function (connect, options) {
    var middlewares = [];
    var directory = options.directory || options.base[options.base.length - 1];
    if (!Array.isArray(options.base)) {
      options.base = [options.base];
    }

    // Setup the proxy
    middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest);

    options.base.forEach(function(base) {
      // Serve static files.
      middlewares.push(connect.static(base));
    });

    // Make directory browse-able.
    middlewares.push(connect.directory(directory));

    return middlewares;
  };

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

  // 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 %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      },
      jsTest: {
        files: ['test/spec/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      compass: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass:server', 'autoprefixer']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/api/{,{config,src,tests}/**/}/*',
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      },
      phpTest: {
        files: ['<%= yeoman.app %>/api/{,{config,src,tests}/**/}/*'],
        tasks: ['shell:phpTest']
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9024,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35742
      },
      proxies: [
        {
          context: '/api',
          host: 'localhost',
          port: '<%= php.options.port %>'
        }
      ],
      livereload: {
        options: {
          open: true,
          middleware: function (connect, options) {
              var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
            return [
//              modRewrite([
//                '!\\.html|\\.js|\\.css|\\.png$ /index.html [L]'
//              ]),
                require('connect-modrewrite')([
                    '^/api/(.*) - [L]',
                    '.*/api/(.*) /api/$1',
                    '!(\\..+)$ /index.html ',
                ]) ,
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ].concat(proxyMiddleware(connect, options))
            .concat(optBase.map(function(path){ return connect.static(path); }));
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect, options) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ].concat(proxyMiddleware(connect, options));
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>',
          middleware: proxyMiddleware
        }
      }
    },

    // PHP built-in server
    php: {
      options: {
        port: 8000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '127.0.0.1',
        router: 'api/index.php'
      },
      server: {
        options: {
          base: '<%= yeoman.app %>',
        }
      },
      dist: {
        options: {
          base: '<%= yeoman.dist %>',
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: {
        src: [
          'Gruntfile.js',
          '<%= yeoman.app %>/scripts/{,*/}*.js'
        ]
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        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
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      options: {
        cwd: ''
      },
      app: {
        src: ['<%= yeoman.app %>/index.html'],
        ignorePath:  /..\//
      },
      sass: {
        src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        ignorePath: /(\.\.\/){1,2}bower_components\//
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    compass: {
      options: {
        sassDir: '<%= yeoman.app %>/styles',
        cssDir: '.tmp/styles',
        generatedImagesDir: '.tmp/images/generated',
        imagesDir: '<%= yeoman.app %>/images',
        javascriptsDir: '<%= yeoman.app %>/scripts',
        fontsDir: '<%= yeoman.app %>/styles/fonts',
        importPath: './bower_components',
        httpImagesPath: '/images',
        httpGeneratedImagesPath: '/images/generated',
        httpFontsPath: '/styles/fonts',
        relativeAssets: false,
        assetCacheBuster: false,
        raw: 'Sass::Script::Number.precision = 10\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%= yeoman.dist %>/images/generated'
        }
      },
      server: {
        options: {
          debugInfo: true
        }
      }
    },

    // 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 %>/styles/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'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/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 %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // 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,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html', 'views/{,*/}*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    // ngmin tries to make the code safe for minification automatically by
    // using the Angular long form for dependency injection. It doesn't work on
    // things like resolve or inject so those have to be done manually.
    ngmin: {
      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: [
            'api/{{config,src,vendor}/**,index.php,.htaccess}',
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'images/{,*/}*.{webp}',
            'fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }, {
          expand: true,
          cwd: '.',
          src: 'bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/*',
          dest: '<%= yeoman.dist %>'
        }]
      },
      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: [
        'compass:server'
      ],
      test: [
        'compass'
      ],
      dist: [
        'compass:dist',
        'imagemin',
        'svgmin'
      ]
    },

    shell: {
      options: {
        stdout: true,
        stderr: true,
        failOnError: true
      },
      phpTest: {
        command: 'make --directory <%= yeoman.app %>/api test'
      },
      phpUpdate: {
        command: 'make --directory <%= yeoman.app %>/api update'
      }
    },

    // 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',
        'configureProxies',
        'php:dist',
        'connect:dist:keepalive'
      ]);
    }

    grunt.task.run([
      'clean:server',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'configureProxies',
      'php: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',
    'shell:phpTest',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'shell:phpUpdate',
    'wiredep',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
//    'ngmin',
    'copy:dist',
//    'cdnify',
//    'cssmin',
//    'uglify',
    'filerev',
    'usemin',
//    'htmlmin'
  ]);

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

谢谢你的帮助

最佳答案

好吧,最后我又做了很多实验和测试,终于找到了问题所在。与依赖版本 (lodash) 发生冲突。 有两个依赖项,ui-google-maps 和 spark-scroll,它们需要两个不同版本的 lodash,不知何故导致某些模块无法正确加载。现在我已经删除了 ui-google-maps 依赖项并重新安装了我的 bower_components。

关于javascript - grunt 构建后 Angular 模块不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39389801/

相关文章:

javascript - 使用 moment js 创建一个包含星期几和一天中几小时的数组?

javascript - grunt-jsxhint 和 jsxhint 的行为不一样

javascript - PHP项目的Gulp/Grunt文件夹结构与实践

javascript - React - 从函数更改路线

javascript - 禁用输入按钮中的回车键

javascript - 每个函数只触发一次

angularjs - 修改 ng-include 指令

javascript - ng click inside li <a> 元素在 ng-repeat 中不起作用

javascript - 为什么 grunt 不运行我的任务?

javascript - D3 将多个 child 添加到同一个 parent