Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit ff37de2
Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Wed Mar 6 15:37:07 2024 +0100

    Version Packages (#378)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

commit 3235392
Author: Iakhub Seitasanov <[email protected]>
Date:   Wed Mar 6 17:29:46 2024 +0300

    fix: prevent duplication of location header (#369)

    * fix: prevent duplication of location header

    * changeset

    * fix linting

    ---------

    Co-authored-by: conico974 <[email protected]>

commit af2d3ce
Author: Chung Wei Leong <[email protected]>
Date:   Wed Mar 6 22:06:33 2024 +0800

    Fix image optimization support for Next 14.1.1 (#377)

    * Move image optimization to plugin

    * Refactor image optimization code

    * Added image optimization plugin for 14.1.1

    * Fix image optimization plugin

    * Add changeset

    * Revert default sharp version to 0.32.6

    * e2e test for image optimization

    * change one of the test to use an external image

    ---------

    Co-authored-by: Dorseuil Nicolas <[email protected]>

commit 3deb202
Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Tue Feb 13 08:39:35 2024 -0800

    Version Packages (#363)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

commit f9b90b6
Author: khuezy <[email protected]>
Date:   Tue Feb 13 08:35:10 2024 -0800

    changeset/2.3.6 (#362)

commit 40c2b36
Author: Patrick Ufer <[email protected]>
Date:   Tue Feb 13 09:23:40 2024 -0700

    security fix: upgrade sharp version to 0.32.6 (#361)

    * upgrade sharp version

commit 63fab05
Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Fri Feb 2 00:14:11 2024 +0100

    Version Packages (#359)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

commit c80f1be
Author: conico974 <[email protected]>
Date:   Fri Feb 2 00:00:56 2024 +0100

    Fix trailing slash redirect to external domain (#358)

    * fix trailing slash redirect to external domain

    * changeset

commit 186e28f
Author: Jaden VanEckhout <[email protected]>
Date:   Thu Feb 1 16:49:14 2024 -0600

    fix(open-next): correctly set cache control for html pages (#353)

    * fix(open-next): correctly set cache control for html pages

    * changeset

    ---------

    Co-authored-by: conico974 <[email protected]>

commit b9eefca
Author: Manuel Antunes <[email protected]>
Date:   Thu Feb 1 19:41:47 2024 -0300

    Fix Cache Support for [email protected] (#356)

    * feat: add cache support for [email protected]

    * fix: lint files

    * chore: apply the proposed changes

    * Fix typo

    * changeset

    ---------

    Co-authored-by: conico974 <[email protected]>

commit afd9605
Author: conico974 <[email protected]>
Date:   Sat Jan 27 15:19:11 2024 +0100

    update docs for V3 (#351)

commit 46241fe
Author: Abhishek Malik <[email protected]>
Date:   Sat Jan 27 19:45:18 2024 +0530

    Update bundle_size.mdx for excluding pdfjs-dist optional dependency docs (#346)

    * Update bundle_size.mdx for excluding pdfjs-dist optional dependency docs

    The current fix didn't work, but this updated fix did work for me. Hence proposing this as another solution.

    * Update docs/pages/common_issues/bundle_size.mdx

    Co-authored-by: khuezy <[email protected]>

    ---------

    Co-authored-by: khuezy <[email protected]>

commit 9a6473a
Author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Date:   Fri Jan 5 16:56:42 2024 +0100

    Version Packages (#345)

    Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

commit bbf9b30
Author: Lucas Vieira <[email protected]>
Date:   Fri Jan 5 12:45:13 2024 -0300

    fix(open-next): use dynamic import handler for monorepo entrypoint (#341)

    * fix(open-next): use dynamic import handler for monorepo entrypoint

    * changeset

    ---------

    Co-authored-by: Dorseuil Nicolas <[email protected]>

commit 83b0838
Author: santiperone <[email protected]>
Date:   Fri Jan 5 12:38:12 2024 -0300

    add suport for bun lockfile in monorepo (#337)

    * add suport for bun lockfile in monorepo

    * changeset

    ---------

    Co-authored-by: Dorseuil Nicolas <[email protected]>

commit e773e67
Author: Jan Stevens <[email protected]>
Date:   Fri Jan 5 16:31:27 2024 +0100

    fix: try to match errors, fall back to just adding raw key / value pare (#336)

    * fix: try to match errors, fall back to just adding raw key / value pair instead

    * changeset

    * fix lint

    ---------

    Co-authored-by: Dorseuil Nicolas <[email protected]>

commit fd90b26
Author: Dylan Irion <[email protected]>
Date:   Fri Jan 5 17:22:28 2024 +0200

    Changes encoding on cache.body from utf8 to base64 (#329)

    * changes encoding on cache.body from utf8 to base64

    * retain utf8 for json content-type

    * opting for less greedy base64

    * use isBinaryContentType

    * changeset

    ---------

    Co-authored-by: Dorseuil Nicolas <[email protected]>

commit eb08980
Author: sommeeeR <[email protected]>
Date:   Fri Jan 5 16:02:47 2024 +0100

    fix: make invalidateCFPaths function async in docs (#344)

commit 83207d8
Author: conico974 <[email protected]>
Date:   Thu Dec 14 16:59:15 2023 +0100

    updated docs for v3 (#334)

commit 0e827ce
Author: conico974 <[email protected]>
Date:   Fri Dec 8 17:57:51 2023 +0100

    ci: update node e2e

commit 36da819
Author: conico974 <[email protected]>
Date:   Thu Dec 7 17:44:06 2023 +0100

    Initial docs for V3 (#330)

    * docs for V3

    * fix link

    * clearer routes in config
  • Loading branch information
conico974 committed Mar 10, 2024
1 parent 46562b1 commit 429914a
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 34 deletions.
14 changes: 14 additions & 0 deletions examples/app-pages-router/app/image-optimization/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Image from "next/image";

export default function ImageOptimization() {
return (
<div>
<Image
src="/static/corporate_holiday_card.jpg"
alt="Corporate Holiday Card"
width={300}
height={300}
/>
</div>
);
}
3 changes: 3 additions & 0 deletions examples/app-pages-router/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export default function Home() {
<Nav href={"/parallel"} title="Parallel">
Parallel routing
</Nav>
<Nav href={"/image-optimization"} title="Image Optimization">
Image Optimization with next/image
</Nav>
</main>
<h1>Pages Router</h1>
<main className="grid grid-cols-2 gap-4 p-10 [&>a]:border">
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions examples/app-router/app/image-optimization/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Image from "next/image";

export default function ImageOptimization() {
return (
<div>
<Image
src="https://open-next.js.org/architecture.png"
alt="Open Next architecture"
width={300}
height={300}
/>
</div>
);
}
3 changes: 3 additions & 0 deletions examples/app-router/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export default function Home() {
<Nav href={"/revalidate-tag"} title="Revalidate Tag">
Revalidate Tag
</Nav>
<Nav href={"/image-optimization"} title="Image Optimization">
Image Optimization with next/image
</Nav>
</main>
</>
);
Expand Down
8 changes: 8 additions & 0 deletions examples/app-router/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ const nextConfig = {
experimental: {
serverActions: true,
},
images: {
remotePatterns: [
{
protocol: "https",
hostname: "open-next.js.org",
},
],
},
redirects: () => {
return [
{
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions packages/open-next/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# open-next

## 2.3.7

### Patch Changes

- 3235392: fix: prevent duplication of location header
- af2d3ce: Fix Image Optimization Support for [email protected]

## 2.3.6

### Patch Changes

- f9b90b6: Security fix: [email protected]

## 2.3.5

### Patch Changes
Expand Down
27 changes: 7 additions & 20 deletions packages/open-next/src/adapters/image-optimization-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import path from "node:path";
import { Writable } from "node:stream";

import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import type { APIGatewayProxyEventHeaders } from "aws-lambda";
import { loadConfig } from "config/util.js";
// @ts-ignore
import { defaultConfig } from "next/dist/server/config-shared";
import {
imageOptimizer,
ImageOptimizerCache,
// @ts-ignore
} from "next/dist/server/image-optimizer";
Expand All @@ -23,6 +21,7 @@ import { ImageLoader, InternalEvent, InternalResult } from "types/open-next.js";

import { createGenericHandler } from "../core/createGenericHandler.js";
import { awsLogger, debug, error } from "./logger.js";
import { optimizeImage } from "./plugins/image-optimization/image-optimization.js";
import { setNodeEnv } from "./util.js";

// Expected environment variables
Expand Down Expand Up @@ -69,7 +68,12 @@ export async function defaultHandler(
headers,
queryString === null ? undefined : queryString,
);
const result = await optimizeImage(headers, imageParams);
const result = await optimizeImage(
headers,
imageParams,
nextConfig,
downloadHandler,
);

return buildSuccessResponse(result);
} catch (e: any) {
Expand Down Expand Up @@ -115,23 +119,6 @@ function validateImageParams(
return imageParams;
}

async function optimizeImage(
headers: APIGatewayProxyEventHeaders,
imageParams: any,
) {
const result = await imageOptimizer(
// @ts-ignore
{ headers },
{}, // res object is not necessary as it's not actually used.
imageParams,
nextConfig,
false, // not in dev mode
downloadHandler,
);
debug("optimized result", result);
return result;
}

function buildSuccessResponse(result: any): InternalResult {
return {
type: "core",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { IncomingMessage, ServerResponse } from "node:http";

import type { APIGatewayProxyEventHeaders } from "aws-lambda";
import type { NextConfig } from "next/dist/server/config-shared";
//#override imports
import {
// @ts-ignore
fetchExternalImage,
// @ts-ignore
fetchInternalImage,
imageOptimizer,
} from "next/dist/server/image-optimizer";
//#endOverride
import type { NextUrlWithParsedQuery } from "next/dist/server/request-meta";

import { debug } from "../../logger.js";

//#override optimizeImage
export async function optimizeImage(
headers: APIGatewayProxyEventHeaders,
imageParams: any,
nextConfig: NextConfig,
handleRequest: (
newReq: IncomingMessage,
newRes: ServerResponse,
newParsedUrl?: NextUrlWithParsedQuery,
) => Promise<void>,
) {
const { isAbsolute, href } = imageParams;

const imageUpstream = isAbsolute
? await fetchExternalImage(href)
: await fetchInternalImage(
href,
// @ts-ignore
{ headers },
{}, // res object is not necessary as it's not actually used.
handleRequest,
);

// @ts-ignore
const result = await imageOptimizer(
imageUpstream,
imageParams,
nextConfig,
false, // not in dev mode
);
debug("optimized result", result);
return result;
}
//#endOverride
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { IncomingMessage, ServerResponse } from "node:http";

import { APIGatewayProxyEventHeaders } from "aws-lambda";
import { NextConfig } from "next/dist/server/config-shared";
//#override imports
import { imageOptimizer } from "next/dist/server/image-optimizer";
//#endOverride
import { NextUrlWithParsedQuery } from "next/dist/server/request-meta";

import { debug } from "../../logger.js";

//#override optimizeImage
export async function optimizeImage(
headers: APIGatewayProxyEventHeaders,
imageParams: any,
nextConfig: NextConfig,
handleRequest: (
newReq: IncomingMessage,
newRes: ServerResponse,
newParsedUrl: NextUrlWithParsedQuery,
) => Promise<void>,
) {
const result = await imageOptimizer(
// @ts-ignore
{ headers },
{}, // res object is not necessary as it's not actually used.
imageParams,
nextConfig,
false, // not in dev mode
handleRequest,
);
debug("optimized result", result);
return result;
}
//#endOverride
29 changes: 25 additions & 4 deletions packages/open-next/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cp from "node:child_process";
import fs, { readFileSync } from "node:fs";
import { createRequire as topLevelCreateRequire } from "node:module";
import os from "node:os";
import path from "node:path";
import url from "node:url";
Expand All @@ -13,6 +14,7 @@ import { buildEdgeBundle } from "./build/edge/createEdgeBundle.js";
import { generateOutput } from "./build/generateOutput.js";
import {
BuildOptions,
compareSemver,
copyOpenNextConfig,
esbuildAsync,
esbuildSync,
Expand All @@ -24,9 +26,11 @@ import {
} from "./build/helper.js";
import { validateConfig } from "./build/validateConfig.js";
import logger from "./logger.js";
import { openNextReplacementPlugin } from "./plugins/replacement.js";
import { openNextResolvePlugin } from "./plugins/resolve.js";
import { OpenNextConfig } from "./types/open-next.js";

const require = topLevelCreateRequire(import.meta.url);
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
let options: BuildOptions;
let config: OpenNextConfig;
Expand Down Expand Up @@ -74,9 +78,10 @@ export async function build(openNextConfigPath?: string) {

createStaticAssets();
await createCacheAssets(monorepoRoot);

await createServerBundle(config, options);
await createRevalidationBundle();
createImageOptimizationBundle();
await createImageOptimizationBundle();
await createWarmerBundle();
await generateOutput(options.appBuildOutputPath, config);
logger.info("OpenNext build complete.");
Expand Down Expand Up @@ -314,7 +319,7 @@ async function createRevalidationBundle() {
);
}

function createImageOptimizationBundle() {
async function createImageOptimizationBundle() {
logger.info(`Bundling image optimization function...`);

const { appPath, appBuildOutputPath, outputDir } = options;
Expand All @@ -326,17 +331,33 @@ function createImageOptimizationBundle() {
// Copy open-next.config.mjs into the bundle
copyOpenNextConfig(options.tempDir, outputPath);

const plugins =
compareSemver(options.nextVersion, "14.1.1") >= 0
? [
openNextReplacementPlugin({
name: "opennext-14.1.1-image-optimization",
target: /plugins\/image-optimization\/image-optimization\.js/g,
replacements: [
require.resolve(
"./adapters/plugins/image-optimization/image-optimization.replacement.js",
),
],
}),
]
: undefined;

// Build Lambda code (1st pass)
// note: bundle in OpenNext package b/c the adapter relies on the
// "@aws-sdk/client-s3" package which is not a dependency in user's
// Next.js app.
esbuildSync(
await esbuildAsync(
{
entryPoints: [
path.join(__dirname, "adapters", "image-optimization-adapter.js"),
],
external: ["sharp", "next"],
outfile: path.join(outputPath, "index.mjs"),
plugins,
},
options,
);
Expand Down Expand Up @@ -375,7 +396,7 @@ function createImageOptimizationBundle() {
// For SHARP_IGNORE_GLOBAL_LIBVIPS see: https://github.com/lovell/sharp/blob/main/docs/install.md#aws-lambda

const nodeOutputPath = path.resolve(outputPath);
const sharpVersion = process.env.SHARP_VERSION ?? "0.32.5";
const sharpVersion = process.env.SHARP_VERSION ?? "0.32.6";

//check if we are running in Windows environment then set env variables accordingly.
try {
Expand Down
18 changes: 8 additions & 10 deletions packages/open-next/src/core/routing/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,21 +122,19 @@ export async function handleMiddleware(
// If the middleware returned a Redirect, we set the `Location` header with
// the redirected url and end the response.
if (statusCode >= 300 && statusCode < 400) {
const location = result.headers
.get("location")
?.replace(
"http://localhost:3000",
`https://${internalEvent.headers.host}`,
);
resHeaders.location =
responseHeaders
.get("location")
?.replace(
"http://localhost:3000",
`https://${internalEvent.headers.host}`,
) ?? resHeaders.location;
// res.setHeader("Location", location);
return {
body: "",
type: internalEvent.type,
statusCode: statusCode,
headers: {
...resHeaders,
Location: location ?? "",
},
headers: resHeaders,
isBase64Encoded: false,
};
}
Expand Down
20 changes: 20 additions & 0 deletions packages/tests-e2e/tests/appPagesRouter/image-optimization.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from "@playwright/test";

test("Image Optimization", async ({ page }) => {
await page.goto("/");

const imageResponsePromise = page.waitForResponse(
/corporate_holiday_card.jpg/,
);
await page.locator('[href="/image-optimization"]').click();
const imageResponse = await imageResponsePromise;

await page.waitForURL("/image-optimization");

const imageContentType = imageResponse.headers()["content-type"];
expect(imageContentType).toBe("image/webp");

let el = page.locator("img");
await expect(el).toHaveJSProperty("complete", true);
await expect(el).not.toHaveJSProperty("naturalWidth", 0);
});
20 changes: 20 additions & 0 deletions packages/tests-e2e/tests/appRouter/image-optimization.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from "@playwright/test";

test("Image Optimization", async ({ page }) => {
await page.goto("/");

const imageResponsePromise = page.waitForResponse(
/https%3A%2F%2Fopen-next.js.org%2Farchitecture.png/,
);
await page.locator('[href="/image-optimization"]').click();
const imageResponse = await imageResponsePromise;

await page.waitForURL("/image-optimization");

const imageContentType = imageResponse.headers()["content-type"];
expect(imageContentType).toBe("image/webp");

let el = page.locator("img");
await expect(el).toHaveJSProperty("complete", true);
await expect(el).not.toHaveJSProperty("naturalWidth", 0);
});
Loading

0 comments on commit 429914a

Please sign in to comment.