reactjsnpmwebpacknext.jsexternal-dependencies

Including React as a webpack external results in cannot find module 'react'


I am creating an NPM package with commonly used components in multiple projects. I don't want to bundle my own react/react-dom in this package so I'm doing the following in my webpack.config.js:

  externals: {
    react: {
      commonjs: 'react',
      commonjs2: 'react'
    },
    'react-dom': {
      commonjs: 'react-dom',
      commonjs2: 'react-dom'
    }
}

I've also specified the above two dependencies as peerDependencies in my package.json

What I want to happen is for this package to share the react dependency that my parent project (also processed by Webpack) has.

When I build my parent project with my package as a dependency however, I get this error:

Error: Cannot find module 'react'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/package/dist/main.js:1:898)
    at n (/package/dist/main.js:1:62)
    at Module.<anonymous> (/package/dist/main.js:22:45607)
    at n (/package/dist/main.js:1:62)
    at /package/dist/main.js:1:861
    at Object.<anonymous> (/package/dist/main.js:1:872)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Module._compile (/parent-project/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Object.newLoader [as .js] (/parent-project/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12) code: 'MODULE_NOT_FOUND' }

I was wondering if anyone has any idea where I'm going wrong here? The parent project is a NextJS app if that helps...

EDIT: I have tried to include the package in a standard create-react-app project and this works. So now I'm thinking it's something to do with the server side rendering step of NextJS?


Solution

  • Here is what worked for me:

    In my webpack output config I had the following:

      output: {
        filename: '[name].js',
        path: __dirname + '/dist',
        libraryTarget: 'commonjs'
      },
    

    I needed my libraryTarget to be umd to make the package work on both the client and the server. Before my package worked on the client but not on the server.