From d98e9d13e7fc3009b05ee051943a88585f12dd95 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 16:24:09 -0400 Subject: [PATCH 1/6] Add warning during `next build` when sharp is missing --- packages/next/build/index.ts | 11 ++++++ .../image-optimizer/test/index.test.js | 35 +++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 6621ed8ef2cf5b1..a0d0f4b0d349606 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -930,6 +930,17 @@ export default async function build( return returnValue }) + if (isNextImageImported) { + try { + require(process.env.NEXT_SHARP_PATH || 'sharp') + } catch (e) { + Log.warn( + `The optional \`sharp\` package is strongly recommended for production Image Optimization. Run \`yarn add sharp\`, and Next.js will use it automatically.\n` + + 'Read more: https://nextjs.org/docs/messages/sharp-missing-in-production' + ) + } + } + if (customAppGetInitialProps) { console.warn( chalk.bold.yellow(`Warning: `) + diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index 9faab437aa3d7fd..a869f909e0a4baa 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -25,8 +25,8 @@ const largeSize = 1080 // defaults defined in server/config.ts let nextOutput let appPort let app - -const sharpMissingText = `For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended` +const sharpRuntimeWarning = `For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended` +const sharpBuildWarning = `The optional \`sharp\` package is strongly recommended for production Image Optimization` async function fsToJson(dir, output = {}) { const files = await fs.readdir(dir) @@ -727,12 +727,20 @@ function runTests({ w, isDev, domains = [], ttl, isSharp }) { }) if (isDev || isSharp) { - it('should not have sharp missing warning', () => { - expect(nextOutput).not.toContain(sharpMissingText) + it('should not have runtime sharp missing warning', () => { + expect(nextOutput).not.toContain(sharpRuntimeWarning) + }) + + it('should not have runtime sharp missing warning', () => { + expect(buildOutput).not.toContain(sharpBuildWarning) }) } else { - it('should have sharp missing warning', () => { - expect(nextOutput).toContain(sharpMissingText) + it('should have runtime sharp missing warning', () => { + expect(nextOutput).toContain(sharpRuntimeWarning) + }) + + it('should have build time sharp missing warning', () => { + expect(buildOutput).toContain(sharpBuildWarning) }) } } @@ -911,7 +919,8 @@ describe('Image Optimizer', () => { }) nextOutput = '' nextConfig.replace('{ /* replaceme */ }', json) - await nextBuild(appDir) + const out = await nextBuild(appDir, [], { stderr: true }) + buildOutput = out.stderr appPort = await findPort() app = await nextStart(appDir, appPort, { onStderr(msg) { @@ -949,7 +958,8 @@ describe('Image Optimizer', () => { }, }` ) - await nextBuild(appDir) + const out = await nextBuild(appDir, [], { stderr: true }) + buildOutput = out.stderr appPort = await findPort() app = await nextStart(appDir, appPort) }) @@ -1025,7 +1035,8 @@ describe('Image Optimizer', () => { }, }` nextConfig.replace('{ /* replaceme */ }', newConfig) - await nextBuild(appDir) + const out = await nextBuild(appDir, [], { stderr: true }) + buildOutput = out.stderr appPort = await findPort() app = await nextStart(appDir, appPort) }) @@ -1133,7 +1144,8 @@ describe('Image Optimizer', () => { const size = 384 // defaults defined in server/config.ts beforeAll(async () => { nextOutput = '' - await nextBuild(appDir) + const out = await nextBuild(appDir, [], { stderr: true }) + buildOutput = out.stderr appPort = await findPort() app = await nextStart(appDir, appPort, { onStderr(msg) { @@ -1168,7 +1180,8 @@ describe('Image Optimizer', () => { }) nextOutput = '' nextConfig.replace('{ /* replaceme */ }', json) - await nextBuild(appDir) + const out = await nextBuild(appDir, [], { stderr: true }) + buildOutput = out.stderr appPort = await findPort() app = await nextStart(appDir, appPort, { onStderr(msg) { From a10ed0fb64f1960288cb3b8591237c45c5672c6d Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 16:59:56 -0400 Subject: [PATCH 2/6] Decrease warning size --- packages/next/build/index.ts | 3 +-- test/integration/image-optimizer/test/index.test.js | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index a0d0f4b0d349606..7cffc108fc4abab 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -935,8 +935,7 @@ export default async function build( require(process.env.NEXT_SHARP_PATH || 'sharp') } catch (e) { Log.warn( - `The optional \`sharp\` package is strongly recommended for production Image Optimization. Run \`yarn add sharp\`, and Next.js will use it automatically.\n` + - 'Read more: https://nextjs.org/docs/messages/sharp-missing-in-production' + 'Detected `next/image` usage without `sharp` package. Please run `yarn add sharp`. Read more: https://nextjs.org/docs/messages/sharp-missing-in-production' ) } } diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index a869f909e0a4baa..0378eb0f1a58d91 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -26,7 +26,8 @@ let nextOutput let appPort let app const sharpRuntimeWarning = `For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended` -const sharpBuildWarning = `The optional \`sharp\` package is strongly recommended for production Image Optimization` +const sharpBuildWarning = + 'Detected `next/image` usage without `sharp` package. Please run `yarn add sharp`.' async function fsToJson(dir, output = {}) { const files = await fs.readdir(dir) From f8cbee56523efc7e096213fabfe8ab759400ceb1 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 17:13:51 -0400 Subject: [PATCH 3/6] Shorten message --- packages/next/build/index.ts | 2 +- test/integration/image-optimizer/test/index.test.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 7cffc108fc4abab..750ee7e70366426 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -935,7 +935,7 @@ export default async function build( require(process.env.NEXT_SHARP_PATH || 'sharp') } catch (e) { Log.warn( - 'Detected `next/image` usage without `sharp` package. Please run `yarn add sharp`. Read more: https://nextjs.org/docs/messages/sharp-missing-in-production' + 'Detected `next/image` usage without `sharp`. https://nextjs.org/docs/messages/sharp-missing-in-production' ) } } diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index 0378eb0f1a58d91..e172a71743c876a 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -26,8 +26,7 @@ let nextOutput let appPort let app const sharpRuntimeWarning = `For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended` -const sharpBuildWarning = - 'Detected `next/image` usage without `sharp` package. Please run `yarn add sharp`.' +const sharpBuildWarning = 'Detected `next/image` usage without `sharp`.' async function fsToJson(dir, output = {}) { const files = await fs.readdir(dir) From eb3a867ca384ab89a8aa74fd66d1a7d77b13a676 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 20:47:41 -0400 Subject: [PATCH 4/6] Fix lint --- test/integration/image-optimizer/test/index.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index e172a71743c876a..234b331282c7c4c 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -23,6 +23,7 @@ const imagesDir = join(appDir, '.next', 'cache', 'images') const nextConfig = new File(join(appDir, 'next.config.js')) const largeSize = 1080 // defaults defined in server/config.ts let nextOutput +let buildOutput let appPort let app const sharpRuntimeWarning = `For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended` From 98b7e5c5cef6881b16071bb46bc03f6dfaefec0c Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 21:39:39 -0400 Subject: [PATCH 5/6] Update tests --- .../image-optimizer/test/index.test.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index 234b331282c7c4c..739501224c7b1e7 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -727,20 +727,28 @@ function runTests({ w, isDev, domains = [], ttl, isSharp }) { expect(Object.keys(json1).length).toBe(1) }) - if (isDev || isSharp) { - it('should not have runtime sharp missing warning', () => { + if (isDev) { + it('should not have runtime warning in dev', () => { expect(nextOutput).not.toContain(sharpRuntimeWarning) }) - it('should not have runtime sharp missing warning', () => { + it('should not have build warning in dev', () => { + expect(buildOutput).not.toContain(sharpBuildWarning) + }) + } else if (isSharp) { + it('should not have runtime warning when sharp is installed', () => { + expect(nextOutput).not.toContain(sharpRuntimeWarning) + }) + + it('should not have build warning when sharp is installed', () => { expect(buildOutput).not.toContain(sharpBuildWarning) }) } else { - it('should have runtime sharp missing warning', () => { + it('should have runtime warning when sharp is not installed', () => { expect(nextOutput).toContain(sharpRuntimeWarning) }) - it('should have build time sharp missing warning', () => { + it('should have build warning when sharp is not installed', () => { expect(buildOutput).toContain(sharpBuildWarning) }) } @@ -919,6 +927,7 @@ describe('Image Optimizer', () => { }, }) nextOutput = '' + buildOutput = '' nextConfig.replace('{ /* replaceme */ }', json) const out = await nextBuild(appDir, [], { stderr: true }) buildOutput = out.stderr @@ -1096,6 +1105,7 @@ describe('Image Optimizer', () => { const size = 384 // defaults defined in server/config.ts beforeAll(async () => { nextOutput = '' + buildOutput = '' appPort = await findPort() app = await launchApp(appDir, appPort, { onStderr(msg) { @@ -1123,6 +1133,7 @@ describe('Image Optimizer', () => { }, }) nextOutput = '' + buildOutput = '' nextConfig.replace('{ /* replaceme */ }', json) appPort = await findPort() app = await launchApp(appDir, appPort, { @@ -1145,6 +1156,7 @@ describe('Image Optimizer', () => { const size = 384 // defaults defined in server/config.ts beforeAll(async () => { nextOutput = '' + buildOutput = '' const out = await nextBuild(appDir, [], { stderr: true }) buildOutput = out.stderr appPort = await findPort() @@ -1180,6 +1192,7 @@ describe('Image Optimizer', () => { }, }) nextOutput = '' + buildOutput = '' nextConfig.replace('{ /* replaceme */ }', json) const out = await nextBuild(appDir, [], { stderr: true }) buildOutput = out.stderr From 7c143c6a3d319869da331023645dc8276022e90a Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 10 Aug 2021 22:22:42 -0400 Subject: [PATCH 6/6] Fix sharp detection during `next build` --- packages/next/build/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 750ee7e70366426..cdb0f9d14df6123 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -932,7 +932,13 @@ export default async function build( if (isNextImageImported) { try { - require(process.env.NEXT_SHARP_PATH || 'sharp') + if (process.env.NEXT_SHARP_PATH) { + require(process.env.NEXT_SHARP_PATH) + } else { + require.resolve('sharp', { + paths: [path.join(dir, 'node_modules')], + }) + } } catch (e) { Log.warn( 'Detected `next/image` usage without `sharp`. https://nextjs.org/docs/messages/sharp-missing-in-production'