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

feat: support JS build process #141

Merged
merged 9 commits into from
Feb 26, 2024
Merged

feat: support JS build process #141

merged 9 commits into from
Feb 26, 2024

Conversation

dustin-jw
Copy link
Contributor

Description

This work replaces our rudimentary mechanism for including JS on pages with a more robust build process using esbuild. This will make it easier to contribute JS and will give us some performance boosts from minification, code splitting, and caching. Notable changes include:

  • Building files that get written to dist/js instead of inlined in HTML files
  • Moving most logic into helper functions and files so that entry points are limited to importing functions, then running them
  • Fixing a bug where the page title wouldn't match the heading

To Validate

  1. Make sure all PR Checks have passed
  2. Pull down this branch
  3. Run npm start
  4. Go through each of the game types, confirming the following:
    • Question order is randomized (compare URL to the stated question number on the page)
    • Pagination remains predictable within the randomized order ("Previous" takes you back to the same question you just saw)
    • Multiple choice behavior works as expected when you click an incorrect/correct answer
    • The order of multiple choice answers is randomized (reload the page several times to see different orders)
    • Short answer behavior works as expected when you submit the form (the accepted answer is revealed)
  5. Run npm run build and inspect the dist/js folder. All files should be minified and re-used code should be in chunk-<id>.js file(s) that get imported in other files

@netlify
Copy link

netlify bot commented Oct 18, 2023

Deploy Preview for triviaccessibility ready!

Name Link
🔨 Latest commit dcd2cac
🔍 Latest deploy log https://app.netlify.com/sites/triviaccessibility/deploys/65d919a906178500084f1731
😎 Deploy Preview https://deploy-preview-141--triviaccessibility.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@dustin-jw dustin-jw force-pushed the chore--js-build-process branch from 1525f37 to 5272682 Compare December 4, 2023 15:43
@dustin-jw dustin-jw force-pushed the chore--js-build-process branch from 5272682 to 08dc1d9 Compare December 13, 2023 22:42
@dustin-jw dustin-jw force-pushed the chore--js-build-process branch from 08dc1d9 to da4d2eb Compare January 9, 2024 19:57
@dustin-jw dustin-jw force-pushed the chore--js-build-process branch 2 times, most recently from 3a826a3 to 25e1425 Compare February 22, 2024 15:38
@dustin-jw dustin-jw force-pushed the chore--js-build-process branch from 25e1425 to 6056e28 Compare February 22, 2024 21:00
Copy link

@marissahuysentruyt marissahuysentruyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again, I don't have a great grasp on the repo quite yet, but it seems to function as expected, according to the validation instructions. I only wanted to bring up one thing, with the minified dist/js/multiple-choice.js file. I haven't looked at many minified files, so are those last 3 lines ok? I wasn't sure if literally EVERYTHING should be smooshed together without indentation.

Screenshot 2024-02-23 at 3 57 15 PM

If that looks like you'd expect it, I'll approve!

Questions (purely for my own understanding):

  1. It seems like some of this work was refactoring- pulling functions from larger files, into smaller pieces. How do you determine what gets extracted to a separate file, vs. just stays within a larger file?
  2. What exactly is the .ejs file for? After a quick google, it seems it means Embedded (or maybe effective?) JavaScript. It looks like it's transforming JSON?
  3. I've done zero research on this, but I've seen the robots.txt a couple places lately. Can you share any like, resources or articles or anything, so I can understand what that file is doing?
  4. What do "Distractor 1" and "Distractor 2" mean? Why those words? (again, if that's something I should just google, let me know)

It wouldn't be me without extra questions, right?!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the pages in all...those correspond to when a user clicks on the "All Questions" in a game type, correct? I was a little confused at first, since those files are almost identical, but that's what I could gather.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there's a lot of repetition that we could probably refactor to make it a little easier to manage, but there are enough small differences that would make that a hassle. Honestly, it might be easier to tag each question in Airtable as "All", then delete the all folder entirely.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure what this file is doing. It's setting a bunch of variables/data based on whether or not the environment is dev/local or production I think, but I don't really know why. Some of them I get- like minify is true for the production files (so after the site is built). Same for bundle, and I understand outdir...

Maybe I need to look up esbuild.context()? Would that be a good place to start?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

esbuild is similar to webpack, which you might have seen before, but effectively it's a build tool for bundling/smooshing together JS (it can do other things, but that's the basic idea).

