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: add blob storage #2287

Merged
merged 221 commits into from
Oct 17, 2023
Merged

feat: add blob storage #2287

merged 221 commits into from
Oct 17, 2023

Conversation

nickytonline
Copy link

@nickytonline nickytonline commented Aug 29, 2023

Description

Uses Netlify blob storage for prerendered content instead of storing prerendered content in the generated lambdas, assuming blob storage is configured for the site.

There are 2 distinct and somewhat separate changes here:

  1. (minimal code changes) we don't force fresh/revalidated content on first ODB request anymore (we use x-prerender-revalidate header to force revalidation) - this applies also when blob storage is not used (then it will use files from lambda instead of blob storage)
    • note here - this change makes fallback: true pages behavior really bad, because ODB would cache those fallback (think Skeleton) so for users they would always first see skeleton page before browser client would re-render with actual content (if navigated to a page directly, and not using client navigation like with @next/link).

      So to address that this also makes fallback: true behave more like fallback: blocking (which is behavior we do have today, so we are not changing it really)

  2. Use blob storage for ISR assets generated at build time:
    • we compile ESM-only @netlify/blobs to CJS via build:blob script - runtime is CJS and although there are tricks and hacks to still be able to use ESM version there are a lot of problems with them (await import is compiled to require using our current tsconfig, any eval tricks to avoid that later make lambda bundling problematic etc)
    • we check a feature flag (next-runtime-use-blobs-for-isr-assets) and if that is enabled we also test for availability of blob store to determine wether to use it (there are no additional feature flags)
    • if blob store is available:
      • (at build time) when we iterate over generated files after Next build, if file is connected to ISR page we upload the file content to blob storage and delete original file (currently we just keep the file as-is and those are later bundled into lambdas)
      • (at lambda request time) fs.readFIle will download a file from blob store (if the file to read was uploaded at build time). We already had mechanism like that that would pull files from CDN for SSG assets (like for example next-server deciding to serve 404 page) - that mechanism now can also pull from blob store as well.

Documentation

Tests

You can test this change yourself like so:

  1. TODO

Relevant links (GitHub issues, etc.) or a picture of cute animal

Fixes

Fixes https://github.com/netlify/pod-ecosystem-frameworks/issues/568
Fixes FRA-34

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for netlify-plugin-nextjs-static-root-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-static-root-demo/deploys/652e5dbf50f4df0008f8eacc
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-static-root-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for netlify-plugin-nextjs-next-auth-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-next-auth-demo/deploys/652e5dbfc3f702000890c309
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-next-auth-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for netlify-plugin-nextjs-nx-monorepo-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-nx-monorepo-demo/deploys/652e5dbfdfc875000854cc5c
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-nx-monorepo-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for netlify-plugin-nextjs-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-demo/deploys/652e5dbfa69aaa000826dec9
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for nextjs-plugin-custom-routes-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/nextjs-plugin-custom-routes-demo/deploys/652e5dbf5a0e6d0008fb5bf2
😎 Deploy Preview https://deploy-preview-2287--nextjs-plugin-custom-routes-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for next-plugin-canary ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-canary/deploys/652e5dbfbb57b30008a7c322
😎 Deploy Preview https://deploy-preview-2287--next-plugin-canary.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for next-plugin-edge-middleware ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/next-plugin-edge-middleware/deploys/652e5dbfbb01db000881b07c
😎 Deploy Preview https://deploy-preview-2287--next-plugin-edge-middleware.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for next-i18next-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/next-i18next-demo/deploys/652e5dbfd43959000874257b
😎 Deploy Preview https://deploy-preview-2287--next-i18next-demo.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.

@netlify
Copy link

netlify bot commented Aug 29, 2023

Deploy Preview for netlify-plugin-nextjs-export-demo ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-export-demo/deploys/652e5dbfc3f702000890c304
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-export-demo.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.

@netlify
Copy link

netlify bot commented Aug 31, 2023

Deploy Preview for netlify-plugin-nextjs-demo-all-flags ready!

Name Link
🔨 Latest commit ff4d8c5
🔍 Latest deploy log https://app.netlify.com/sites/netlify-plugin-nextjs-demo-all-flags/deploys/652e5dbff16fee00080d0520
😎 Deploy Preview https://deploy-preview-2287--netlify-plugin-nextjs-demo-all-flags.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.

