vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.15k stars 26.73k forks source link

Unable to load FabricJS when using appDir due to .node bindings in the library #43050

Open HMilbradt opened 1 year ago

HMilbradt commented 1 year ago

Verify canary release

Provide environment information

    Operating System:
      Platform: linux
      Arch: x64
      Version: #1 SMP Fri Apr 2 22:23:49 UTC 2021
    Binaries:
      Node: 16.18.0
      npm: 8.19.2
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.0.3-canary.4
      eslint-config-next: 13.0.0
      react: 18.2.0
      react-dom: 18.2.0

What browser are you using? (if relevant)

na

How are you deploying your application? (if relevant)

na

Describe the Bug

Loading FabricJS, which contains files that allow it to work on NodeJS, throws this error. I have tried importing it with next/dynamic, and I've tried to only import it inside mount effects, and I've tried conditionally rendering

Stack trace:

error - ./node_modules/canvas/build/Release/canvas.node
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

Expected Behavior

This currently works fine in normal NextJS pages directories, so I'm unsure if it's something I'm doing wrong, a problem that FabricJS needs to resolve, or something else entirely.

However, I would at least expect that using the dynamic component would work with ssr: false.

In the meantime I can just use a custom build of fabric, but this would be great to have some guidance on.

Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster

https://github.com/HMilbradt/next-13-fabric

To Reproduce

yarn install
yarn dev
http://localhost:3000
transitive-bullshit commented 1 year ago

I ran into the same issue using sharp. The solution I found was to mark it as external using a custom webpack config in your next.config.js:

  webpack: (config) => {
    config.externals.push({
      sharp: 'commonjs sharp',
      canvas: 'commonjs canvas'
    })
    return config
  }
balazsorban44 commented 1 year ago

In the case of Server Components, you can use the serverComponentsExternalPackages option to mark the package so Next.js won't bundle it.

You can refer to the docs: https://beta.nextjs.org/docs/api-reference/next.config.js#servercomponentsexternalpackages

This should fix it:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['fabric'],
  },
};

module.exports = nextConfig;

Still investigating the expected behavior for Client components ("use client").

