Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal error: Generate is not a function #163

Open
jamie-l-robertson opened this issue Mar 6, 2019 · 35 comments
Open

Fatal error: Generate is not a function #163

jamie-l-robertson opened this issue Mar 6, 2019 · 35 comments
Assignees

Comments

@jamie-l-robertson
Copy link

This issue only started a day ago, when running grunt-modernizr im getting Fatal error: Generate is not a function at the Building your customized Modernizr stage. Looks like Modernizr is failing to build - https://travis-ci.org/Modernizr/Modernizr

This is on a clean install of grunt-modernizr and therefor Modernizr too, i can take a previous install and it works.

any help would be appreciated.

Screenshot of the error.
screen shot 2019-03-06 at 15 36 29

@rejas rejas transferred this issue from Modernizr/Modernizr Mar 6, 2019
@rejas
Copy link
Member

rejas commented Mar 6, 2019

Moved to grunt-modernizr since that is what you are using, Which version of grunt / grunt-modernizr are you using?

@rejas
Copy link
Member

rejas commented Mar 6, 2019

(The failing modernizr build is unrelated)

@jamie-l-robertson
Copy link
Author

thanks @rejas im on version 1.0.3

@rejas
Copy link
Member

rejas commented Mar 6, 2019

Could you try the latest master branch of this repo where we updated all the dependencies? Just use "grunt-modernizr": "https://github.com/Modernizr/grunt-modernizr#master" in your package.json (and do a npm install) to try it out.

Edited the wrong package name :-D

@rejas
Copy link
Member

rejas commented Mar 6, 2019

(I dont have publishing rights on npm so the latest v2 cannot be published yet). Also: which node and grunt versions are you using?

@jamie-l-robertson
Copy link
Author

Hi @rejas still the same issue unfortunately...

Grunt - 1.0.3
Node - tried on 6, 7, 8, 9

strangely it runs if only grunt modernizr is called, but when its included with other task then this issue appears. Its worth also noting this has worked flawlessly on tons of my sites for the past 2 years.

@jamie-l-robertson
Copy link
Author

I just bumped customizr's modernizr dependency down to 3.6.0 and its now working again, seems theres an issue with modernizr 3.7.0

@rejas
Copy link
Member

rejas commented Mar 6, 2019

Hrmpf... Is your grunt file somewhere publicly visible for me to check out? And what tests are expected for it to be found?

@jamie-l-robertson
Copy link
Author

jamie-l-robertson commented Mar 6, 2019

sure, see below. i suspect because modernizr is currently broken and its a dependency of customizr that its all bubbling up to that.

var remapify = require('remapify');
var path = require('path');