@github-actions github-actions bot added the type: feature code contributing to the implementation of a feature and/or user facing functionality label Sep 5, 2023
Comment on lines 1 to 20
import * as esbuild from '@netlify/esbuild'

// https://github.com/evanw/esbuild/issues/1760#issuecomment-964900401
const stripNodeColonPlugin = {
name: 'strip-node-colon',
setup({ onResolve, onLoad }) {
onResolve({ filter: /^node:/ }, (args) => {
return { path: args.path.slice('node:'.length), external: true }
})
},
}

await esbuild.build({
entryPoints: ['src/templates/netliblob.mts'],
format: 'cjs',
bundle: true,
outfile: 'src/templates/blob.js',
platform: 'node',
plugins: [stripNodeColonPlugin],
})
Copy link
Contributor

Choose a reason for hiding this comment

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

this compiles ESM-only @netlify/blobs to CJS and removes node: prefixes in import/requires (like from node:fs) to make resulting code compatible with our minimal node version

Comment on lines +152 to +159
setBlobInit({
authentication: {
contextURL: data.url,
token: data.token,
},
context: `deploy:${event.headers['x-nf-deploy-id']}`,
siteID: event.headers['x-nf-site-id'],
})
Copy link
Contributor

Choose a reason for hiding this comment

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

We use Blob Storage in a place that doesn't have direct access to event/context which is needed to initialize the store, so instead we globally set init argument on each request. This means it's possible that requests would use init data we got from another one (depending on timing), but this is acceptable/ok to do and only note is that there is expiration time on token so that's why this being refreshed on each request and not just once.

Comment on lines +1 to +8
if (!globalThis.fetch) {
const fetch = require('node-fetch')

globalThis.fetch = fetch
globalThis.Headers = fetch.Headers
globalThis.Request = fetch.Request
globalThis.Response = fetch.Response
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this is used just in Next's e2e tests setup, everywhere else there is global fetch (@netlify/blobs require fetch to be either passed in or to be globally available)

@pieh pieh marked this pull request as ready for review October 5, 2023 13:42
@pieh pieh requested a review from a team as a code owner October 5, 2023 13:42
/**
* @netlify/blobs ATM has some limitation to keys, so we need to normalize it for now (they will be resolved so we will be able to remove this code)
*/
export const getNormalizedBlobKey = (key: string): string => Buffer.from(key).toString('base64url')
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this fixed now? I know soemthing about encoding keys has landed

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not yet fully fixed - some fixes did land, but for now result is that keys starting with / are no longer throwing, but trying to read those keys result in null values, so we still need this for time being

ascorbic
ascorbic previously approved these changes Oct 10, 2023
orinokai
orinokai previously approved these changes Oct 10, 2023
Copy link
Contributor

@orinokai orinokai left a comment

Choose a reason for hiding this comment

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

Wow, this was quite an undertaking! Thanks @pieh, looks great.

// `fallback: true` is not working correctly with ODBs
// as we will cache fallback html forever, so
// we are treating those as `fallback: blocking`
// by editing the manifest
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for documenting all these!

@pieh pieh dismissed stale reviews from orinokai and ascorbic via 563a189 October 10, 2023 13:33
@nickytonline
Copy link
Author

I still get notified since I opened the PR. Great work @pieh!

orinokai
orinokai previously approved these changes Oct 10, 2023
Copy link
Author

@nickytonline nickytonline left a comment

Choose a reason for hiding this comment

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

:shipit:

@linear
Copy link

linear bot commented Oct 13, 2023

FRA-34 Add blob storage to reduce bundle size

#2287

orinokai
orinokai previously approved these changes Oct 16, 2023
Copy link
Contributor

@orinokai orinokai left a comment

Choose a reason for hiding this comment

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

All looks dandy 🚢

Copy link
Contributor

@MarcL MarcL left a comment

Choose a reason for hiding this comment

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

:shipit:

@pieh pieh merged commit 5da5a8c into main Oct 17, 2023
76 checks passed
@pieh pieh deleted the nickytonline/blob-storage branch October 17, 2023 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature code contributing to the implementation of a feature and/or user facing functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants