1

I am using requirejs in my project and each module has a js file using require calls to make use of libraries/components. Following is sample code :-

require(["modernizr",
"jquery",
"bootstrap",
"handlebars",
"bootstrap-table",
], function(modernizr, $, bootstrap, Handlebars, bootstrapTable) {

$(document).on('click', '#searchBtn', function(e){
    search();
});

$('#table').bootstrapTable({
    classes: 'table table-no-bordered',
    striped: true,
    iconsPrefix: 'fa',
    responsive: true,
    responsiveBreakPoint: 768,
    responsiveClass: "bootstrap-table-cardview",
    undefinedText: "",
    showFooter: true,
    columns: columns(),
    data: data(),
});
}

I want to minimize the number of js calls in the browser while page load.

(I am aware of r.js but would like to avoid it as it requires me change my project folder structure)

So I am thinking of concatenating and minifying all library/component js files like jquery, bootstrap etc. using grunt and then require them in module specific files.

If I do so, I wanted to know how I can include the same using require and be able to use jquery($) and bootstrapTable the way I am using now?

I tried the following but it does not seem to be working :-

require(["mainjs"], function(mainjs) {

mainjs(document).on('click', '#searchBtn', function(e){
    search();
});

mainjs('#table').mainjs({
    classes: 'table table-no-bordered',
    striped: true,
    iconsPrefix: 'fa',
    responsive: true,
    responsiveBreakPoint: 768,
    responsiveClass: "bootstrap-table-cardview",
    undefinedText: "",
    showFooter: true,
    columns: columns(),
    data: data(),
});
}

Following is my project structure :-

my-proj
build
src
    app
        components
            selectpicker
                selectpicker.hbs
                selectpicker.js
                selectpicker.less
            calendar
                calendar.hbs
                calendar.js
                calendar.less
            ...
            ...
            ...
        page
            homepage
                homepage.html
                homepage.js
            transacations
                transactions.html
                transactions.js
            ...
            ...
            ...
    assets
        images
        js
            jquery.js
            modernizr.js
            handlebar.js
            require.js
            bootstrap.js
            moment.js
            ...
            ...
            ...
        less
Gruntfile.js
package.json
Stacy J
  • 2,721
  • 15
  • 58
  • 92

2 Answers2

1

You can use webpack:

Create a file webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

and your code file src/index.js :

const modernizr = require("modernizr");
const $ = require("jquery");
const bootstrap = require("bootstrap");
const Handlebars= require("handlebars");
const bootstrapTable = require("bootstrap-table");

$(document).on('click', '#searchBtn', function(e){
    search();
});

$('#table').bootstrapTable({
    classes: 'table table-no-bordered',
    striped: true,
    iconsPrefix: 'fa',
    responsive: true,
    responsiveBreakPoint: 768,
    responsiveClass: "bootstrap-table-cardview",
    undefinedText: "",
    showFooter: true,
    columns: columns(),
    data: data(),
});

Then run the command line program webpack in your project directory. This will create a file called dist/bundle.js, which includes your project code as well as all used libraries inside one file.

You can also tell webpack to minify the entire code, using the following configuration. This will also minify all used dependencies inside the destination file.

const webpack = require("webpack");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  // ...
  optimization: {
    minimize: true,
    minimizer: new UglifyJsPlugin({
      include: /\.min\.js$/
    })
  }
};
Lukas Bach
  • 3,559
  • 2
  • 27
  • 31
  • Yes, there is a grunt package for webpack. Look into https://github.com/webpack-contrib/grunt-webpack – Lukas Bach Jun 20 '18 at 18:33
  • I have another clarification, the sample file that I shared above is for one of the modules in the project. I have several modules with each having a js file similar to above one. In this case, can I still create a bundle.js specific to each module? – Stacy J Jun 20 '18 at 19:08
  • You mean having several output files, one for each input? This is also possible, look into https://stackoverflow.com/a/45278943/2692307. It will still combine all used dependencies into each output module, so that each output js file is standalone, but still create one output per input file. – Lukas Bach Jun 21 '18 at 00:04
  • Yes, that's what I was looking for. I'll give it a try. Thanks – Stacy J Jun 21 '18 at 04:50
  • I am getting following error for many component - Module not found: Error: Can't resolve 'bootstrap-select', Module not found: Error: Can't resolve 'bootstrap-table. Only jquery and bootstrap doesn't throw an error. Any idea why? I've updated the question with my project folder structure – Stacy J Jun 21 '18 at 06:14
  • Thats odd.. Do the respective folders exist in your node_modules folder? Try following the reference of the required modules in your IDE (CTRL+B in IntelliJ, F12 in VSCode) and see if your IDE can resolve the module. – Lukas Bach Jun 21 '18 at 19:19
0

You can use webpack, parceljs or Browserify to bundle modules into one .js file.

Kokodoko
  • 26,167
  • 33
  • 120
  • 197