Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should project-level bundling be handled for non SPA use?

I am learning browserify and I am trying to do two basic things with it:

  1. Transform (via shim) non-CommonJS modules for ease-of-use and dependency tracking
  2. Bundle the libraries that are project-specific

I've found a working process for how to do all of this and automate it with Gulp. This works and produces the right output but, I am curious if it could be made simpler. It seems like I have to duplicate a lot of configuration on the project-based bundles. Here is the working example:

package.json
invalid comments added for clarification

{
    //project info and dependencies omitted

    //https://github.com/substack/node-browserify#browser-field
    "browser": { //tell browserify about some of my libraries and where they reside
        "jquery": "./bower_components/jquery/dist/jquery.js",
        "bootstrap": "./bower_components/bootstrap/dist/js/bootstrap.js"
    },
    "browserify": {
        //https://github.com/substack/node-browserify#browserifytransform
        "transform": [
            "browserify-shim"
        ]
    },
    "browserify-shim": { 
       //shim the modules defined above as needed 
        "jquery": {
            "exports": "$"
        },
        "bootstrap": {
            "depends": "jquery:$"
        }
    }
}

config.js
contains all task-runner related configuration settings

module.exports = {

    browserify: {
        // Enable source maps and leave un-ulgified
        debug: true,
        extensions: [],
        //represents a separate bundle per item
        bundleConfigs: [
            {
                 //I really want to refer to the bundles here made in the package.json but 
                 //if I do, the shim is never applied and the dependencies aren't included
                 entries: ['/bundles/shared-bundle.js'], 
                 dest: '/dist/js',
                 outputName: 'shared.js'
            }
        ]
    },
    //...
};

shared-bundle.js
acts as a bundling file where node loads the dependencies and at this point, the shim has been applied

require('bootstrap');

browserify-task.js
contains the browserify bundling gulp task

//module requires omitted
gulp.task('browserify', function (callback) {
    var bundleQueue = config.bundleConfigs.length;
    var browserifyBundle = function (bundleConfig) {
        var bundler = browserify({
            entries: bundleConfig.entries,
            extensions: config.extensions,
            debug: config.debug,
        });

        var bundle = function () {
                return bundler.bundle()
                // Use vinyl-source-stream to make the stream gulp compatible
                .pipe(source(bundleConfig.outputName))
                // Specify the output destination
                .pipe(gulp.dest(bundleConfig.dest))
                .on('end', reportFinished);
        };

        var reportFinished = function () {
            if (bundleQueue) {
                bundleQueue--;
                if (bundleQueue === 0) {
                    // If queue is empty, tell gulp the task is complete
                    callback();
                }
            }
        };
        return bundle();
    };
    config.bundleConfigs.forEach(browserifyBundle);
});

In config.js where the first bundleConfig item's entries is a source to a file that has the require() modules, I'd like replace those with module names of modules defined in the package.json browser key.

In the config.js, if I change the bundle configuration to:

 bundleConfigs: [
      {
           entries: ['bootstrap'], 
           dest: '/dist/js',
           outputName: 'shared.js'
      }
 ]

and run the gulp task, it will include bootstrap.js but it doesn't run the shim transformation. jQuery is not being included at all.

This leaves me with a few questions:

  • Is there a better way to be bundling my js for use in a non-SPA application (ie am I going about this the wrong way)?
  • If not, is there a way to ensure the shim transformation is run prior to the bundling so that I can have my bundle configuration in one place?
like image 384
Carrie Kendall Avatar asked Dec 17 '14 23:12

Carrie Kendall


People also ask

What are the different ways for bundling and minification in asp net core?

Bundling and minification are two techniques you can use in ASP.NET to improve page load performance for your web application. Bundling combines multiple files into a single file. Minification performs a variety of different code optimizations to scripts and CSS, which results in smaller payloads.

What is difference between bundling and minification?

Bundling is one of the features of MVC. By implementing this, we can improve performance request load time. Minification is the process of removing unnecessary data without changing its functionality such as removing white spaces, comments, converting the large variable names to small, etc.

What is the use of bundling in MVC?

Bundling is a new feature in ASP.NET 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create CSS, JavaScript and other bundles. Fewer files means fewer HTTP requests and that can improve first page load performance.

How minification is implemented in MVC?

Bundling and minification can be enabled or disabled in two ways: either setting the value of the debug attribute in the compilation Element in the Web. config file or setting the enableOptimizations property on the BundleTable class. In the following example, debug is set to true in web.


1 Answers

Certainly, you just have to tell your gulp file that it should shim first. Looks like you can add your own shim object when calling browserify from your gulp file. Check out this example

If you want to ensure everything is shimmed before you bundle them, use the deps array: "An array of tasks to be executed and completed before your task will run."

It would look something like this:

gulp.task('shim', function() {
  // ...
});

gulp.task('browserify', ['shim'], function(){
  // ...
});
like image 134
Keenan Lidral-Porter Avatar answered Oct 03 '22 05:10

Keenan Lidral-Porter