Home > Mobile >  Exclude React from webpack-ed component library
Exclude React from webpack-ed component library

Time:11-19

I'm trying to set up my project so I can have a common library that is then used by two different wep-apps. All apps use React and I'm working on breaking out a part of the first web-app I've gotten working into it's own library, the common library.

So far,

  • I've created two npm packages, software/library and software/app1.
  • library has webpack and babel setup.
  • I've ran npm link ../library from inside software/app1.

Now I'm still getting the message:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

It seems like webpack and babel are working correctly because app1 can see ../library, but library's React must be conflicting with app1's copy.

ran in app1

npm ls react
app1@0.1.0 /software/app1
├─┬ @testing-library/react@11.2.7
│ └── react@17.0.2 deduped
├─┬ react-dom@17.0.2
│ └── react@17.0.2 deduped
├─┬ react-router-dom@5.3.0
│ ├─┬ react-router@5.2.1
│ │ ├─┬ mini-create-react-context@0.4.1
│ │ │ └── react@17.0.2 deduped
│ │ └── react@17.0.2 deduped
│ └── react@17.0.2 deduped
├─┬ react-serialize@0.2.0
│ └── react@17.0.2 deduped invalid
├── react@17.0.2 invalid
└─┬ theme@1.0.0 -> /software/theme
  ├─┬ react-dom@16.14.0
  │ └── react@16.14.0 deduped
  └── react@16.14.0

npm ERR! code ELSPROBLEMS
npm ERR! invalid: react@17.0.2 software/app1/node_modules/react

I know it can't be a React Hook problem because when library was part of app1's source, the hooks inside it worked fine.

I'll post my library/package.json and library/webpack.config.js.

package.json

{
    "babel": {
    "presets": [
        "@babel/env",
        "@babel/react"
    ]
    },
    "type": "module",
    "name": "library",
    "version": "1.0.0",
    "description": "common library",
    "author": "John Smith",
    "main": "./dist/index.js",
    "module": "./dist/index.modern.js",
    "source": "./src/index.js",
    "engines": {
        "node": ">=10"
    },
    "peerDependencies": {
        "react": "^16.14.0",
        "react-dom": "^16.13.1",
        "react-scripts": "^3.4.1"
    },
    "devDependencies": {
        "@babel/cli": "^7.16.0",
        "@babel/core": "^7.16.0",
        "@babel/preset-env": "^7.16.4",
        "@babel/preset-react": "^7.16.0",
        "babel-eslint": "^10.0.3",
        "babel-loader": "^8.1.0",
        "babel-plugin-transform-react-jsx": "^6.24.1",
        "cross-env": "^7.0.2",
        "css-loader": "^3.4.2",
        "eslint": "^6.8.0",
        "eslint-config-prettier": "^6.7.0",
        "eslint-config-standard": "^14.1.0",
        "eslint-config-standard-react": "^9.2.0",
        "eslint-plugin-import": "^2.18.2",
        "eslint-plugin-node": "^11.0.0",
        "eslint-plugin-prettier": "^3.1.1",
        "eslint-plugin-promise": "^4.2.1",
        "eslint-plugin-react": "^7.17.0",
        "eslint-plugin-standard": "^4.0.1",
        "file-loader": "^4.3.0",
        "gh-pages": "^2.2.0",
        "html-webpack-plugin": "^4.0.0-beta.11",
        "microbundle-crl": "^0.13.10",
        "npm-run-all": "^4.1.5",
        "prettier": "^2.0.4",
        "react": "^16.14.0",
        "react-dom": "^16.13.1",
        "react-scripts": "^3.4.1",
        "style-loader": "^0.23.1",
        "url-loader": "^2.3.0",
        "webpack": "^4.42.0",
        "webpack-cli": "^4.9.1",
        "webpack-dev-server": "^3.11.0",
        "webpack-node-externals": "^3.0.0"
    },
    "files": [
        "dist"
    ]
}

webpack.config.js

import nodeExternals from 'webpack-node-externals';
import path from 'path';
import fs from 'fs';

const PACKAGE = JSON.parse(fs.readFileSync('./package.json'));
const APPNAME = PACKAGE['name'];

export default {
    // entry:'./src/index.js',
    output:{
    path:path.resolve('dist'),
    // filename:'webpack-'   APPNAME   '.js',
    filename:APPNAME   '.js',
    library:APPNAME
    },

    entry: PACKAGE['source'],
    mode: "development",
    externals:[nodeExternals()],
    module: {
    rules: [
        {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
            loader: "babel-loader"
        }
        },
        {
        test: /\.css$/,
        use: [
            "style-loader",
            {
            loader: "css-loader",
            options: {
                modules: true
            }
            }
        ]
        },
        {
        test: /\.(png|svg|jpg|gif)$/,
        use: ["file-loader"]
        }
    ]
    }
};

I've been working on this problem for the past day without any solution. So far I've tried:

  • Only having library's React be a peerDependency and devDependency.
  • Adding webpack external

It all doesn't seem to make a difference. I think at first it wasn't working because I didn't have babel setup, but now it's still including library's React and not working.

Thanks.

CodePudding user response:

You have React in both peerDependencies, and devDependencies.

Remove React from your devDependencies property in package.json, delete your node_modules directory, and run npm install.

CodePudding user response:

I ended up nuking my package.json and replaced webpack with rollup. For some reason, webpack just wasn't taking the instruction to exclude React and I could find how to disable React's inclusion. It seems strange that webpack didn't work, but I actually am using library in app1 now. This is what worked.

config.babel.js

module.exports = {
    presets:[
        "@babel/preset-env",
        "@babel/preset-react"
    ]
};

rollup.config.js

import babel from 'rollup-plugin-babel';
import postcss from 'rollup-plugin-postcss';

const config = [
    {
    input:'src/index.js',
    output:{
        file:'dist/index.esm.js',
        format:'esm',
    },
    external:['react'],
    plugins:[
         postcss({
      plugins: []
         }),
        babel({ exclude:"node_modules/**" }),
    ],
    }
];

export default config;

package.json

{
    "devDependencies": {
        "@babel/cli": "^7.16.0",
        "@babel/core": "^7.16.0",
        "@babel/preset-env": "^7.16.4",
        "@babel/preset-react": "^7.16.0",
        "postcss": "^8.3.11",
        "rollup-plugin-babel": "^4.4.0",
        "rollup-plugin-postcss": "^4.0.1"
    },
    "name": "theme",
    "module": "dist/index.esm.js",
    "files": [
        "dist"
    ],
    "version": "1.0.0",
    "scripts": {
        "build": "rollup -c"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "description": ""
}

This answer doesn't answer the question, but it is what I ended up getting to work. If someone knows what was going on with webpack and why it wasn't working they should post that as well.

  • Related