I'm using webpack and I'm using require to pull in some packages. I have two packages: package1.js and package2.js. package1.js simply creates an object with some properties called pkg1
. package2 is a javascript file that contains a self executing function that extends package1. E.g.
package2.js:
!function () {
pkg1.prototype.newFunction = function {return "foo"};
}()
I'm trying to require both of these into a new script in the following manner:
require('package1')
require('package2')
When I do this, I get an error:
Uncaught TypeError: pkg1.newFunction is not a function
I think this is because of Javascripts asynchronous loading: require(package2)
executes before require('package1')
. My evidence for this is that when I do the following I don't get an error:
require('package1')
!function () {
pkg1.prototype.newFunction = function {return "foo"};
}()
However, this is very messy, and I would like to use require. How would I go about making this work?
Edit: Specific Examples
The leaflet-d3 plugin begins with:
(function() {
L.HexbinLayer = L.Class.extend({
...
})()
Hence, at least to my understanding, putting in a require(leaflet-d3-plugin)
should cause this script to execute and extend L
which is brought in by require('leaflet')
Similarly, d3-hexbin-v0 starts with:
!function(){d3.hexbin=function(){
...
}}()
Again, the way I read this is that this script simply adds a .hexbin
method to d3
.
Now if I were just writing html, I would just put these different things in various script tags and this just works:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.hexbin.v0.min.js"></script>
or
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
<script src="static/leaflet-d3.min.js" charset="utf-8"></script>
But since I'm using webpack, I should just be able to require and/or import these libraries after I have installed them with npm or if I just copy the .js in these scripts into some directory and then require
them from that location. Unfortunately, this does not seem to work unless I copy the .js in these modules directly into whatever script I am writing. This is what I am trying to avoid.
E.g.
import * as d3 from 'd3'; \\I'm using d3 v4 here.
require('/resources/d3-hexbin.min.js')
results in:
Uncaught TypeError: d3.hexbin is not a function
There are four basic concepts in webpack: entry , output , modules and plug-ins . These configurations are added in webpack.
Webpack v4+ will minify your code by default in production mode .
Webpack runs on Node. js, a JavaScript runtime that can be used in computers and servers outside a browser environment.
The major difference between require and import , is that require will automatically scan node_modules to find modules, but import , which comes from ES6, won't. Most people use babel to compile import and export , which makes import act the same as require .
Webpack loades it synchronously but each file have its own scope.
That's why in your statement
import * as d3 from 'd3'; \\I'm using d3 v4 here.
require('/resources/d3-hexbin.min.js')
your second doesn't find d3
variable.
You can solve it by using ProvidePlugin
:
webpack.config.js
plugins: [
new webpack.ProvidePlugin({
d3: 'd3'
}),
... //other plugins
This way d3
will be available throughout the application.
Alternative way to achieve it is to use the following:
import * as d3 from 'd3';
window.d3 = d3;
require('./d3.hexbin.v0.min.js')
Hope it helps you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With