next.js: Unable to load FabricJS when using appDir due to .node bindings in the library

Verify canary release

  • I verified that the issue exists in the latest Next.js 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

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 4
  • Comments: 15 (1 by maintainers)

Most upvoted comments

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.

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
  }

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?

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

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.