What could probably be clearer is that if isProduction is false, then we're running esbuild in "watch" mode, so it will rebuild whenever you save a file that affects the entry points. Otherwise, we just build our output JS files once and call it a day. I'll add some comments to clarify that behavior because I don't think it's intuitive.

@marissahuysentruyt
Copy link

@dustin-jw Oh, actually there was one more thing! I don't know if it's related to work on this PR, or if it should be an extra card/issue. But I do get a flash of the questions index number (I think) before it changes to its randomized question number (if that makes sense).

Screen.Recording.2024-02-23.at.3.11.25.PM.mov

I don't really make it clear in the video, but it happens when I click either the "Next" and "Previous" buttons.

@dustin-jw
Copy link
Contributor Author

If that looks like you'd expect it, I'll approve!

The minified file looks correct to me. The reason those last few lines stand out is due to a multi-line string, which is preserving the original whitespace. It's not strictly necessary in this case, but that is generally what we want to happen with those kinds of strings 👍

Questions (purely for my own understanding):

1. It seems like some of this work was refactoring- pulling functions from larger files, into smaller pieces. How do you determine what gets extracted to a separate file, vs. just stays within a larger file?

Some people take it to an extreme, like "one file for every function", while others will just put everything in one file. It's been a while since I wrote this PR, but I think my rule of thumb was to group related behaviors and keep entry points slim, so for example update-pagination-links.js has a bunch of helper functions that go into the updatePaginationLinks function that is exported and used elsewhere. Those entry points (flash-cards.js, game-selection.js, multiple-choice.js, and short-answer.js) all just import functions and call them to set up the behavior they need.

2. What exactly is the `.ejs` file for? After a quick google, it seems it means Embedded (or maybe effective?) JavaScript. It looks like it's transforming JSON?

Eleventy supports a ton of different templating languages, and EJS is one of them. I forget why I chose EJS for this instead of Nunjucks like everything else, but I'm guessing it had something to do with better support for JSON formatting.

3. I've done zero research on this, but I've seen the `robots.txt` a couple places lately. Can you share any like, resources or articles or anything, so I can understand what that file is doing?

The short answer is it isn't doing anything. The long answer is that it's a file that web crawlers look for and pinky promise to respect while indexing your site or scraping it to feed ChatGPT. There are things that you can put into a robots.txt to tell Google, for example, not to add your site or specific pages to their search results, but there's no real enforcement mechanism behind it. Here's a decent, but not super technical, history if you're interested.

4. What do "Distractor 1" and "Distractor 2" mean? Why those words? (again, if that's something I should just google, let me know)

Those are just the words we picked for the wrong multiple choice answers. You can see them in the column names in Airtable, so each multiple choice question has a right answer and up to two answers that distract you from the correct one.

It wouldn't be me without extra questions, right?!

I love the questions! It makes me think about things that I would totally gloss over otherwise or assume makes sense to everyone.

@dustin-jw
Copy link
Contributor Author

dustin-jw commented Feb 23, 2024

@dustin-jw Oh, actually there was one more thing! I don't know if it's related to work on this PR, or if it should be an extra card/issue. But I do get a flash of the questions index number (I think) before it changes to its randomized question number (if that makes sense).

This is a tricky thing to address because of how the site is built. During deployment, Eleventy grabs all the data it needs and builds every HTML file that we need for the site, and the HTML matches the permalinks, so /all/flash-cards/23/ has the baked in heading of "Question 23 of 50". So when we're randomizing the order, we have to update that question number, but to do so, the page needs to be rendered and our JS needs to look up which question number we should be showing. Really, the only way around having that flash of incorrect content would be to change our build to render HTML from a server on the fly, or maybe get into some advanced trickery with service workers, which I am now tempted to do.

@dustin-jw dustin-jw merged commit db61ff5 into main Feb 26, 2024
6 checks passed
@dustin-jw dustin-jw deleted the chore--js-build-process branch February 26, 2024 14:54
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