module.exports = function (grunt) {
  var scriptsPattern = ['patterns/**/*.js', 'components/**/*.js', 'assets/scripts/*.js'];
  var scriptsPatternMain = ['patterns/**/*.main.js', 'components/**/*.main.js', 'assets/scripts/**/*.main.js'];
  var stylesPattern = ['patterns/**/*.scss', 'components/**/*.scss', 'assets/styles/**/*.scss', '!**/*_scsslint_tmp*.scss'];
  var sasslintIgnorePattern = ['!assets/styles/{vendor,mixins}/*.scss'];
  var sasslintPattern = stylesPattern.concat(sasslintIgnorePattern);
  var imagesPattern = ['assets/images/**/*'];
  var fontsPattern = ['assets/fonts/**/*'];
  var iconsPattern = ['assets/icons/**/*'];
  var stylesPatternMain = ['./assets/styles/build.scss'];
  var stylesPatternSecondary = ['./assets/styles/build-secondary.scss'];
  var fontsPatternDist = ['./dist/fonts/**/*'];
  var stylesPatternDist = ['./dist/styles/build.css'];
  var stylesPatternSecondaryDist = ['./dist/styles/build-secondary.css'];
  var scriptsPatternDist = ['./dist/scripts/build.js'];
  var scriptsLibsPatternDist = ['./dist/scripts/libs/**/*.js'];
  var svgPattern = ['assets/icons/svg/*.svg'];

  grunt.config.init({
    watch: {
      options: {
        cwd: './',
        interval: 200,
        spawn: false
      },
      fabric: {
        files: ['package.json'],
        tasks: ['version']
      },
      scripts: {
        files: scriptsPattern,
        tasks: ['scripts']
      },
      styles: {
        files: stylesPattern,
        tasks: ['styles']
      },
      fonts: {
        files: fontsPattern,
        tasks: ['copy:fonts']
      },
      images: {
        files: imagesPattern,
        tasks: ['copy:images']
      },
      icons: {
        files: iconsPattern,
        tasks: ['svg', 'copy:icons']
      },
      sasslint: {
        files: sasslintPattern
      },
      jscs: {
        files: scriptsPattern
      }
    },
    sass: {
      build: {
        files: [
          { './dist/styles/build.css': stylesPatternMain },
          { './dist/styles/build-secondary.css': stylesPatternSecondary }
        ]
      }
    },
    /*
     Copy files to dist folder
     */
    copy: {
      fabric: {
        files: [{
          expand: true,
          cwd: './assets/',
          src: 'version.txt',
          dest: './dist/'
        }]
      },
      fonts: {
        files: [{
          expand: true,
          cwd: './assets/fonts/',
          src: '**/*',
          dest: './dist/fonts/'
        }]
      },
      images: {
        files: [{
          expand: true,
          cwd: './assets/images/',
          src: '**/*',
          dest: './dist/images/'
        }]
      },
      icons: {
        files: [{
          expand: true,
          cwd: './assets/icons/',
          src: '**/*',
          dest: './dist/icons/'
        }]
      },
      scripts: {
        files: [{
          expand: true,
          cwd: './assets/scripts/libs/',
          src: '**/*',
          dest: './dist/scripts/libs/'
        }]
      },
      data: {
        files: [{
          expand: true,
          cwd: './assets/data/',
          src: '**/*',
          dest: './dist/data/'
        }]
      }
    },
    /*
     Apply vendor prefixed properties to generated css using 'Can I use' db
     */
    postcss: {
      options: {
        processors: [
          require('autoprefixer')({ browsers: ['last 5 versions', 'ie 8', 'ie 9'] })
        ]
      },
      build: {
        src: stylesPatternDist
      },
      buildSecondary: {
        src: stylesPatternSecondaryDist
      }
    },
    /*
     Minify css - keep fonts and build seperate for now
     */
    cssmin: {
      options: {
        keepSpecialComments: 0
      },
      dist: {
        expand: true,
        cwd: './dist/',
        src: ['styles/*.css', 'fonts/**/*.css'],
        dest: './dist/',
        ext: '.css'
      }
    },
    /*
     Build JS bundle using requiresJS optimizer
     */
    requirejs: {
      dev: {
        options: {
          optimize: 'none',
          mainConfigFile: 'config/require.config.js',
          name: 'node_modules/almond/almond',
          include: ['assets/scripts/build.main'],
          insertRequire: ['assets/scripts/build.main'],
          out: 'dist/scripts/build.js'
        }
      }
    },
    /*
     Minify JS - only does the build file until a decision is made on browserify/RequireJS
     */
    uglify: {
      dist: {
        files: {
          './dist/scripts/build.js': [scriptsPatternDist]
        }
      }
    },
    /*
     Generate a modernizr build based on requirements
     */
    modernizr: {
      dist: {
        'dest': './dist/scripts/modernizr.custom.js',
        'parseFiles': true,
        'customTests': [],
        'tests': ['cssanimations', 'svg'],
        'options': [
          'setClasses',
          'mq'
        ],
        'uglify': false,
        "files": {
          "src": [scriptsPatternDist, stylesPatternDist]
        },
      }
    },
    /*
     * JSCS Linting - for definition's see config and http://jscs.info/rules
     */
    jscs: {
      src: '{components,patterns}/**/assets/scripts/**.main.js',
      options: {
        config: 'config/.jscsrc',
        esnext: true,
        verbose: true,
        fix: false,
        force: true
      }
    },
    /*
     Quality check for SCSS
     */
    sasslint: {
      target: sasslintPattern,
      options: {
        configFile: 'config/.sass-lint.yml'
      }
    },
    /*
     SVG management
     */
    svgstore: {
      options: {
        prefix: 'icon-',
        cleanup: true,
        cleanupdefs: true,
        includeTitleElement: false,
        svg: {
          viewBox: '0 0 100 100',
          xmlns: 'http://www.w3.org/2000/svg'
        },
        formatting: {
          indent_size: 2
        }
      },
      your_target: {
        files: {
          'assets/icons/svg/dist/defs.svg': [svgPattern]
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.registerTask('styles', [], function () {
    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-postcss');
    grunt.task.run('sass', 'postcss:build', 'postcss:buildSecondary');
  });

  grunt.registerTask('modernizr', [], function () {
    grunt.loadNpmTasks("grunt-modernizr");
    grunt.task.run('modernizr');
  });

  grunt.registerTask('scripts', [], function () {
    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.task.run('requirejs');
  });

  grunt.registerTask('dist', [], function () {
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    //TODO redo this sequence
    grunt.task.run('styles', 'cssmin', 'scripts', 'modernizr', 'uglify', 'svg', 'version', 'copy');
  });

  grunt.registerTask('ie8', [], function () {
    grunt.loadNpmTasks('grunt-stripmq');
    grunt.task.run('stripmq');
  });

  grunt.registerTask('lintjs', [], function () {
    grunt.loadNpmTasks('grunt-jscs');
    grunt.task.run('jscs');
  });

  grunt.registerTask('lintscss', [], function () {
    grunt.loadNpmTasks('grunt-sass-lint');
    grunt.task.run('sasslint');
  });

  grunt.registerTask('lint', [], function () {
    grunt.task.run('lintscss', 'lintjs');
  });

  grunt.registerTask('svg', [], function () {
    grunt.loadNpmTasks('grunt-svgstore');
    grunt.task.run('svgstore');
  });

  grunt.registerTask('version', [], function () {
    version(grunt);
  });

  grunt.registerTask('default', [], function () {
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.task.run('styles', 'cssmin', 'scripts', 'modernizr', 'svg', 'version', 'copy', 'watch');
  });

  /*
   * With SCSS/JSCS linting enabled, we want to only check the currently changed file/s
   */
  var changed_files = Object.create(null);
  var onChange = grunt.util._.debounce(function (ext) {
    if (ext === '.scss') {
      var target = Object.keys(changed_files).concat(sasslintIgnorePattern);

      grunt.config('sasslint.target', target);
      grunt.task.run('lintscss');
    }

    if (ext === '.js') {
      grunt.config('jscs.src', Object.keys(changed_files));
      grunt.task.run('lintjs');
    }

    changed_files = Object.create(null);
  }, 200);

  grunt.event.on('watch', function (action, filepath) {
    var ext = path.extname(filepath);
    changed_files[filepath] = action;
    onChange(ext);
  });

};

/*
 * Write a version file for Backend, states working project version.
*/
function version(grunt) {
  var package = grunt.file.readJSON('package.json');
  var version = package.version;
  var project = package.name;
  var filePath = './assets/version.txt';

  grunt.log.writeln('Version: ' + project.cyan + ' @ ' + version.magenta);
  grunt.log.oklns('Logged to file: ' + filePath.cyan);
  grunt.file.write(filePath, version);
}

/*
 set up aliases used in build process
 */
function preBrowserifyBundle(b) {
  b.plugin(remapify, [
    {
      cwd: './assets/scripts/',
      src: '**/*.js',
      expose: 'build'
    },
    {
      cwd: './components/',
      src: '**/*.main.js',
      expose: 'component'
    },
    {
      cwd: './patterns/',
      src: '**/*.main.js',
      expose: 'pattern'
    }
  ]);
}

@rejas
Copy link
Member

rejas commented Mar 6, 2019

I am a little baffled now... Tried out grunt-config on my project and it worked fine with this dependencies:

    "grunt": "^1.0.3",
    "grunt-modernizr": "https://github.com/Modernizr/grunt-modernizr.git",

and this config

module.exports = function(grunt) {

    grunt.loadNpmTasks('grunt-modernizr');

    // Project configuration.
    grunt.initConfig({
        modernizr: {
            dist: {
                'dest': './test/modernizr.custom.js',
                'parseFiles': true,
                'customTests': [],
                'tests': ['cssanimations', 'svg'],
                'options': [
                    'setClasses',
                    'mq'
                ],
                'uglify': false,
                "files": {
                    "src": ['src/**/*.js']
                }
            }
        },
    });

    // Default task.
    grunt.registerTask('default', [
        'modernizr'
    ]);
};

bildschirmfoto 2019-03-06 um 19 09 06

What also is weird is that your config says 'uglify': false, but the screenshot says otherwise. But I guess that might be a oversight on your part.

But really weird is that nowhere in Modernizr or customizr (the middleware between) there is a function or call by the name of generate Maybe some other library is throwing the error (also on your screenshot it looks like there is output from modernizr below the error message) ? Could you send a whole picture of the error output? Maybe some other plugin in your build pipeline doesnt like v3.7?

As for the broken builds of Modrnizr in travis: That has something to do with travis as I already said. The tests run fine on my windows machine locally and Modernizr is sucessfully build and used in gulp-modernizr.

@jamie-l-robertson
Copy link
Author

jamie-l-robertson commented Mar 6, 2019

its only different as i was trying to test why it was breaking... so uglify was turned off just incase :)

I created a fork and dropped the customizr dependancy to 1.0.0 and it seems to be working as expected. have you tried nuking your npm cache etc then try a fresh install? my local build was fine until i did this.

its also worth noting that the modernizr task alone works fine, its when its in a pipeline of other tasks it fails. if i remove grunt-modernizr from the pipeline it works as expected as does using the forked version :( have you done any changes in the past day?

theres a generate function in the build.js file of modernizr, found on line 66. but is used throughout from what i can see.

excerpt below:

function build(generate, generateBanner, pkg) {
  return function build(config, cb) {
    var requireConfig = {};
    var banner;
    config = config || {};
    cb = cb || function noop() {};

    _extend(requireConfig, baseRequireConfig);

    requireConfig.rawText = {
      'modernizr-init': generate(config)
    };

@rejas
Copy link
Member

rejas commented Mar 6, 2019

You're right, there is indeed that one generate call (I can only say as an excuse that i am a little under the weather these days).
Could you try if it fails with customizr v1.1.0 too?
That it fails while in the pipeline but succeeds standalone makes it hard for me to debug from here unfortunately (plus I dont use grunt really anmore)

@jamie-l-robertson
Copy link
Author

@rejas no worries, thank you for your assistance so far! im just highlighting my findings, to help hopefully find the issue. I will try with v1.1.0 and feedback.

@jamie-l-robertson
Copy link
Author

@rejas customizr 1.1.0 also works as expected.
screen shot 2019-03-07 at 08 31 19

@rejas
Copy link
Member

rejas commented Mar 7, 2019

@jamie-l-robertson next try: coudl you rename your task from modenrizr to something else since grunt.modernizr itself defines a "mnodernizr"-grunt task? (a shot in the dark sicne I dont know if grunt has a problem with that ....
Otherwise I dont see much changes from 1.1.0 customizr to the latest master where something could have gone wrong.

@jamie-l-robertson
Copy link
Author

@rejas will give that try and feedback, will be this evening before i get time though. only difference i can see is 1.1.0 uses Modernizr 3.6.0 too.

@shayneoneill
Copy link

was there any updates on this?

@jamie-l-robertson
Copy link
Author

@shayneoneill ended up forking and downgrading version. Works fine.

@rejas
Copy link
Member

rejas commented Feb 6, 2020

@jamie-l-robertson so renaming the task didnt help to solve your problem?

@jamie-l-robertson
Copy link
Author

Unfortunately not... will try give it another look.

@devprojectsapps
Copy link

devprojectsapps commented Feb 21, 2020

I have the same error "Building your customized ModernizrFatal error: generate is not a function".
Is there any chance to fix it?

package.json:
"devDependencies": {
"bower": "~1.3.1",
"grunt": "^1.0.4",
"grunt-autoprefixer": "^3.0.4",
"grunt-bower-install": "^1.6.0",
"grunt-bower-requirejs": "^2.0.0",
"grunt-concurrent": "^3.0.0",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-connect": "^2.1.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-cssmin": "^3.0.0",
"grunt-contrib-htmlmin": "^3.1.0",
"grunt-contrib-imagemin": "^3.1.0",
"grunt-contrib-jshint": "^2.1.0",
"grunt-contrib-less": "^2.0.0",
"grunt-contrib-requirejs": "^1.0.0",
"grunt-contrib-uglify": "^4.0.1",
"grunt-contrib-watch": "^1.1.0",
"grunt-mocha": "^1.2.0",
"grunt-modernizr": "^0.4.0",
"grunt-newer": "^1.3.0",
"grunt-phonegap": "^0.15.3",
"grunt-rev": "^0.1.0",
"grunt-svgmin": "^6.0.0",
"grunt-usemin": "^3.1.1",
"jshint-stylish": "^2.2.1",
"load-grunt-tasks": "^5.1.0",
"requirejs": "^2.3.6",
"time-grunt": "^2.0.0"
}

bower.json:
"dependencies": {
"modernizr": "~2.6.2",
"require-handlebars-plugin": "~0.8.0",
"requirejs": "^2.3.6",
"backbone": "^1.4.0",
"moment": "momentjs#^2.24.0",
"imagesloaded": "^4.1.4",
"masonry-layout": "masonry#^4.2.2",
"iscroll": "^5.2.0",
"numeral": "^2.0.6"
}

@rejas
Copy link
Member

rejas commented Feb 23, 2020

hi @devprojectsapps unfortunatly I cannot help you with these old and outdated versions of grunt-modernizr and modernizr. Is upgrading to v2 of grunt-modernizr (and therefor v3 of modernizr too) an option for you?

@devprojectsapps
Copy link

Hi @rejas . If i update modernizr and grunt-modernizr to actual version i got the same error :-(.

@rejas
Copy link
Member

rejas commented Feb 23, 2020

mhhh.... what node version are you using?

@devprojectsapps
Copy link

devprojectsapps commented Feb 23, 2020

I am using node -v:
v8.10.0

Hmmm is it maybe the thing that i have to change this block:

modernizr: {
devFile: '<%= config.app %>/bower_components/modernizr/modernizr.js',
outputFile: '<%= config.dist %>/scripts/vendor/modernizr.js',
files: [
'<%= config.dist %>/scripts/{,/}.js',
'<%= config.dist %>/styles/{,/}.css',
'!<%= config.dist %>/scripts/vendor/*'
],
uglify: true
},

to

modernizr: {
dist: {
devFile: '<%= config.app %>/bower_components/modernizr/modernizr.js',
outputFile: '<%= config.dist %>/scripts/vendor/modernizr.js',
files: [
'<%= config.dist %>/scripts/{,/}.js',
'<%= config.dist %>/styles/{,/}.css',
'!<%= config.dist %>/scripts/vendor/*'
],
uglify: true
}
},

@jamie-l-robertson
Copy link
Author

Narrows this down to build.js in modernizr/libs...

it seems these 3 required modules arent resolving for some reason:

  var generateBanner = requirejs(__dirname + '/generate-banner.js');
  var generate = requirejs('generate');
  var pkg = requirejs('package');

if i do a npm i within the modernizr directory, it fixes it. any ideas?

@jamie-l-robertson
Copy link
Author

jamie-l-robertson commented Feb 23, 2020

ok... so we are using 'grunt-contrib-requirejs' which runs before 'grunt-modernizr'. it seems to be conflicting, once we changed the order they are ran it works fine with the latest version. will test further.

@shayneoneill
Copy link

shayneoneill commented Feb 24, 2020

Good luck folks, I'm unsubbing from this as I don't work anymore in the job where this stack was an issue. I sort of managed to solve this by not havign modnernizr work as a step in watch. Its not clear at all why it needed to be part of that particular cycle. Devs: Thankyou for your work, its an awesome project.

@devprojectsapps
Copy link

Ok this "Building your customized ModernizrFatal error: generate is not a function" happens if i update the npm grunt-modernizr package to actual version 2.1.1 .
If i use 0.4.0 i do not get this error.

@rejas
Copy link
Member

rejas commented Feb 25, 2020

thanks for the infos. could you try out @devprojectsapps which version breaks the build? so if 0.4.0 works but not 2.1.1 which one still works and which starts to show the error?

@devprojectsapps
Copy link

@rejas
From version 0.5.0 i get this error if run grunt --force

"Running "modernizr:uglify" (modernizr) task
Warning: Cannot use 'in' operator to search for 'devFile' in true"

So from version 0.5.0 its not working with my configuration :-(

My configuration in Gruntfile for modernizr is
modernizr: {
devFile: '<%= config.app %>/bower_components/modernizr/modernizr.js',
outputFile: '<%= config.dist %>/scripts/vendor/modernizr.js',
files: [
'<%= config.dist %>/scripts/{,/}.js',
'<%= config.dist %>/styles/{,/}.css',
'!<%= config.dist %>/scripts/vendor/*'
],
uglify: true
},

@rejas
Copy link
Member

rejas commented Feb 26, 2020

Oh, thats a different error...

Could you try the fix from above:

'ok... so we are using 'grunt-contrib-requirejs' which runs before 'grunt-modernizr'. it seems to be conflicting, once we changed the order they are ran it works fine with the latest version. will test further.'

if that helps? To be honest, with grunt and its plugins being more or less in maintainance mode I cannot devote much of my spare time in debugging this :-(

@devprojectsapps
Copy link

devprojectsapps commented Feb 29, 2020

Ok it runs threw that is good.
But I still have the problem that the modernizr file is not copied or created in the www / scripts / vendor directory.
I need this file, otherwise my app will not run.

Thats the out if i use command grunt modernizr in my old version:

Running "modernizr" task

Enabled Extras

shiv
load
cssclasses

Looking for Modernizr references

Downloading source files
cache modernizr-latest.js
cache modernizr.load.1.5.4.js

Generating a custom Modernizr build
Uglifying

Wrote file to ../www/scripts/vendor/modernizr.js

Done, without errors.

In my new version it is:

Running "modernizr:dist" (modernizr) task

Looking for Modernizr references

1 match in ../www/styles/myratch.css
svg

Ready to build using these settings:
setClasses, addTest, html5printshiv, testProp
Your file will be minified with UglifyJS

Building your customized Modernizr...OK

Done.

You see the difference?

Thats really strange, because the config of modernizr is the same.

@rejas
Copy link
Member

rejas commented Mar 4, 2020

sorry @devprojectsapps for the delay was traveling. can you post your grunt config where you configure grunt-modernizr?

@devprojectsapps
Copy link

devprojectsapps commented Mar 6, 2020

Thanks for your answer @rejas
You can see the Gruntfile here:
https://github.com/devprojectsapps/grunt/blob/master/Gruntfile.js

In the old versions in the modernizr task a vendor file is copied in the www/js/vendor path.
In the new versions this is not gone happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants