0

I have a module A as follows,Module A is bundles using web pack and it includes Module B. This module also exports Highcharts library using require variable

A.js (under modules folder:: src/main/webapp/resources/js/modules)

var HighCharts = require("highchart");
var moduleB = require("../common/B.js"); //so that we can call draw() of moduleB

$(document).ready(function() {
    moduleB.print();
}

B.js (Under Common Folder: src/main/webapp/resources/js/common)

var print = function() {
console.log("something");
draw();
}
var chart;
function draw() {
    chart = new Highcharts.Chart({

    });
}

exports.print = print;

Note ModuleB.js is bundled in A.js

When i load the javascript, it is throwing me an error, Highcharts is undefined.

//how to load this

chart = new Highcharts.Chart({

        });

To avoid this error, I did the following.

In B.js did the following.

var Highcharts = require('highcharts');

Also moved B.js into modules folder from common folder, as it is an Entry Point Now(moved to src/main/webapp/resources/js/modules from src/main/webapp/resources/js/common)

WebPack is giving me the following error.
ERROR in ./src/main/webapp/resources/js/modules/A.js Module not found: Error: a dependency to an entry point is not allowed @ ./src/main/webapp/resources/js/modules/A.js 7:14-37

Webpack.config.js

Entry point will be all the files under the modules folder.

var path = require('path');
var webpack = require("webpack");
var glob = require("glob");
//var BowerWebpackPlugin = require("bower-webpack-plugin");
var jsSrcPath = 'src/main/webapp/resources/js/modules/**/*.js';
var jsDestPath = 'src/main/webapp/resources/build/js/modules';
var cssPath = '';


var files = glob.sync(jsSrcPath, {});
var entries = {};


for (var i = 0; i < files.length; i++) {
  var file = files[i];
  entries[file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "")] = path.join(__dirname, file);
}

var webpackOptions = {
  cache: true,
  watch: false,
  entry: entries,
  output: {
    path: __dirname + "/" + jsDestPath,
    filename: '[name].js',
  },
  module: {
    loaders: [{
        test: /.(?:jsx|js)$/,
        exclude: /node_modules/,
        loader: 'babel-loader?blacklist=useStrict'
      },
      // }, {
      //   test: /\.json/,
      //   exclude: /node_modules/,
      //   loader: 'json-loader'
      // }, {
      //   test: /\.css$/,
      //   exclude: /node_modules/,
      //   loader: "style!css"
      // }, {
      //   test: /\.scss$/,
      //   exclude: /node_modules/,
      //   loader: 'style-loader!css-loader!sass-loader!autoprefixer-loader?browsers=last 10 version'
      // }, {
      //   test: /\.(png|jpg)$/,
      //   exclude: /node_modules/,
      //   loader: 'url-loader?limit=999999'
      // }, {
      {
        test: /vendor\/.+\.(jsx|js)$/,
        exclude: /node_modules/,
        loader: 'imports?jQuery=jquery,$=jquery,this=>window'
      }
    ]
  },
  resolve: {
    root: [path.join(__dirname, "bower_components")],
    extensions: ['', '.js', '.json', '.jsx', '.css']
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),
    // new webpack.optimize.UglifyJsPlugin({
    //   compress: {
    //     warnings: false
    //   }
    // })
  ],
  devServer: {
    contentBase: ".",
    noInfo: true, //  --no-info option
    hot: true,
    inline: true
  }
};



module.exports = webpackOptions;

PS: Initially B.js is outside modules folder as it is not an entry point. Later it was moved inside modules folder, as we have made that as an entry point.

Raghu
  • 1,363
  • 1
  • 23
  • 37

1 Answers1

1

"Clearly i don't want to load my highchairs lib in moduleB as it is not an entry point for web pack"

This is actually not the case, as unintuitive as it may seem! You do need to import Highcharts in moduleB, as that's where you're using it. In Node and Webpack, module imports aren't global; if you had a moduleC with another chart in it, you'd have to import Highcharts there too.

Webpack is smart enough to not run/include the imported code twice, so there's no reason to avoid doing this. This answer I wrote a while back explains exactly how this works.

