2015-01-07 3 views
0

Я работаю над приложением AngularJS, используя Yeoman with Grunt. При использовании команды grunt serve проблем нет. Однако, когда я использую команду grunt и посмотреть на сайте, я получаю эти ошибки:Yeoman AngularJS Grunt нарушает модули

Uncaught Error: [$injector:modulerr] Failed to instantiate module webshopAdminApp due to: 
Error: [$injector:modulerr] Failed to instantiate module ui.slider due to: 
Error: [$injector:nomod] Module 'ui.slider' 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. 

Мой хрюкать файл:

// Generated on 2014-10-02 using generator-angular 0.9.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); 

    var modRewrite = require('connect-modrewrite'); 

    // 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'] 
     }, 
     styles: { 
     files: ['<%= yeoman.app %>/styles/{,*/}*.css'], 
     tasks: ['newer:copy:styles', '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: 9090, 
     // Change this to '0.0.0.0' to access the server from outside. 
     hostname: 'lumino.gidomanders.nl', 
     livereload: 35730 
     }, 
     livereload: { 
     options: { 
      open: true, 
      middleware: function (connect) { 
      return [ 
       modRewrite(['^[^\\.]*$ /index.html [L]']), //Matches everything that does not contain a '.' (period) 
       connect.static('.tmp'), 
       connect().use(
       '/bower_components', 
       connect.static('./bower_components') 
      ), 
       connect.static(appConfig.app) 
      ]; 
      } 
     } 
     }, 
     test: { 
     options: { 
      port: 9091, 
      middleware: function (connect) { 
      return [ 
       connect.static('.tmp'), 
       connect.static('test'), 
       connect().use(
       '/bower_components', 
       connect.static('./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: 'test/.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: '<%= yeoman.app %>/../' 
     }, 
     app: { 
     src: ['<%= yeoman.app %>/index.html'], 
     ignorePath: /\.\.\// 
     } 
    }, 

    // 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' 
     }], 
     options: { 
      cache: false 
     } 
     } 
    }, 

    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', '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: [ 
      '*.{ico,png,txt}', 
      '.htaccess', 
      '*.html', 
      'views/{,*/}*.html', 
      'views/{,*/*/}*.html', 
      'images/{,*/}*.{webp}', 
      'fonts/{,*/}*' 
      ] 
     }, { 
      expand: true, 
      cwd: '.tmp/images', 
      dest: '<%= yeoman.dist %>/images', 
      src: ['generated/*'] 
     }, { 
      expand: true, 
      cwd: 'bower_components/bootstrap/dist', 
      src: 'fonts/*', 
      dest: '<%= yeoman.dist %>' 
     }, { 
      expand: true, 
      cwd: 'bower_components/font-awesome', 
      src: 'fonts/*', 
      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: [ 
     'copy:styles' 
     ], 
     test: [ 
     'copy:styles' 
     ], 
     dist: [ 
     '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', 
     'concurrent:server', 
     'autoprefixer', 
     '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', 
    'concurrent:test', 
    'autoprefixer', 
    'connect:test', 
    'karma' 
    ]); 

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

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

Мой karma.config.js имеет это:

// list of files/patterns to load in the browser 
    files: [ 
     'bower_components/angular/angular.js', 
     'bower_components/angular-mocks/angular-mocks.js', 
     'bower_components/angular-animate/angular-animate.js', 
     'bower_components/angular-cookies/angular-cookies.js', 
     'bower_components/angular-resource/angular-resource.js', 
     'bower_components/angular-route/angular-route.js', 
     'bower_components/angular-sanitize/angular-sanitize.js', 
     'bower_components/angular-touch/angular-touch.js', 
     'bower_components/angular-ui-router/release/angular-ui-router.js', 
     'bower_components/angular-bootstrap/ui-bootstrap.js', 
     'bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 
     'bower_components/angular-bootstrap-lightbox/dist/angular-bootstrap-lightbox.js', 
     'bower_components/angular-loading-bar/build/loading-bar.js', 
     'bower_components/angular-cached-resource/angular-cached-resource.js', 
     'bower_components/angular-ui-slider/src/slider.js', 
     'bower_components/angular-local-storage/dist/angular-local-storage.js', 
     'bower_components/angular-bootstrap-lightbox/dist/angular-bootstrap-lightbox.js', 
     'bower_components/ng-file-upload/angular-file-upload.js', 
     'bower_components/ng-tags-input/ng-tags-input.min.js', 
     'bower_components/angular-ui-tinymce/src/tinymce.js', 
     'app/scripts/**/*.js', 
     'test/mock/**/*.js', 
     'test/spec/**/*.js' 
    ], 

