Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an ESM bundle #135

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Create an ESM bundle #135

wants to merge 1 commit into from

Conversation

alijsh
Copy link
Contributor

@alijsh alijsh commented Jul 25, 2024

Exports the code as an ECMAScript module and stops calling the sort function on page load. In a web application, as opposed to a browser extension, this should be left to developers when to call sorting. There are scenarios with no initial tables (tables are loaded dynamically and the sort function is called when required). As for file extension, it can be ".mjs", which is the standard or alternatively, something like ".esm.js"

Exports the code as an ECMAScript module and stops calling the sort function on page load. In a web application, as opposed to a browser extension, this should be left to developers when to call sorting. There are scenarios with no initial tables (tables are loaded dynamically and the sort function is called when required). As for file extension, it can be ".mjs", which is the standard or alternatively, something like ".esm.js"
@LeeWannacott
Copy link
Owner

LeeWannacott commented Jul 25, 2024

stops calling the sort function on page load.

Technically it doesn't sort on the pages content loading it just adds the event listener and sets the table up to be sortable on click.

There are scenarios with no initial tables (tables are loaded dynamically and the sort function is called when required).
Yeah, I think if the tables are loaded from a database etc (is this your use case?). We could probably do a better job of handling this, probably with a class to override, or something.

The main problem I have with this PR is that I would have to maintain two different scripts each with different logic (and would have to setup tests for this new file).

I think if you want an .mjs file it should be made from the public/table-sort.js script on deploy/release and the script itself should detect the file extension and use export (and select whatever logic is relevant for it as a module ) if the file is a .mjs

@alijsh
Copy link
Contributor Author

alijsh commented Jul 25, 2024

Currently, the following line fails with the error message: The requested module doesn't provide an export named 'tableSortJs'

import { tableSortJs } from 'path to table-sort.js';

As a result, your package can't be used in JavaScript modules, whether I use the file as table-sort.js or table-sort.mjs. Your project lacks support for JavaScript modules.

You won't have to maintain two different scripts. Upon releasing a new version, you only need to copy the whole code from table-sort.js to table-sort.mjs and add "export" before function declaration (export function tableSortJs). Alternatively, you can add export { tableSortJs }; to the end of table-sort.mjs. That's all.

As an example, Color.js offers different bundles including an ESM bundle. The package can be readily imported as a JavaScript module. This file shows that the process can be automated.

As for the other requested change, I didn't mean tables are sorted on page load but that tableSortJs function is executed on page load. It might be useful for a browser extension to force its code execution on page load but generally, load events should be managed by those who use your package in their projects. This change could be discussed separately but since a typical JavaScript component does not have a load event, I thought I could request both changes at the same time. We can skip this change and focus on the necessity of an ESM bundle for your project.

@alijsh alijsh changed the title Create table-sort.mjs Create an ESM bundle Jul 25, 2024
@LeeWannacott
Copy link
Owner

LeeWannacott commented Jul 25, 2024

Currently, the following line fails with the error message: The requested module doesn't provide an export named 'tableSortJs'

import { tableSortJs } from 'path to table-sort.js';

What about like this; where you just import tableSort without brackets, does this work? (this should export the whole thing as a module)?

import tableSort from "table-sort-js/table-sort.js";

Calling it in React (web app):

  useEffect(() => {
    tableSort()
  },[]);

https://leewannacott.github.io/table-sort-js/docs/react.html

@alijsh
Copy link
Contributor Author

alijsh commented Jul 25, 2024

What about like this; where you just import tableSort without brackets, does this work? (this should export the whole thing as a module)?

import tableSort from "table-sort-js/table-sort.js";

It doesn't work. The difference between import X and import { X } is a matter of export vs export default. Your project does not support JavaScript modules, whether in the form of export { tableSortJs } or export default tableSortJs.

@LeeWannacott
Copy link
Owner

LeeWannacott commented Jul 25, 2024

It doesn't work.

How are you installing it?, from npm? I find it hard to believe it doesn't work, because I have used it myself (from npm). However, you might be right in that it doesn't have a default export, so why does it still work for me? and I assume other people ( because why has no one complained up till now if it doesn't work)?

This must be why 🤔

why might a import still work in es6 even when there are no named functions
... being exported and no default export

image

@alijsh
Copy link
Contributor Author

alijsh commented Jul 25, 2024

Please read about different types of modules here. Node.js projects typically use CommonJS. This type of module does not work in the browser (it is a back-end module). React, Vue, etc. use back-end technologies and that's probably why no one has complained so far :) They are transpiled before they can be understood by browsers. I'm requesting support for native JavaScript module called ESM. It works directly in the browser. NPM is not just for Node.js projects. It is also used to install Bootstrap, icon libraries, etc. As I mentioned before, Color.js is a good sample of projects that support different types of modules.

Edit: I must clarify that your code works in the browser if one codes in non-modular JavaScript but it fails as a JavaScript module.

@LeeWannacott
Copy link
Owner

LeeWannacott commented Jul 25, 2024

@alijsh Yeah, I'm not opposed to making .mjs file. I was just curious why it was working currently for React. Do we need named exports or just a default export? , I think the easiest way is just add a export default onto the end of the file after copying form public/table-sort.js -> public/table-sort.mjs using a bash script i.e https://github.com/LeeWannacott/table-sort-js/blob/master/deploy.sh.

I don't think we need the following, as I think they are doing this for the minifier (terser), jsDelivr would make a minifier url for the .mjs anyway.
https://github.com/color-js/color.js/blob/main/_build/rollup.config.js

load events should be managed by those who use your package in their projects

I think if table-sort.js is loaded from a <script> tag it should keep the current behavior (for ease of use and not breaking when updating table-sort-js), but include an option to override. But if its a ESM module, or React etc. then it can be up to the developer when to call it. It already is kinda with React; You can do dynamic importing with React etc...

@alijsh
Copy link
Contributor Author

alijsh commented Jul 25, 2024

Do we need named exports or just a default export? , I think the easiest way is just add a export default onto the end of the file after copying form public/table-sort.js -> public/table-sort.mjs using a bash script i.e https://github.com/LeeWannacott/table-sort-js/blob/master/deploy.sh.

Both are possible but we can go for what you find the easiest. You just add export default tableSortJs; to the end of table-sort.mjs and it's ready to be imported as an ESM module in other files: import tableSortJs from 'path/to/table-sort.mjs';.

I think if table-sort.js is loaded from a <script> tag it should keep the current behavior (for ease of use and not breaking when updating table-sort-js)

Yes. The current behavior will remain intact as ESM modules are loaded differently: <script type="module">.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants