Skip to content

__dirname is not defined with nextjs #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Loskir opened this issue Aug 8, 2022 · 1 comment · Fixed by Loskir/zbar-wasm-nextjs#1
Closed

__dirname is not defined with nextjs #2

Loskir opened this issue Aug 8, 2022 · 1 comment · Fixed by Loskir/zbar-wasm-nextjs#1

Comments

@Loskir
Copy link

Loskir commented Aug 8, 2022

Hello! I'm trying to add this library to my project that's using next.js

But I get this error and it doesn't build

image

Here's a reproducible example:

https://github.com/Loskir/zbar-wasm-nextjs

@undecaf
Copy link
Owner

undecaf commented Aug 10, 2022

This issue results from the combination of a few peculiarities:

  1. The file zbar.wasm is loaded by a loader created by Emscripten. Even if created as an ES6 module, this loader references __dirname and uses require('fs') and require('path'). This is a known issue.

  2. For pre-rendering, Next.js evaluates React components also in a Node context .

  3. @undecaf/zbar-wasm requires the file zbar.wasm to be located in the same directory as the zbar-wasm JS code.

Solution:

  • Instead of importing, require(@undecaf/zbar-wasm) in Next.js React components:

    import type { NextPage } from 'next'
    // Avoid importing from '@undecaf/zbar-wasm'
    const { scanImageData } = require('@undecaf/zbar-wasm')
    
    const Home: NextPage = () => {
      const scan = (image: ImageData) => {
        return scanImageData(image)
      }
      return (
        <div>Hello!</div>
      )
    }
    
    export default Home

    This covers 1. and 2. in Node context.

  • Provide stubs for fs and path in browser context. This can be done by adding a custom Webpack config in next.config.js:

    /** @type {import('next').NextConfig} */
    const nextConfig = {
      reactStrictMode: true,
      swcMinify: true,
    
      webpack(config, { isServer }) {
        if (!isServer) {
          // Resolve node modules that are irrelevant for the client
          config.resolve.fallback = {
            ...config.resolve.fallback,
    
            fs: false,
            path: false,
          }
        }
    
        return config
      },
    }
    
    module.exports = nextConfig

    This covers 1. in browser context.

  • Have Webpack copy zbar.wasm to where the chunk containing the zbar-wasm JS code resides. This requires the copy-webpack-plugin:

    yarn add -D copy-webpack-plugin
    

    Then we need to extend next.config.js like so:

    const CopyPlugin = require('copy-webpack-plugin')
    
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      reactStrictMode: true,
      swcMinify: true,
    
      webpack(config, { isServer }) {
        // Copy zbar.wasm to where the chunk containing zbar-wasm is located
        config.plugins.push(new CopyPlugin({
          patterns: [
            {
              // In this project, zbar-wasm becomes part of static/chunks/pages/_app.js
              from: 'node_modules/@undecaf/zbar-wasm/dist/zbar.wasm',
              to: 'static/chunks/pages/'
            },
          ],
        }))
    
        if (!isServer) {
          // Resolve node modules that are irrelevant for the client
          config.resolve.fallback = {
            ...config.resolve.fallback,
    
            fs: false,
            path: false,
          }
        }
    
        return config
      },
    }
    
    module.exports = nextConfig

    This covers 3.

I made a pull request to https://github.com/Loskir/zbar-wasm-nextjs that contains all these changes and fixes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants