[英]Angular.js Module not found when grunt serve:dist, but grunt serve works fine
So I get this error whenever I execute grunt serve:dist
: 所以每当我执行
grunt serve:dist
时,我都会收到此错误grunt serve:dist
:
vendor.7e2420d0.js:4 Uncaught Error: [$injector:modulerr] Failed to instantiate module prometheusApp due to:
Error: [$injector:modulerr] Failed to instantiate module restangular due to:
Error: [$injector:nomod] Module 'restangular' 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.
The problem is that if I run grunt serve
it works just fine. 问题是如果我运行
grunt serve
它就可以了。 Obviously it has to do with the minification/uglify
process. 显然它与
minification/uglify
过程有关。 But since the error does not say anything else I cannot figure out how to solve it. 但由于错误没有说什么,我无法弄清楚如何解决它。
This is my Gruntfile
: 这是我的
Gruntfile
:
// Generated on 2015-04-15 using generator-angular 0.11.1 //使用generator-angular 0.11.1在2015-04-15生成
'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'
var modRewrite = require('connect-modrewrite');
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);
// 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,
less: {
compile: {
options: {
paths: ['bower_components/{,*}*.less'],
sourceMap: true,
},
files: {
'<%= yeoman.app %>/styles/main.css': '<%= yeoman.app %>/styles/main.less'
}
},
theme_one: {
options: {
paths: ['bower_components/{,*}*.less']
},
files: {
'<%= yeoman.app %>/styles/main.css': '<%= yeoman.app %>/styles/main1.less'
}
},
theme_two: {
options: {
paths: ['bower_components/{,*}*.less']
},
files: {
'<%= yeoman.app %>/styles/main.css': '<%= yeoman.app %>/styles/main2.less'
}
}
},
// 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/{,*/}*.less'],
tasks: ['less:compile', '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: 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(['^[^\\.]*$ /index.html [L]']),
connect.static('.tmp'),
connect().use('/bower_components', connect.static('./bower_components')),
connect().use('/app/styles', connect.static('./app/styles')),
connect.static(appConfig.app)
];
}
}
},
test: {
options: {
port: 9001,
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: '.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']
},
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 Bower components into the app
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
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}}\','
}
}
}
}
},
// 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',
'<%= yeoman.dist %>/styles'
]
}
},
// 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 %>'
}]
}
},
// 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}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'images/{,*/}*.{webp}',
'styles/fonts/{,*/}*.*'
]
}, {
//for bootstrap fonts
expand: true,
dot: true,
cwd: 'bower_components/bootstrap/dist',
src: ['fonts/*.*'],
dest: '<%= yeoman.dist %>'
}, {
//for font-awesome
expand: true,
dot: true,
cwd: 'bower_components/font-awesome',
src: ['fonts/*.*'],
dest: '<%= yeoman.dist %>'
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}, {
expand: true,
flatten: true,
src: [
'<%= yeoman.app %>/translations/*',
],
dest: '<%= yeoman.dist %>/translations'
}, {
expand: true,
flatten: true,
src: [
'bower_components/components-font-awesome/fonts/*',
'bower_components/bootstrap/fonts/*'
],
dest: '<%= yeoman.dist %>/fonts'
}, {
expand: true,
flatten: true,
src: [
'divshot.json',
],
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']);
var tasks = ['clean:server'];
if (target === 'theme_one') tasks.push('less:theme_one');
else if (target === 'theme_two') tasks.push('less:theme_two');
else tasks.push('less:compile'), console.log("tema elegido: " + target);
tasks = tasks.concat(['wiredep',
'concurrent:server',
'autoprefixer:server',
'connect:livereload',
'watch']);
grunt.task.run(tasks, 'connect:dist:keepalive');
});
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',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'less:compile',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
grunt.registerTask('build:theme:one', [
'clean:dist',
'less:theme_one',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
grunt.registerTask('build:theme:two', [
'clean:dist',
'less:theme_two',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
grunt.loadNpmTasks('grunt-contrib-less');
};
I have no clue what could be wrong. 我不知道什么是错的。 How could I debug this error?
我怎么能调试这个错误?
Angular finds the controller's dependencies from the names of arguments found in the constructor function. Angular从构造函数中找到的参数名称中查找控制器的依赖项。 When you minify the JavaScript code for PrometheusApp, all of its function arguments get minified, and the Angular is not be able to find the modules.
当您缩小PrometheusApp的JavaScript代码时,其所有函数参数都会缩小,并且Angular无法找到模块。
There is a couple of ways to go about doing this. 有几种方法可以做到这一点。
I would recommend using the $inject Property Annotation 我建议使用$ inject属性注释
This annotation allows the minifiers to rename the function parameters. 此注释允许缩小器重命名函数参数。 When using this annotation functions need to be annotated with the $inject property.
使用此注释时,需要使用$ inject属性注释函数。 This is an array of service names to inject for this module.
这是要为此模块注入的服务名称数组。
var PrometheusApp = function($scope, customComponent) {
// Do Stuff here
}
PrometheusApp.$inject = ['$scope', 'customComponent'];
This is obviously a preference, all three options listed above will work just find. 这显然是一种偏好,上面列出的所有三个选项都可以找到。 I prefer using the $inject Annotation as I fell its more explicit.
我更喜欢使用$ inject Annotation,因为我更明确地使用它。
Take a look at the Angular documentation for dependency injection 看一下Angular文档中的依赖注入
https://docs.angularjs.org/guide/di https://docs.angularjs.org/guide/di
Try removing uglifyjs from your usemin process like below, to find out if restangular has been included in your vendor.js file. 尝试从您的usemin进程中删除uglifyjs,如下所示,以确定您的vendor.js文件中是否包含了restangular。 + Could I see your bower.json file too?
+我可以看到你的bower.json文件吗?
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat'],
css: ['cssmin']
},
post: {}
}
}
}
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.