gridstack.js icon indicating copy to clipboard operation
gridstack.js copied to clipboard

Missing ES distribution that works in browser

Open mnlipp opened this issue 2 years ago • 6 comments

Subject of the issue

I know that it is "out of fashion", but I have my reasons. I want to use gridstack in the browser without any packaging tools. Actually, that's what the ES module demo tries to do, too.

The demo doesn't work, because the referenced '../dist/gridstack.js' isn't on the (demo) server. But even if it was, the demo wouldn't work, because all *.js files "import from './xxx'" without the js extension. This doesn't work in the browser. (Vue for example, includes a special "browser distribution" that has the proper imports.)

My workaround is to replace import/export references to './xxx' with './xxx.js' before putting the files on my server. This works, but is ugly at beast.

Expected behavior

The distribution should have a version that can directly be loaded in the browser.

mnlipp avatar Sep 29 '23 13:09 mnlipp

did you try the demo site https://gridstackjs.com/demo/index.html because all those work just fine including the right .js files.

adumesny avatar Sep 29 '23 17:09 adumesny

Clicking on the link gives me a page with just a title. The firefox debug console says: image

... which is firefox's strange way of saying that the file does not exists.

image

Besides, if the gridstack.js is the one from the dist/..., it won't work. I tried this with my own server (loading .../dist/gridstack.js works there) and, as mentioned above, "import from ..." without .js does not work in the browser.

image

Note the "Certain bundlers may permit importing files without extensions; check your environment.". Browsers don't.

gridstack.js as distributed does not use the extension:

/*!
 * GridStack 9.2.2
 * https://gridstackjs.com/
 *
 * Copyright (c) 2021-2022 Alain Dumesny
 * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE
 */
import { GridStackEngine } from './gridstack-engine';
import { Utils, obsolete } from './utils';
import { gridDefaults, dragInDefaultOptions } from './types';

...

mnlipp avatar Sep 29 '23 18:09 mnlipp

which specific link ? this works in all browsers and many people would complain if the main side didn't load. gridstack-all.js is made to load in browser directly (note the -all.js) not gridstack.js which jus that class TS generated file.

https://gridstackjs.com/demo/float.html image

adumesny avatar Sep 29 '23 22:09 adumesny

As mentioned, this is specifically about the "ES Module loading demo". This one doesn't work for the reason mentioned.

mnlipp avatar Sep 30 '23 04:09 mnlipp

I fixed path to '../node_modules/gridstack/dist/gridstack.js' but now I have to include all .js file (instead of just all.js) but you are telling me that will still fail because their imports don't have extensions.

Problem is I can't test this locally as I get blocked errors "CORS policy" so I would have to push all changes live and make a release just to test....

can you tell me WHY you can't use all.js which work in the browser (why I bother putting it out), otherwise I use TS and package my app like most people.

seems like a lot of work for nothing.. if you really want it please donate as I don't have the bandwidth.

adumesny avatar Sep 30 '23 16:09 adumesny

can oyu tell me WHY you can't use all.js which work in the browser (why I bother putting it out), otherwise I use TS and package my app like most people.

Well, first of all I thought it was supposed to work, because there is the demo. I think we agree now that the demo does not work as intended.

My application is modular. When I add components on the server at runtime, additional components become available in the front-end. Simplifying things a bit, imagine that a component is added on the server. When the user refreshes the page, additional code is loaded, very much like in your example:

  <script type="module">
    import { GridStack } from '../node_modules/gridstack/dist/gridstack.js';

    let items = [{x: 1, y: 1}, {x: 2, y: 2, w: 3}];
    let count = 0;
    items.forEach(e => e.content = String(count++));

    GridStack.init({float: true}).load(items);
  </script>

The resource referenced (../node_modules/gridstack/dist/gridstack.js) has become available on the server because the additional component has been added (wasn't there before).

Due to this "dynamic nature", there is no application that can be packaged during development. The available javascript modules vary at runtime, depending on the current configuration on the server. They are "knitted together" in the browser (and not by some bundler).

Most libraries are distributed with a version of their js-code that can simply be made available as resource on the server and referenced in the import-statement as shown above (I already mentioned vue as an example). Of course, this is not a requirement for an npm package and you can choose not to do this. But then you should remove the "ES Module loading demo" from the page.

mnlipp avatar Oct 01 '23 11:10 mnlipp