thanpolas
thanpolas

Reputation: 848

How can Modernizr 3.x modules be required?

I am trying to require specific Modernizr tests into a browserify project but i must be doing something wrong.

I use the deamdify transform when building using browserify.

Modernizr is required as an NPM package directly from the source repo's master. The reason this happens is because pending v3.x will be available through npm and the latest bower packages do not offer the sources, only prebuilt versions.

I want to be flexible with what Modernizr modules i include in my application so for my needs, having an extra build-modernizr step is not acceptable. I want to have a single build step, browserify.

The problem is that deamdify fails to recognize the required Moderizr modules as AMD and does not resolve their dependencies or wrap them in AMD containers...

I have setup a repo that illustrates the problem:

https://github.com/thanpolas/browserify-modernizr

Upvotes: 4

Views: 2365

Answers (3)

mixel
mixel

Reputation: 25846

Though you said that having an extra build-modernizr step is not acceptable for you (I provided answer for that case) but still I want to add another answer for the case when using browserify and Modernizr with gulp.

gulp-modernizr can crawl through specified files, find Modernizr usages and make custom Modernizr build:

npm install --save-dev gulp-modernizr

Define gulp task in gulpfile.js:

var modernizr = require('gulp-modernizr')

gulp.task('modernizr', function () {
    return gulp.src('src/**/*.js')
        .pipe(modernizr())
        .pipe(gulp.dest('build'));
});

This task generates build/modernizr.js that contains only tests used in your source code. When added to html file with <script> tag this file sets Modernizr instance to window.Modernizr property. So you can use it like:

if (window.Modernizr.filereader) {
    // your code here
}

Using modernizr as module.

If you want to use modernizr as module (see this issue for discussion) than create src/modernizr.js file:

module.exports = window.Modernizr;

And expose this file as module with name modernizr:

var browserify = require('browserify');
var source = require('vinyl-source-stream');

gulp.task('browserify', ['modernizr'], function() {
    var b = browserify({ entries: 'src/index.js' });
    b.require('src/modernizr.js', {expose: 'modernizr'});
    return b.bundle()
        .pipe(source('index.js'))
        .pipe(gulp.dest('build'));
});

Now you can use it in your source code:

var modernizr = require('modernizr');

if (modernizr.filereader) {
   ...
}

Injecting build/modernizr.js and build/index.js scripts in index.html.

Suppose you have src/index.html:

<!DOCTYPE html>
<html class='no-js' lang=''>
<head>
    <meta charset='UTF-8'>
    <title>Example</title>
    <!-- inject:head:js -->
    <!-- endinject -->
</head>
<body>
<!-- inject:js -->
<!-- endinject -->
</body>
</html>

The following gulp task will inject build/modernizr.js in head section and build/index.js in body section and place resulting file to build/index.html:

var inject = require('gulp-inject');

gulp.task('html', ['browserify'], function() {
    return gulp.src('src/index.html')
        .pipe(inject(gulp.src('build/modernizr.js', { read: false }),
        { ignorePath: 'build', addRootSlash: true, starttag: '<!-- inject:head:{{ext}} -->'}))
        .pipe(inject(gulp.src('build/index.js', { read: false }),
        { ignorePath: 'build', addRootSlash: true}))
        .pipe(gulp.dest('build'));
});

Upvotes: 1

mixel
mixel

Reputation: 25846

With browsernizr you can specify what tests you need in your source code.

Install:

npm install --save browsernizr

Use:

// pick what tests you need 
require('browsernizr/test/css/rgba');
require('browsernizr/test/file/filesystem');
require('browsernizr/test/websockets');

// make sure to do this after importing the tests 
require('browsernizr');

// or if you need access to the modernizr instance: 
var Modernizr = require('browsernizr');

browserify will include required tests in bundle.

Upvotes: 0

Patrick
Patrick

Reputation: 13974

Nope, you aren't doing anything wrong. Its just not set up to work like that quite yet. Its a bit of a custom AMD.

@robw has been working on a new build system that I believe would show you to do what you are looking for.

update: the new build system is finally in effect - using master as of 2/8/2015 you can require tests

Upvotes: 1

Related Questions