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

Patterns deployment cache #1088

Closed
wants to merge 3 commits into from
Closed

Patterns deployment cache #1088

wants to merge 3 commits into from

Conversation

acelaya
Copy link
Contributor

@acelaya acelaya commented Jun 7, 2023

This PR introduces a number of changes in order to improve and more granularly control the patterns deployment cache in Cloudinary:

  • Update rollup's config to generate JS bundles with a content hash for production
  • Update nginx config to cache assets in the next way:
    • index.html file should never be cached, as it contains references for the hashed bundles (alternatively we could change this and use a small cache period, like 5min)
    • CSS/JS bundles can be cached "forever", because once they change, the hash will be different.
    • Image files cache to be determined
  • Create a new gulp task that manually replaces references to CSS/JS bundles with the ones including the hashes.
    There are rollup plugins to do this automatically, but since we are bundling CSS separately, we would need to orchestrate plugins and bundlings, so this seemed like a simple solution.

Considerations

  • The CSS bundle is still not generated with a hash, because it requires some changes in frontend-build's buildCSS function.
    I tested it locally, and there are a couple of possible approaches for this:
    • Use a postcss plugin
    • Extend our bundleCSS function to accept an option to generate a hash or not.
      I prefer this option, because it basically requires adding this snippet, and a couple changes here and there:
      import crypto from 'crypto';
      
      const hash = (content: string) => 
        crypto
          .createHash('sha256')
          .update(content)
          .digest('hex')
          .substr(0, 10);
  • The task to update the bundle references in the index file is quite coupled with this use case.
    We could also get rid of it using other building mechanisms, but for now this is the simplest option I could find.
  • The solutions applied here are perhaps too custom for this project specifically. We could consider other solutions that allow us to reuse existing tools.

Testing steps

TODO

This PR relates to #1084

@@ -3,15 +3,15 @@ FROM node:19.8.1-alpine as builder
COPY . /frontend-shared
RUN cd /frontend-shared && \
yarn install --frozen-lockfile && \
yarn build-pattern-lib
NODE_ENV=production yarn build-pattern-lib
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We cannot set ENV NODE_ENV=production for the whole docker stage, because then yarn install does not install dev dependencies, which are needed for bundling.

.replace('pattern-library.css', cssBundleName);

// eslint-disable-next-line no-undef
fs.writeFileSync('templates/index.html', Buffer.from(indexContent));
Copy link
Member

Choose a reason for hiding this comment

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

Here templates/index.html has become an actual template instead of just a static file. If that is the case then I think we should make that obvious by rendering it with a template renderer when served or at build time. Assuming we're continuing to serve this as static content, then the output should go into the build/ directory rather than modifying the source file.

Copy link
Member

Choose a reason for hiding this comment

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

The dumbest possible template renderer is to use some obvious placeholder like {{ js_bundle }} and do a string search and replace all. We might as well use something like Mustache though and at least get proper escaping.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here templates/index.html has become an actual template instead of just a static file. If that is the case then I think we should make that obvious by rendering it with a template renderer when served or at build time. Assuming we're continuing to serve this as static content, then the output should go into the build/ directory rather than modifying the source file.

We recently renamed this file to change the mustache-specific extension to .html because it was static. If it's a "template again," we should once again change the source file name, methinks.

@lyzadanger
Copy link
Contributor

Hi, @acelaya ! Can you help me understand if this PR has any relationship or overlaps with #1077 ?

@acelaya
Copy link
Contributor Author

acelaya commented Jun 7, 2023

Hi, @acelaya ! Can you help me understand if this PR has any relationship or overlaps with #1077 ?

Sure! #1077 is like the simplest possible approach in which we can have a reasonable solution for the caching issue.

However, in this thread Rob and I discussed further options, and this is one of them.

Honestly, I think we can just go with #1077, because it solves it in a good enough way that the extra effort's probably not worth it, but that's sometimes easier to see with a draft PR in front of you.

@acelaya
Copy link
Contributor Author

acelaya commented Jun 9, 2023

I have realized this can be achieved by using the existing generateManifest function from frontend-build, which brings hashing capabilities without affecting how we bundle CSS or JS, so I'm preparing another proposal which supersedes this one.

@acelaya acelaya closed this Jun 9, 2023
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.

3 participants