(@transitive-bullshit sharp should already work, do you have a repro where it does not? See https://github.com/vercel/next.js/blob/canary/packages/next/lib/server-external-packages.ts)

transitive-bullshit commented 1 year ago

sharp should already work, do you have a repro where it does not?

I had a repro a week ago but have since moved sharp out of my project (have been updating canary daily and am using appDir). I only commented because it was the exact same error message the OP is getting.

transitive-bullshit commented 1 year ago

@balazsorban44 I just tried a minimal repro and sharp no longer complains 😄

karl-run commented 1 year ago

I'm moving some pages based API-routes to route handlers, the routes are using JSDom which has a peer depedency on canvas. I'm seeing the same .node bindings error:

Failed to compile.

./node_modules/canvas/build/Release/canvas.node
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

Import trace for requested module:
./node_modules/canvas/build/Release/canvas.node
./node_modules/canvas/lib/bindings.js
./node_modules/canvas/index.js
./node_modules/jsdom/lib/jsdom/utils.js
./node_modules/jsdom/lib/jsdom/browser/Window.js
./node_modules/jsdom/lib/api.js
./src/scraping/dom.ts
./src/scraping/client.ts
./src/app/api/poll-post/route.ts

An interesting quirk when I migrated these pages is that with the old API-routes API, I wasn't required to have JSDOM's peer dependency canvas as an explicit dependency. But as soon as I moved the pages (and refactored the API to match route handlers:

Failed to compile.

./node_modules/jsdom/lib/jsdom/utils.js
Module not found: Can't resolve 'canvas'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/jsdom/lib/jsdom/browser/Window.js
./node_modules/jsdom/lib/api.js
./src/scraping/dom.ts
./src/scraping/client.ts
./src/app/api/poll-post/route.ts

Are route handlers somehow more strict when it comes to module resolution as well?

karl-run commented 1 year ago

I created a quick repro in Codesanbox.

https://codesandbox.io/p/sandbox/white-water-k6fjgx?file=%2Fapp%2FREADME.md

Edit: Never mind :sweat: It works in the newest canary. Forgot to bump when I created a new Codesandbox.

hgogoi2012 commented 1 year ago

When using

webpack: (config) => { config.externals.push({ sharp: 'commonjs sharp', canvas: 'commonjs canvas', }); return config; },

It is working in development but during deployment in vercel I am getting this below error. Can someone please help me with it\

`

-- 06:58:01.855 | 57:11 Warning: Image elements must have an alt prop, either with meaningful text, or an empty string for decorative images. jsx-a11y/alt-text 06:58:01.855 |   06:58:01.855 | ./app/creator/create-product/component/resizeableImage.tsx 06:58:01.856 | 36:7 Warning: Image elements must have an alt prop, either with meaningful text, or an empty string for decorative images. jsx-a11y/alt-text 06:58:01.856 |   06:58:01.856 | ./app/creator/customize/editforms/SiteSettings.tsx 06:58:01.856 | 54:9 Warning: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images. jsx-a11y/alt-text 06:58:01.856 |   06:58:01.857 | info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules 06:58:02.687 | - info Collecting page data... 06:58:03.744 | - info Generating static pages (0/21) 06:58:03.905 | - info Generating static pages (5/21) 06:58:04.123 | - info Generating static pages (10/21) 06:58:04.276 | - info Generating static pages (15/21) 06:58:04.310 | Error: /lib64/libz.so.1: version ZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.310 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.310 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.310 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.310 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.310 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.310 | at Object.<anonymous> (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.310 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.311 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.311 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.311 | at Module._load (node:internal/modules/cjs/loader:958:12) { 06:58:04.311 | code: 'ERR_DLOPEN_FAILED' 06:58:04.312 | } 06:58:04.317 |   06:58:04.317 | Error occurred prerendering page "/creator/create-product". Read more: https://nextjs.org/docs/messages/prerender-error 06:58:04.317 | Error: /lib64/libz.so.1: versionZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.317 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.318 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.318 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.318 | at Object. (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.318 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.318 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.468 | - info Generating static pages (21/21) 06:58:04.471 |   06:58:04.471 | > Export encountered errors on following paths: 06:58:04.471 | /creator/create-product/page: /creator/create-product

`

alejandro28100 commented 1 year ago

Error: /lib64/libz.so.1: versionZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.310 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.310 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.310 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.310 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.310 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.310 | at Object. (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.310 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.311 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.311 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.311 | at Module._load (node:internal/modules/cjs/loader:958:12) { 06:58:04.311 | code: 'ERR_DLOPEN_FAILED' 06:58:04.312 | } 06:58:04.317 |   06:58:04.317 | Error occurred prerendering page "/creator/create-product". Read more: https://nextjs.org/docs/messages/prerender-error 06:58:04.317 | Error: /lib64/libz.so.1: version `ZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.317 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.318 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.318 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.318 | at Object. (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.318 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.318 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.468 | - info Generating static pages (21/21) 06:58:04.471 |   06:58:04.471 | > Export encountered errors on following paths: 06:58:04.471 | /creator/create-product/page: /creator/create-product

`

@hgogoi2012 I was facing the same error when deploying to vercel. I'm not using the app dir though. You may want to check out this issue. The solution mentioned there solved the error I was facing.

https://github.com/Automattic/node-canvas/issues/1779#issuecomment-1557079079

hgogoi2012 commented 1 year ago

Error: /lib64/libz.so.1: versionZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.310 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.310 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.310 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.310 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.310 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.310 | at Object. (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.310 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.311 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.311 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.311 | at Module._load (node:internal/modules/cjs/loader:958:12) { 06:58:04.311 | code: 'ERR_DLOPEN_FAILED' 06:58:04.312 | } 06:58:04.317 |   06:58:04.317 | Error occurred prerendering page "/creator/create-product". Read more: https://nextjs.org/docs/messages/prerender-error 06:58:04.317 | Error: /lib64/libz.so.1: version ZLIB_1.2.9' not found (required by /vercel/path0/node_modules/canvas/build/Release/libpng16.so.16) 06:58:04.317 | at Module._extensions..node (node:internal/modules/cjs/loader:1338:18) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.318 | at Module.require (node:internal/modules/cjs/loader:1141:19) 06:58:04.318 | at require (node:internal/modules/cjs/helpers:110:18) 06:58:04.318 | at Object. (/vercel/path0/node_modules/canvas/lib/bindings.js:3:18) 06:58:04.318 | at Module._compile (node:internal/modules/cjs/loader:1254:14) 06:58:04.318 | at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) 06:58:04.318 | at Module.load (node:internal/modules/cjs/loader:1117:32) 06:58:04.318 | at Module._load (node:internal/modules/cjs/loader:958:12) 06:58:04.468 | - info Generating static pages (21/21) 06:58:04.471 |   06:58:04.471 | > Export encountered errors on following paths: 06:58:04.471 | /creator/create-product/page: /creator/create-product

@hgogoi2012 I was facing the same error when deploying to vercel. I'm not using the app dir though. You may want to check out this issue. The solution mentioned there solved the error I was facing.

Automattic/node-canvas#1779 (comment)

It worked for few days but after than I got another error from vercel saying that node js 16.x has reach its lifeline (Some similar error) and to complete the deployment i need to upgrade to nodejs 18.x and once i upgraded to 18.x i again started getting the same error.

davafy111 commented 1 year ago

If u are using fabric 5.3 & nextjs app router, change it to pages router, this solve the issue. If u are using fabricjs 6.0 beta, then app router & pages router are all fine. Hope this help someone.

omatheusant commented 9 months ago

If u are using fabric 5.3 & nextjs app router, change it to pages router, this solve the issue. If u are using fabricjs 6.0 beta, then app router & pages router are all fine. Hope this help someone.

i'm having this issue with fabric js and AppDir, if this works, you ll be a angel for me

TharindaPrabhath commented 9 months ago

I ran into the same issue using sharp. The solution I found was to mark it as external using a custom webpack config in your next.config.js:

  webpack: (config) => {
    config.externals.push({
      sharp: 'commonjs sharp',
      canvas: 'commonjs canvas'
    })
    return config
  }

Hi, In my case adding such a custom webpack config broke the fast refresh. Has anybody experienced it?

kirtirajsinh commented 8 months ago

I am getting the same error on adding the fabricjs in a fresh app router repo. Here's the error I am getting

./node_modules/canvas/build/Release/canvas.node Module parse failed: Unexpected character '�' (1:2) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders (Source code omitted for this binary file)

Can someone help

omatheusant commented 8 months ago

I am getting the same error on adding the fabricjs in a fresh app router repo. Here's the error I am getting

./node_modules/canvas/build/Release/canvas.node Module parse failed: Unexpected character '�' (1:2) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders (Source code omitted for this binary file)

Can someone help

Add this in my next.config.js solve my issue;

const nextConfig = {
  reactStrictMode: false,
  webpack: (config) => {
  config.externals.push({
  sharp: "commonjs sharp",
  canvas: "commonjs canvas"
  })
  return config
  },
  }

  module.exports = nextConfig
codesharpdev commented 8 months ago

The reason is to configure the webpack for canvas runtime error that will crash the application and utf-8-validate & bufferutil warning.

Below is the code for next.config.js to solve the issue.

/** @type {import('next').NextConfig} */
const nextConfig = {
  // reactStrictMode: false,
  webpack: (config) => {
    config.externals.push({
      "utf-8-validate": "commonjs utf-8-validate",
      bufferutil: "commonjs bufferutil",
      canvas: "commonjs canvas",
    });
    // config.infrastructureLogging = { debug: /PackFileCache/ };
    return config;
  },
};

module.exports = nextConfig;

*Solution is working for Fabric JS.

AsimSafarli commented 4 months ago

thanks this code help to my code for deploy