Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the recommended way to require minified versions in production but debug in development when using browserify?

I have just started looking at browserify and am wondering what is the recommended way to require the min versions of dependencies when building for production and the debug ones when building for development?

For example, I have followed the tutorial here - http://www.sitepoint.com/getting-started-browserify/ and ended up with the following files:

js\main.js

var names = require('./names.js'),
    findSuperman = require('./findsuperman.js');

if (findSuperman(names())) {
    document.write('We found Superman');
} else {
    document.write('No Superman...');
}

js\names.js

module.exports = function () {
    return ['Barry Allen', 'Hal Jordan', 'Kara Kent', 'Diana Prince', 'Ray Palmer', 'Oliver Queen', 'Bruce Wayne', 'Wally West', 'John Jones', 'Kyle Rayner', 'Arthur Curry', 'Clark Kent'];
}

js\findsuperman.js

var _ = require('underscore');

module.exports = function (values) {
    var foundSuperman = false;

    _.find(values, function (name) {
        if (name === 'Clark Kent') {
            console.log('It\'s Superman!');
            foundSuperman = true;
        } else {
            console.log('... No superman!');
        }
    });

    return foundSuperman;
}

index.html

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Find Superman</title>
</head>
<body>
    <script src="js/findem.js"></script>
</body>
</html>

package.json

{
    "name": "FindSuperman",
    "version": "0.0.1",
    "author": "Patrick Catanzariti",
    "description": "Code designed to find the elusive red blue blur",
    "dependencies": {
        "underscore": "*"
    },
    "devDependencies": {
        "browserify": "*",
        "grunt": "*",
        "grunt-browserify": "*",
        "grunt-contrib-watch": "*"
    },
    "scripts": {
        "grunt": "grunt"
    }
}

gruntFile.js

module.exports = function (grunt) {
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-browserify');

    grunt.registerTask('default', ['browserify', 'watch']);

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        browserify: {
            main: {
                options: {
                    browserifyOptions: {
                        debug: true
                    }
                },
                src: 'js/main.js',
                dest: 'js/findem.js'
            }
        },
        watch: {
            files: 'js/*',
            tasks: ['default']
        }
    });
}

Running npm run grunt creates js/findem.js, which includes the debug version of the underscore package (and also starts the watcher).

But I would also like to have js/findem-min.js - the min version intended for production and which should include the min version of the underscore package.

And here there are a few things I need to understand. Indeed:

  1. require('underscore') maps to the debug version. There does not seem to be require('underscore-min'). Seems like one has to resort to require('underscore/underscore-min.js'). Am I correct?
  2. How to require different things conditionally depending on the production or development build, but only when browserifying? The final js file (js\findem.js or js\findem-min.js) should require the right thing unconditionally, of course.
  3. Should I also have index-min.html? Does not seem right. So, I should have one index.html which loads either js\findem.js or js\findem-min.js? Since I cannot have both at the same time I need to serve index.html as a dynamic content rather than a static file. Something like a jade template with the name of the js file being either js\findem.js or js\findem-min.js depending on the startup parameters (NODE_ENV=development comes to mind). Am I correct?

I would like to know whether I understand correctly the items 1 and 3, but I do not have an answer for item 2. What is the recommended way (the best practice, if you please) to do it? I might have gotten items 1 and 3 wrong as well, so please, correct me if I am wrong there.

like image 418
mark Avatar asked Apr 11 '16 04:04

mark


1 Answers

I haven't used browserify in years. Most people use Webpack now. That said, the parameters passed to Browserify from grunt will control the output. A "run" command typically maps to debug. There will be a separate command to build production files.

For #1, you'll only ever want to write require('underscore'). It's up to the module bundler (browserify/webpack/etc) to rewrite/handle that. Include .js in your requires if you're referencing a specific file. Do not include it if you're referencing a module from outside of your project, such as underscore.

For #2, Browserify has pretty bad documentation. Since Webpack works in mostly the same way here, reading their resolve documentation might help you figure this out. https://webpack.github.io/docs/resolving.html

For #3, that's correct. The HTML needs to reference different .js files depending on if you're in prod/debug. You can hardcode it with two files if you want static output. But in most cases, yes, you typically pick an env variable. Other cases might be serving legacy .js files for old browsers, etc.

Good luck (and switch to webpack :)

like image 80
James Avatar answered Oct 19 '22 09:10

James