Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bundle d3 v4 using webpack

Tags:

webpack

d3.js

I was using D3 v3 with webpack which was simple with one single package. Now that D3 v4 has become modular with separate packages, I am unable to bundle them into single package.

I have referred to mbostock's article below using rollup but it fails saying it is unable to load d3 from index.js. Can anyone help me with how to bundle them using webpack?

EDIT 1: I removed d3 from the rollup options and the rollup worked fine. I have explained the steps below

  1. D3 v4 installed.
  2. Added rollup config and storing to ./dist/d3.min.js
  3. pointed webpack to the ./dist/d3.min.js
  4. tried resolve.alias in webpack and require("d3") in one home.js. But no luck it says

cannot resolve module d3 in home.js

  1. tried webpack.Provideplugin in home.js. Still the above error.

Can anyone please help me with getting this d3 loaded?

Rollup.js

import node from "rollup-plugin-node-resolve";

export default {
  entry: "index.js",
  format: "umd",
  moduleName: "d3",
  plugins: [node()],
  dest: "./dist/d3.js"
};

index.js

export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";

webpack.config.js

var webpack = require('webpack')
var path = require('path')

module.exports = {

        entry:    [
            //"./dist/d3-combined.js",
            "./client/home.js"
            ,"./client/pages.js"
            ,"./client/graph.js"
            ,"./client/orient_databases.js"
            ,"./node_modules/d3/d3.js",
            ,"./public/jquery-2.2.4.min.js"

        ]
        ,output: { 
            path: path.join(__dirname,'dist')
          // ,path: '/static'
            ,publicPath: 'http://localhost:3000/scripts/'
            ,filename: 'bundle.js'
        }
        ,plugins :[
              new webpack.ProvidePlugin({
                    jquery : "jquery"
                }),  

           new webpack.optimize.UglifyJsPlugin({
              compress: {
                warnings: false
              }
            })
        ]
        ,module: {
            // avoid webpack trying to shim process
            noParse: /es6-promise\.js$/,
            loaders: [
              {
                test: /\.vue$/,
                loader: 'vue'
              },
              {
                test: /\.js$/,
                // excluding some local linked packages.
                // for normal use cases only node_modules is needed.
                exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
                loader: 'babel-loader',
                query : {
                    presets : ['es2015']
                    //,optional : ["runtime"]
                }
              }
            ]
          }

         ,resolve : {
            //root : [path.resolve('./node_modules')],
            alias : [ {"d3": path.join(__dirname,"dist/d3.min.js") } ],
            modulesDirectories : ["node_modules"]
         }

}
like image 275
Rao Avatar asked Nov 03 '16 10:11

Rao


People also ask

How do you bundle on a webpack?

You can bundle your JavaScript using the CLI command by providing an entry file and output path. Webpack will automatically resolve all dependencies from import and require and bundle them into a single output together with your app's script.

What is bundling in webpack?

In the wake of React—Facebook's UI library—came Webpack, a simple but awesome module bundler. Module bundlers are just what they are called, they bundle up JavaScript modules into one file. This way, when the client makes a request to your server, it doesn't have to make multiple requests for static files.

What does webpack do with node modules?

Webpack is a static module bundler for JavaScript applications. It takes modules, whether that's a custom file that we created or something that was installed through NPM, and converts these modules to static assets.

What webpack is used for?

This is why webpack exists. It's a tool that lets you bundle your JavaScript applications (supporting both ESM and CommonJS), and it can be extended to support many different assets such as images, fonts and stylesheets.


1 Answers

There are quite a few incompatibilities with D3 v4's rollup approach and webpack—yours is totally a sensible approach.

It looks like you're missing the minification step? (Rollup.js creates d3.js, but webpack.config.js expects d3.min.js)

It's also possible that webpack v2's new configuration has some relevant fixes.

This setup works for me (using webpack v2):

home.js

let d3 = require('d3');

rollup.config.js

import npm from 'rollup-plugin-node-resolve';

export default {
  entry: './d3.bundle.js',
  format: 'umd',
  moduleName: 'd3',
  plugins: [npm({jsnext: true})],
  dest: './dist/d3.js'
};

d3.bundle.js

export * from "d3-selection";
export * from "d3-zoom";
export * from "d3-scale";
export * from "d3-drag";
export * from "d3-force";
export * from "d3-axis";

package.json

{

  ...

  "scripts": {
    "prepublish": "rollup -c && uglifyjs dist/d3.js -c -m -o dist/d3.min.js"
  },

  ...
}

webpack.config.js

module.exports = {

  ...

  resolve: {
    alias: {
      'd3': path.resolve(__dirname, 'dist/d3.min.js')
    }
  },

  ...

};
like image 175
accidental_PhD Avatar answered Dec 01 '22 00:12

accidental_PhD