EDIT: Looking at your config, I think you may have the wrong idea about how Webpack works. You don't input a whole directory of files and then get an entire directory full of files back; you set a single file as the entry point, and then Webpack traces all of its dependencies, bundling everything into a single output file*. The entry point is, as the name suggests, the point where you enter into your application - you definitely shouldn't be setting every file in your source folder as an entry point like you are now!

Here is a (hopefully) fixed version of your config:

var path = require('path');
var webpack = require("webpack");
var jsDestPath = 'src/main/webapp/resources/build/js/modules';
var cssPath = '';

var webpackOptions = {
  cache: true,
  watch: false,
  entry: path.join(__dirname, "src/main/webapp/resources/js/modules/a.js"),
  output: {
    path: __dirname + "/" + jsDestPath,
    filename: '[name].js',
  },
  module: {
    loaders: [{
        test: /.(?:jsx|js)$/,
        exclude: /node_modules/,
        loader: 'babel-loader?blacklist=useStrict'
      },
      // }, {
      //   test: /\.json/,
      //   exclude: /node_modules/,
      //   loader: 'json-loader'
      // }, {
      //   test: /\.css$/,
      //   exclude: /node_modules/,
      //   loader: "style!css"
      // }, {
      //   test: /\.scss$/,
      //   exclude: /node_modules/,
      //   loader: 'style-loader!css-loader!sass-loader!autoprefixer-loader?browsers=last 10 version'
      // }, {
      //   test: /\.(png|jpg)$/,
      //   exclude: /node_modules/,
      //   loader: 'url-loader?limit=999999'
      // }, {
      {
        test: /vendor\/.+\.(jsx|js)$/,
        exclude: /node_modules/,
        loader: 'imports?jQuery=jquery,$=jquery,this=>window'
      }
    ]
  },
  resolve: {
    root: [path.join(__dirname, "bower_components")],
    extensions: ['', '.js', '.json', '.jsx', '.css']
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    }),
    // new webpack.optimize.UglifyJsPlugin({
    //   compress: {
    //     warnings: false
    //   }
    // })
  ],
  devServer: {
    contentBase: ".",
    noInfo: true, //  --no-info option
    hot: true,
    inline: true
  }
};



module.exports = webpackOptions;

* This is a generalization - you can have multiple entry points, but they need to be independent - they definitely can't import each other.`

Community
  • 1
  • 1
Joe Clay
  • 33,401
  • 4
  • 85
  • 85
  • If i include highchairs in module B, then what happens is i cannot include module B in module A. Web pack will give this error.ERROR in ./src/main/webapp/resources/js/A.js Module not found: Error: a dependency to an entry point is not allowed – Raghu Sep 20 '16 at 11:07
  • @Raghu: Can you edit your question and add the contents of your `webpack.config.js`? That error makes me think that your entry points are configured wrong. – Joe Clay Sep 20 '16 at 11:10
  • Edited the question. Thanks. – Raghu Sep 20 '16 at 11:19
  • @Raghu: You should not have every file in your JS source directory set as an entry point (which is what you're doing with that `for` loop). Get rid of the loop entirely and set `entry` to just be the path to `moduleA`. This should get rid of your error and allow you to import Highcharts in `moduleB`. – Joe Clay Sep 20 '16 at 11:26
  • @Raghu: If you're not sure what I mean, let me know and I'll add an example to my answer. – Joe Clay Sep 20 '16 at 11:27
  • If B.js is not an entry point, how we can import highchairs in B.js using var Highcharts = require('highcharts'); Import of highcharts will be done by web pack only right? – Raghu Sep 20 '16 at 11:34
  • @Raghu: Updated my answer - I think you may have some misconceptions as to what an entry point actually is! – Joe Clay Sep 20 '16 at 11:36
  • It worked, thanks. Upvoted. Accepted your answer. Thanks Joe. – Raghu Sep 20 '16 at 11:45
  • @Raghu: Glad to hear it! Webpack configs are tricky business, I've had similar problems in the past. Especially if you're coming from build tools like Gulp or Grunt, the single entry point can seem odd. – Joe Clay Sep 20 '16 at 11:46