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

Example of using webpack and js modules alongside vanilla js :) #33

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sneakers-the-rat
Copy link

Part of: openjournals/joss-reviews#6336
Related to: #23

first of all i wanna be super clear this is not a PR that i am intending that you merge! I am making it as a PR just so it's easy to see the diff. feel free to close this any time!


OK previously i had said i would make an example of how you might package this up for distribution while also respecting your very lovely minimal, rock solid, no-hype, standards-based development style (which i love, did i say that already? i love it.)

this is not idiomatic ES6 or webpack, but it is my attempt at a transitional blend - some parts you might like, some parts you might hate, whatever works for you! I tried to touch as little of the code structure as i could.

The tricky thing about vanilla JS that imports everything into one global window scope is that it can be hard to reuse things, and so this is one step towards that - the <script> tags are removed from the html, and instead there are two index.js entrypoints that import from files in the repository, as well as modules that are installed from npm.

Y'all are very capable and i won't bore you with a tutorial, but here are some highlights:

  • The main "meat" of the webpack part is in the config directory - you have one common config that is true for every build of the site, and then a dev and prod config for, well, local development and production deployment!
  • each entry point creates a different js bundle. These take all the code that's imported there, minifies them, packs them into scopes, and then embeds that into the page. It used to be the case that CDNs were good because they let browsers cache the same file if it was used on multiple sites, but that's not really the case anymore. instead these bundles have a content hash, so whenever you change the code the browser knows to reload it, but can otherwise handle caching for just your site quite well. There are lots more fun optimization yak shaves you can get into, for example tree shaking where you can only bundle exactly the code you use from a package you import, and so on.
  • The config also handles:
    • copying images from a source to target directory
    • html templating - in this case there isn't any templating per se, but that's what injects the js into the rendered HTML
    • loading, transforming, and minifying css (you can use sass if you want to!),
    • transpiling javascript for browser compatibility (and all the other lovely things that babel can do)
  • You can have the best of both worlds - small, minified, local-friendly JS and source code that's readable via 'view page source' - i configured both the prod and dev builds to include source maps (see devtool) that are well supported by modern browsers. Someone who just goes to use the site will get the minified js, but if someone wants to see the source, their browser will know to load the source maps and it will appear as normal js.
  • the index.js file has some examples using exports-loader for adapting existing code that relies on global scope/side effects.
  • all your dependencies come from NPM at build time! so i removed the vendored three.js, and now if you want to update the version, etc. you just do that via npm and your lockfile.
  • I added a Gulpfile.js that's responsible for downloading local copies of the existing code from the CDN. Since that's your code, you could also package that up and distribute it via npm ( i see you have already done so with MRIViewer! ) or not, your choice. just another example of how to adapt styles.

The new scripts in package.json are the entrypoints to the dev and prod mode. Normally you would just call webpack there, but I am using a gulp -> webpack adapter that first makes sure the CDN scripts are downloaded and then runs webpack.

at the end of al that you get a nice and tidy dist directory when you run npm run build !

My goal here was ultimately to show appreciation for your years of work and many wonderful web tools, and offer some example of how you might make those pieces play nicely together. I didn't get all the way to packing this as its own module, but in the future, if you decide this is something you like, you will be able to structure it so that you can, for example export some functions from thresholdmann and import them in another site while keeping both separable and single-purpose.

Anyway sorry this took so long, i'm going to finish up my review tomorrow! this was the last thing i wanted to do on that

@sneakers-the-rat
Copy link
Author

Also to be clear i don't guarantee this works 100% out of the box (hence not a PR for merging!) - for example the 3d viewer is having trouble loading the data from the main window, but certainly my doing and nothing wrong with the current implementation

@katjaq
Copy link
Member

katjaq commented Apr 9, 2024

Thanks a lot for this draft PR @sneakers-the-rat . We are learning so much with you! 🥰 We will look into it.

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