DataTables and Webpack
DataTables and Webpack
Hi there -- I'm using DataTables in Webpack and following the instructions here: https://www.datatables.net/download/npm
The interesting thing about Webpack is that it provides BOTH AMD and CommonJS environments, so when the datatables.net module checks for what to export, it defaults to the AMD module. This breaks everything if in fact you used a CommonJS require() to import the module. What you get is a very mysterious 'cannot set $ of undefined' error.
It took me a while to figure this out but as far as I can tell there are two ways to fix this without modifying the datatables.net code:
(1) Disable AMD entirely in Webpack (see http://stackoverflow.com/questions/29302742/is-there-a-way-to-disable-amdplugin); or
(2) Do NOT immediately invoke datatables.net as instructed at https://www.datatables.net/download/npm. In other words, just require the file without invoking or passing arguments. I'm not exactly sure why this latter solution works.
I suppose an additional solution would be to just embrace the AMD dependency but I have not tried this.
I like DataTables a lot so posting this here to help anyone else out that may run across this issue.
swinc
Replies
Very interesting and super useful. Thanks for sharing this knowledge with us!
Allan
I have a similar experience but slightly different solution to the problem.
The problem is indeed that the AMD module support gets "priority" since it's the first check in the datatable source.
I too used the imports-loader plugin for webpack for just datatables.
I did however need to invoke the factory function with (window, $) to make it work.
Here's a gist of exactly what I had to do to get it working in npm and webpack with bootstrap styling: https://gist.github.com/swemaniac/2fbe5d6d5e425b7c046168b6d6e74e95
Thanks for posting your findings! There is also a discussion about it here.
I'll be writing this up into a proper WebPack install guide for DataTables in the coming weeks.
Regards,
Allan
In regards to @swinc 's point (2) above: does it work because it's using AMD?
I am inclined to just use this if it works. I'm not using AMD in my own code, but I don't see a reason to bother with imports-loader if this works.
The other issue I found is that, for the styling packages, webpack doesn't seem to know what to "do with" a styling-only package if you just import the package. You have to point it to the CSS file in the package. I.e.:
(Note that you have to have a CSS loader in your webpack config, but you probably want this anyway.)
What I'm not sure about is if I'm really doing this as designed.
Here's fuller sample code: https://gist.github.com/marcstober/c34bb4bdf7ef622cb24d6675723749bd
as an FYI for anyone that comes across this:
related issue
it's important to note the case difference in the css file name(s): datatables.net-dt/css/jquery.dataTables.css. none of the examples provided should (or will in my experience) work if you build your application on a non-Mac box.
additionally;
with webpack all i had to define were the style/css loader and the es6 import statement:
no additional config is necessary to pull in the CSS.
for javascript dependency:
import dt from 'datatables.net'
thanks!
edited to note: webpack2.*
Really good and helpful post/discussion, thanks all!
I did want to let you all know that the second link to https://datatables.net/download/npm in the original post is broken (looks like a period "." character was appended to the end of the url).
I'm having some weird issues with webpack and datatables. Specifically,
$('table').DataTable()
and$('table').dataTable()
are both returning the same thing, the jquery object. Whereas i'm expecting$('table').DataTable()
to return the api instance. My current workaround is to obtain the api instance by doingvar tableAPI = $('table').DataTable().api()
.Here is what i have in my main.js file:
webpack config for jquery:
That's really odd! If you were using DataTables 1.9 then that would explain it, but that doesn't have an
api()
method.Can you link to a page showing the issue so I can check it out?
Allan
Are you using AMD or CommonJS? You say you attempted to disable AMD. If you use CommonJS you'd need to execute the returned function:
Also you wouldn't need to import both
datatables.net
anddatatables.net-bs
. The Bootstrap styling will automatically importdatatables.net
.Allan
I'm really glad I found this page. I was struggling trying to figure out why my tables weren't looking right after importing datatables.net-bs4 (using an ES6 style import). Simply importing the CSS as above did the trick.
WOW
(2) Do NOT immediately invoke datatables.net
THANK YOU.
It would be nice to tell datatables globally what to do. e.g. via a global variable that is picked up by DataTables while initializing:
In my case I have require.js in place for TypeScript, but so far not everything is migrated to the module system and some other 3rd party dependencies do not use it as well. When I include DataTables I end up with tons of errors. I would like to force it to the classical "browser" mode until my application is ready to use only modules.
Some registration scripts are also not easy to achieve as I am using some script bundeling. I think I can manage to get it running with some additional injected scripts between DataTables and the 3rd party scripts but the easier solution would be some global configuration.
Just disable AMD parser.
My two cents on how to disable amd, but only for datatables.net package (not in webpack.config.js)
After
yarn add imports-loader
you can use:For anyone stumbling upon this issue as I did trying to import datatables in webpack and having css not applying. I had to use the following for it to be working in webpack (obviously exclude plugins you don't want):
Note: In my case I have jQuery imported globally (legacy app). So you may have to adjust the way you import. But these files seem to be important to import if you want css to work (mainly the -bs for bootstrap + css file).
This was my solution that worked:
use
and in webpack config
Have to correct: before I had import dt from 'datatables.net'; and dt(window, $); that did not work anymore now only import 'datatables.net'; had to remove the webpack test again
Stumbled upon this. Got to
that gives
while jquery is exposed
I have tried
import dt from 'datatables.net' and
console.log(dt.version) returns a result. But still DataTable is not a function
There a few threads in the forum, like this and this and this, it would be worth looking at those and seeing if they help.
Colin
Thanks @colin,
I was looking at some of them with no success, but would move through them again.
Ok. Let's do this.
Trying first solution - https://datatables.net/forums/discussion/comment/132471/#Comment_132471
It results in
when I try to do
So lets change the code to
Again there is an error for
that is
I am commenting the
then the result is
Status: First solution from https://datatables.net/forums/discussion/comment/132471/#Comment_132471 did not work
It says go for https://gist.github.com/jrunestone/2fbe5d6d5e425b7c046168b6d6e74e95#file-jquery-datatables-webpack
And since gist tend to go missing sometimes here is the content of the gist (note, the in gist comments there is an update):
I would install imports-loader, and it does no work.
It is
This does not work. datatable is undefined.
This seems interesting. I also have jquery 2 as I depend on it. I have installed datatables, but it has not installed jquery 3 and there is not error. Let's try to upgrade.
Now I am at 3.5.1
I also have datatables
With require('datatables.net'); I can now successfully use datatables.
Turns out it is the problem with jquery version. I depend on jquery2. Datatable seems to depend on a newer version of jquery without this being explicit about it. I was able to install datatable with jquery2 in package.json, but then datatables was taking another jquery and not using the one defined in the package json?
Correct me if I am wrong but does datatables come with it's own jquery? I don't understand how does this happen?
No - DataTables doesn't come with its own jQuery, and it is compatible back to 1.7. At least in terms of run time. I wasn't aware (or perhaps don't remember) a change in the jQuery 2 / 3 packaging, but DataTables should always just use what
require('jquery')
returns - source.Allan
I used it like this:
... etc