1

I created a small proof of concept React component and pushed it here -> https://github.com/lropero/poc

I'd like to be able to import this component within a different React project by doing: npm install git+https://github.com/lropero/poc.git and then import Poc from 'poc' and be able to render the component (i.e. <Poc />). The thing is I'm getting React's invariant violation error #321 because I'm using hooks (useEffect in this example). I tried commenting this hook out and I'm able to see the <p>TEST</p> element rendered fine. I'm guessing it's a Webpack issue when building Poc's bundle?

Relevant files shown below (everything at https://github.com/lropero/poc):

./src/index.jsx:

import React, { useEffect } from 'react'
import ReactDOM from 'react-dom'

const App = () => {
  useEffect(() => {
    console.log('SUCCESS')
  }, [])
  return <p>TEST</p>
}

if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
  ReactDOM.render(<App />, document.getElementById('app'))
}

export default App

./package.json:

{
  "name": "poc",
  "version": "0.1.0",
  "description": "Proof of concept importing React bundle.",
  "module": "./dist/bundle.js",
  "scripts": {
    "build": "rm -rf dist && npx webpack --config webpack.prod.js",
    "clean": "rm -f npm-*.log && rm -f package-lock.json && rm -rf node_modules && npm cache verify",
    "nuke": "npm run clean && npm install",
    "start": "npx webpack-dev-server --config webpack.dev.js"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/plugin-transform-runtime": "^7.11.5",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "babel-loader": "^8.1.0",
    "html-webpack-plugin": "^4.4.1",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "source-map-loader": "^1.1.0",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^5.1.4"
  },
  "peerDependencies": {
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  },
  "license": "UNLICENSED",
  "private": true
}

./webpack.config.js (webpack.common.js and webpack.prod.js merged together):

{
  entry: './src/index.jsx',
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: path.resolve(__dirname, 'node_modules'),
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/preset-react']
            }
          }
        ]
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    library: 'Poc',
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    alias: {
      [name]: path.resolve(__dirname, 'src')
    },
    extensions: ['.js', '.jsx']
  }
}

2 Answers 2

3

It looks like you forgot to exclude React + ReactDOM out of your bundle file as you build with production mode.

As you publish your code as React component, apart from set React as peer dependency you have to set the react as externals to use the react at the consumer library.

Add more external property in your webpack.prod.js:

externals: {
  'react': {
    commonjs: 'react',
    commonjs2: 'react',
    amd: 'React',
    root: 'React'
  },
  'react-dom': {
    commonjs: 'react-dom',
    commonjs2: 'react-dom',
    amd: 'ReactDOM',
    root: 'ReactDOM'
  }    
},
Sign up to request clarification or add additional context in comments.

Comments

0

The configuration from tmhao will make your module build not work on Linux, it wont be able to find react because of case sensitive issues. Just a heads up, amd should be 'react'

externals: {
  'react': {
    commonjs: 'react',
    commonjs2: 'react',
    amd: 'react',
    root: 'React'
  },
  'react-dom': {
    commonjs: 'react-dom',
    commonjs2: 'react-dom',
    amd: 'react-dom',
    root: 'ReactDOM'
  }    
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.