Моя структура каталогов выглядит следующим образом:

app/ 
    scripts/ 
     app.js 
    styles/ 
    views/ 
bower_components/ 
dist/ 
node_modules/ 
test/ 
bower.json 
Gruntfile.js 
package.json 

В моем app.js вы найдете это:

angular 
     .module('webshopAdminApp', [ 
      'ngAnimate', 
      'ngCookies', 
      'ngResource', 
      'ngRoute', 
      'ngSanitize', 
      'ngTouch', 
      'ui.router', 
      'ui.bootstrap', 
      'ngCachedResource', 
      'ui.slider', 
      'LocalStorageModule', 
      'bootstrapLightbox', 
      'angularFileUpload', 
      'ngTagsInput', 
      'ui.tinymce' 
     ]) 

Я уверен, что все модули, которые я использую загружен. Я проверил поставщика. {Hash} .js файл и все модули находятся там. Когда я полностью удаляю модуль ui.slider, я получаю ту же ошибку с другим модулем, поэтому это не модуль или его реализация.

Я искал в Интернете и нашел только аналогичную проблему here, где проблема связана с инъекциями конвертации uglify. Я пробовал все данные решения, но никто не работал. Я не хочу отключать uglify. Я не знаю, в чем проблема, я создал другое приложение AngularJS с точно такими же спецификациями и конфигурацией без каких-либо проблем.

Кто-нибудь знает, как это исправить?

+0

Основное отличие между «сервисом» и «прямолинейным» - это тесты.Где появляются ваши сообщения об ошибках, так как в ваших тестовых модулях может возникнуть проблема с конфигурацией. –

+0

Существует также разница, когда «grunt serve» не создает файл поставщика со всеми модулями, он создает ссылку на фактические файлы в каталоге bower_components , Поэтому при использовании 'grunt serve' нет проблем, потому что модули в порядке. – gidomanders

ответ

1

Мы определили, что вся конфигурация зависимостей модулей правильная или, по-видимому, является.

Чтобы более четко определить, какие модули терпят неудачу, необходим процесс устранения.

Если вы обнаружите, что появляются ошибки, возникающие из модулятора для отсутствующего модуля или поставщика, затем медленно удаляйте зависимостей модулей один за другим и перестраивайте, чтобы выяснить, какая зависимость выбрасывает ошибку.

Затем удалите зависимость и найдите другую, которая могла бы удовлетворить ее.

Если ваш вопрос с LocalStorageModule, я рекомендую идти с ngStorage и увидеть, если это решит ваши проблемы, here's the link

+0

Я обдумал свой вопрос – gidomanders

+0

Обновленный мой вопрос снова, вы видите, что у моего karma.config.js есть ui-слайдер. – gidomanders

+1

Единственный способ действительно решить эту проблему - посмотреть, какие зависимости у вас отсутствуют. Если вы все еще получаете ошибки, даже если вы удаляете модуль, вам необходимо удалить модули, для которых есть ошибки, и найти корневую зависимость, которая не выполняется. Вы должны ** не ** нуждаться в редактировании Gruntfile.js, генератор должен обрабатывать его для вас. – TommyMac

1

После работы в течение 4 часов, я, наконец, нашел проблему! Я использую LocalStorageModule, который обычно должен работать, но после хрюкания он терпит неудачу. Возможно, неправильная конфигурация, но я заменил ее на $ cookie, и теперь сайт работает без ошибок.

Основная причина, по которой я использовал LocalStorageModule, состоит в том, что очень легко автосохранять переменные фильтра с помощью localStorageService.bind($scope, 'filters', {}, 'filters');, чтобы они не терялись при обновлении страницы или навигации по деталям и обратно.

Я собираюсь открыть проблему на своем GitHub и попытаться найти правильную конфигурацию, чтобы заставить ее работать снова. Спасибо за помощь!

Смежные вопросы