DataTables / DataTablesSrc

DataTables source repository
https://datatables.net
MIT License
587 stars 422 forks source link

The ESM version of datatables.net works well except when require.js is loaded #199

Closed mwouts closed 2 years ago

mwouts commented 2 years ago

Thank you @AllanJard for the great library!

I am opening this issue (also documented at https://datatables.net/forums/discussion/69066/esm-es6-module-support on the forum) as I would like to use a pure ESM version of datatables.net for my itables project (issue #51 there).

Currently the ESM version of datatables.net works very well, except when require.js is loaded.

A sample HTML file that reproduces the issue is below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Datatables ESM fails when requirejs is loaded</title>
</head>
<body>

<!-- This breaks the ESM version of DataTables -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>

<table id="table_id">
    <thead>
    <tr>
        <th>A</th>
    </tr>
    </thead>
</table>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css">
<script type="module">
    import $ from "https://esm.sh/jquery@3.5.0";
    import initDataTables from "https://esm.sh/datatables.net@1.11.3?deps=jquery@3.5.0";

    initDataTables();

    // Display the table
    $(document).ready(function () {
        $('#table_id').DataTable();
    });
</script>

</body>
</html>

Note that the HTML example above works properly when the paragraph that loads require.js is removed.

The error stack is as follows:

Uncaught TypeError: ({}) is not a function
    <anonymous> file:///home/marc/GitHub/itables/itables/datatables_esm_issue_with_requirejs.html:24
AllanJard commented 2 years ago

I've just made this commit which adds a proper ES module file for DataTables to our distribution files.

I'm not entirely happy with this approach is the only thing - specifically the dependencies for the extensions and styling extensions.

When using CommonJS or AMD we could have our Bootstrap 5 integration (for example) datatables.net-bs5 depend upon DataTables core datatables.net. That doesn't and can't exist in this setup since we don't know where the files are going to get loaded from. It would be back to the browser approach of making sure we get them all in the right order, which seems like a step backwards.

I need to think about it some more. Any thoughts would be most welcome.

mwouts commented 2 years ago

Hello @AllanJard - thank you very much for this!

I agree with you that adding ES modules for DataTables should not be done at the expense of the Datatables extensions.

I know very little Javascript so I am afraid the only help I can provide is through testing and feedback, but let me cc @fwouts who suggested to load DataTables as ESM in the itables project - maybe he will have advice on how to package the main module and the extensions.

By the way, do you have any recommendation on how to load this ESM version? In the example above I was using

import $ from "https://esm.sh/jquery@3.5.0";
import initDataTables from "https://esm.sh/datatables.net@1.11.3?deps=jquery@3.5.0";

but maybe with your commit I can use a more standard CDN?

AllanJard commented 2 years ago

I've updated our nightly server to allow the new mjs file, so you can use:

import DataTables from 'https://nightly.datatables.net/js/jquery.dataTables.mjs';

http://live.datatables.net/fedopalo/1/edit

I wouldn't recommend depending upon it long term though - the nightly can, does and will change as development progresses. I'd suggest hosting it on your own server if you wanted to use it for production until we finalise how to get ESM working across all of our files.

mwouts commented 2 years ago

Thank you @AllanJard - I can confirm that the nightly build works and that I don't have any issue now when require.js is loaded.

I think I'll wait until you release the next version and then I'll import DataTables from https://cdn.datatables.net/ Also I still have to find out how to combine SRI with an ES import :smile:

AllanJard commented 2 years ago

You might be interested in a discussion I've started on the WHATWG HTML repo that stemmed from our discussion here: https://github.com/whatwg/html/issues/7600 .

mwouts commented 2 years ago

You might be interested in a discussion I've started on the WHATWG HTML repo that stemmed from our discussion here: https://github.com/whatwg/html/issues/7600 .

Thank you @AllanJard , very interesting discussion indeed... And I am even wondering it what I am seeing in your code snippet, i.e. importing the library from a string, might not help me implement the offline mode in itables...

mwouts commented 2 years ago

I'll close this issue as this has been fixed in the new ES module. If we replace the script above with

<script type="module">
    import $ from "https://esm.sh/jquery@3.6.0";
    import dt from "https://cdn.datatables.net/1.12.1/js/jquery.dataTables.mjs";

    dt($);

    // Display the table
    $(document).ready(function () {
        $('#table_id').DataTable();
    });
</script>

then we don't get a conflict with requirejs any more.