Grunt:加载依赖需要几分钟的时间

我已经把一些相当标准的grunt任务与合理数量的依赖放在一起,但由于某些原因,实际加载依赖需要1-3分钟。 我是一个咕噜咕噜的新手,但是因为大多数关于极端缓慢加载咕噜声依赖的其他问题引用了几秒钟的时间,所以我猜测我正在做一些非常错误的事情。

这是我的gruntfile的样子:

const path = require("path"); module.exports = function(grunt) { require('jit-grunt')(grunt); require('time-grunt')(grunt); const ignoredSourceScriptPatterns = ['!**/*.debug.js', '!**/*.min.js', '!scripts/*', '!**/*.map'], baseUIPath = 'presentation/ui', scripts = grunt.file.expand({filter: 'isFile', matchBase: true, cwd: baseUIPath}, ['*.js', ...ignoredSourceScriptPatterns]); // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), copy: { build: { cwd: 'presentation/', src: 'ui/**', dest: path.join('presentation', 'static'), expand: true } }, uglify: { options: { sourceMap: true, compress: false }, build: { cwd: baseUIPath, files: function() { var modules = grunt.file.expand({ filter: 'isDirectory', expand: true, cwd: 'presentation/ui/modules' }, ['**', '!**/css', '!**/scripts', ...ignoredSourceScriptPatterns]), components = grunt.file.expand({ filter: 'isFile', expand: true, cwd: 'presentation/ui' }, ['components/!*.js', ...ignoredSourceScriptPatterns]), files, componentFiles; files = modules.map(function(path) { var modulePath = `modules/${path}/scripts`, moduleName = modulePath.split('/').reduce(function(result, next) { var nameFragment; switch(next) { case "modules": nameFragment = "Poptart."; break; case "scripts": nameFragment = "min.js"; break; default: nameFragment = `${next.charAt(0).toUpperCase() + next.slice(1)}.`; break; } return result + nameFragment; }, ""); return { src: grunt.file.expand({ filter: 'isFile' }, [`${baseUIPath}/${modulePath}/*.js`, ...ignoredSourceScriptPatterns]).sort( function(a, b) { return a.length - b.length; } ), dest: `${baseUIPath}/${modulePath}/${moduleName}` }; }); componentFiles = components.map(function(componentPath) { return { src: `${baseUIPath}/${componentPath}`, dest: `${baseUIPath}/${componentPath.replace('.js', '.min.js')}` }; }); files = [...files, ...componentFiles]; files.push({ src: grunt.file.expand({ filter: 'isFile' }, [`${baseUIPath}/*.js`, ...ignoredSourceScriptPatterns]), dest: `${baseUIPath}/poptart.min.js` }); return files; }(), extDot: 'last', expand: true } }, cssmin: { options: { sourceMap: true }, build: { cwd: 'presentation/static/ui/', src: ['**/*.css', '!css/jquery-ui/**', '!css/ionicons/**', '!**/*.min.js'], dest: 'presentation/static/ui/', ext: '.min.css', expand: true } }, eslint: { options: { configFile: 'presentation/build/eslint.json', ignorePath: 'presentation/build/.eslintignore' }, target: ['presentation/**/*.js', '!presentation/ui/scripts/*', '!presentation/static/**'] }, shell: { test: { command: 'python manage.py test -p "*tests.py"', options: { stdout: true, failOnError: true } } }, karma: { unit: { configFile: 'karma.conf.js', singleRun: true } }, mochaTest: { unit: { options: { reporter: 'spec' }, src: ['presentation/test/server/*.js'] } } }); /*grunt.loadNpmTasks('grunt-shell'); grunt.loadNpmTasks('grunt-eslint'); grunt.loadNpmTasks('grunt-karma'); grunt.loadNpmTasks('grunt-mocha-test'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-newer');*/ grunt.registerTask('default', ['lint', 'test']); grunt.registerTask('test', ['shell:test', 'mochaTest:unit', 'karma:unit']); grunt.registerTask('lint', ['eslint']); grunt.registerTask('build-static', ['uglify', 'copy', 'cssmin']); }; 

和我的开发依赖从package.json:

  "devDependencies": { "chai": "^3.5.0", "chai-jquery": "^2.0.0", "eslint": "^3.7.1", "grunt": "^1.0.1", "grunt-contrib-copy": "^1.0.0", "grunt-contrib-cssmin": "^1.0.2", "grunt-contrib-uglify": "^2.0.0", "grunt-eslint": "^19.0.0", "grunt-karma": "^2.0.0", "grunt-mocha-test": "^0.13.2", "grunt-newer": "^1.2.0", "grunt-shell": "^1.3.1", "jit-grunt": "^0.10.0", "jquery": "^3.1.1", "karma": "^1.3.0", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^2.0.0", "karma-cli": "^1.0.1", "karma-jquery-chai": "^0.1.3", "karma-mocha": "^1.3.0", "karma-phantomjs-launcher": "^1.0.2", "karma-sinon": "^1.0.5", "mocha": "^3.2.0", "sinon": "^1.17.6", "sinon-chai": "^2.8.0", "time-grunt": "^1.4.0" } 

以下是我迄今为止所尝试的:

  1. 使用time-grunt来validation加载任务实际上是问题。 它是。 实际运行的任务花费了非常合理的时间。
  2. 使用jit-grunt。 这没有什么明显的差别。
  3. npm修剪。 实际上这确实造成了相当大的差距(〜30秒),但是仍然让我处于一个完全不合理的任务加载时间。
  4. 删除和卸载一些依赖关系(uglify,copy,cssmin)我在开始看到这个问题的时候添加了一些附件(最初,当我刚刚完成testing/testing任务时,一切都很好,很快)。 这也没有明显的差别。

所以。 还有什么可能导致这个规模的缓慢?

谢谢你的帮助!

我试着运行你的Gruntfile并手动安装依赖项,并且Gruntfile的加载时间是~4秒。 不是很快,但不是你谈论的分钟。

我的猜测是grunt.file.expand正在努力工作。 也许presentation/ui文件夹太大? 通过运行tree presentation/ui | wc -l获得什么? tree presentation/ui | wc -l ? 这显示了你在那里的文件数量。

否则,也会看到你的package.json和npm ls输出。

所以看起来这样的根本原因是在uglify任务中一些低效的文件search。 我完全忘记了我已经把这个巨大的疯狂和IEF做了,这就解释了为什么即使在我没有执行丑化任务时,我也看到了这种缓慢。 我想这也解释了为什么文件search的时间越来越多的加载任务。

无论如何,主要的罪魁祸首是(可以预料的)我在哪里返回dynamic脚本模块的source / destpath,在这里:

  return { src: grunt.file.expand({ filter: 'isFile' }, [`${baseUIPath}/${modulePath}/*.js`, ...ignoredSourceScriptPatterns]).sort( function(a, b) { return a.length - b.length; } ), dest: `${baseUIPath}/${modulePath}/${moduleName}` }; 

不要惊讶,因为它在一个循环中。 无论如何,我注意到它错过了一个cwd。 加上时间减less到7秒。 仍然需要改进,但至less现在我知道要改进什么。

这个故事的道德:

  1. search文件时添加cwd的
  2. 也许只是不search文件,如果你不必