Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[edge] allow importing blob assets (#38492)
* [edge] allow importing blob assets * Fix test * extract to a new file, to make it easier to read and review * Use webpack asset discovery and transform with a loader * fix tests * don't prefix assets * use emitFile * rename assets to blobs to be more specific * rename blobs to assets and use webpack's hashing algo * Dedupe correctly * Add a Node.js dep test * Update packages/next/server/next-server.ts Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com> * [code review] test remote URL fetches * [code review] use `import type` for type-only imports * Update packages/next/server/next-server.ts Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com> * Apply suggestions from code review Co-authored-by: JJ Kasper <jj@jjsweb.site> Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com> Co-authored-by: JJ Kasper <jj@jjsweb.site>
- Loading branch information
1 parent
9b312db
commit 20486c1
Showing
16 changed files
with
298 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
packages/next/build/webpack/loaders/next-middleware-asset-loader.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import loaderUtils from 'next/dist/compiled/loader-utils3' | ||
import { getModuleBuildInfo } from './get-module-build-info' | ||
|
||
export default function MiddlewareAssetLoader(this: any, source: Buffer) { | ||
const name = loaderUtils.interpolateName(this, '[name].[hash].[ext]', { | ||
context: this.rootContext, | ||
content: source, | ||
}) | ||
const filePath = `edge-chunks/asset_${name}` | ||
const buildInfo = getModuleBuildInfo(this._module) | ||
buildInfo.nextAssetMiddlewareBinding = { | ||
filePath: `server/${filePath}`, | ||
name, | ||
} | ||
this.emitFile(filePath, source) | ||
return `module.exports = ${JSON.stringify(`blob:${name}`)}` | ||
} | ||
|
||
export const raw = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { createReadStream, promises as fs } from 'fs' | ||
import path from 'path' | ||
import { requestToBodyStream } from '../../body-streams' | ||
import type { EdgeFunctionDefinition } from '../../../build/webpack/plugins/middleware-plugin' | ||
|
||
/** | ||
* Short-circuits the `fetch` function | ||
* to return a stream for a given asset, if a user used `new URL("file", import.meta.url)`. | ||
* This allows to embed assets in Edge Runtime. | ||
*/ | ||
export async function fetchInlineAsset(options: { | ||
input: RequestInfo | ||
distDir: string | ||
assets: EdgeFunctionDefinition['assets'] | ||
context: { Response: any } | ||
}): Promise<Response | undefined> { | ||
const inputString = String(options.input) | ||
if (!inputString.startsWith('blob:')) { | ||
return | ||
} | ||
|
||
const hash = inputString.replace('blob:', '') | ||
const asset = options.assets?.find((x) => x.name === hash) | ||
if (!asset) { | ||
return | ||
} | ||
|
||
const filePath = path.resolve(options.distDir, asset.filePath) | ||
|
||
const fileIsReadable = await fs.access(filePath).then( | ||
() => true, | ||
() => false | ||
) | ||
|
||
if (fileIsReadable) { | ||
const readStream = createReadStream(filePath) | ||
return new options.context.Response(requestToBodyStream(readStream)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
test/e2e/edge-compiler-can-import-blob-assets/app/node_modules/my-pkg/hello/world.json
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
60 changes: 60 additions & 0 deletions
60
test/e2e/edge-compiler-can-import-blob-assets/app/pages/api/edge.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
export const config = { runtime: 'experimental-edge' } | ||
|
||
/** | ||
* @param {import('next/server').NextRequest} req | ||
*/ | ||
export default async (req) => { | ||
const handlerName = req.nextUrl.searchParams.get('handler') | ||
const handler = handlers.get(handlerName) || defaultHandler | ||
return handler() | ||
} | ||
|
||
/** | ||
* @type {Map<string, () => Promise<Response>>} | ||
*/ | ||
const handlers = new Map([ | ||
[ | ||
'text-file', | ||
async () => { | ||
const url = new URL('../../src/text-file.txt', import.meta.url) | ||
return fetch(url) | ||
}, | ||
], | ||
[ | ||
'image-file', | ||
async () => { | ||
const url = new URL('../../src/vercel.png', import.meta.url) | ||
return fetch(url) | ||
}, | ||
], | ||
[ | ||
'from-node-module', | ||
async () => { | ||
const url = new URL('my-pkg/hello/world.json', import.meta.url) | ||
return fetch(url) | ||
}, | ||
], | ||
[ | ||
'remote-full', | ||
async () => { | ||
const url = new URL('https://example.vercel.sh') | ||
const response = await fetch(url) | ||
const headers = new Headers(response.headers) | ||
headers.delete('content-encoding') | ||
return new Response(response.body, { headers, status: response.status }) | ||
}, | ||
], | ||
[ | ||
'remote-with-base', | ||
async () => { | ||
const url = new URL('/', 'https://example.vercel.sh') | ||
const response = await fetch(url) | ||
const headers = new Headers(response.headers) | ||
headers.delete('content-encoding') | ||
return new Response(response.body, { headers, status: response.status }) | ||
}, | ||
], | ||
]) | ||
|
||
const defaultHandler = async () => | ||
new Response('Invalid handler', { status: 400 }) |
1 change: 1 addition & 0 deletions
1
test/e2e/edge-compiler-can-import-blob-assets/app/src/text-file.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Hello, from text-file.txt! |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.