5

My work is making a React UI Kit/Component Library to be used internally for our products. Everything is working fine while developing and displaying on Storybook.

While testing the library in a generic project out-of-the-box from create-react-app, importing and implementing the components made without React Hooks are alright, but soon as we use the ones made with Hooks - the Invalid Hook Call error shows: https://reactjs.org/warnings/invalid-hook-call-warning.html

Have tried everything listed there(and read and tried the github thread solutions linked on the page), and the component simply used useRef() and nothing else so we know no rules were broken, React and React-dom versions are up to date, and running npm ls react and npm ls react-dom in the project results in [email protected] and [email protected] and nothing else... So it doesn't seem like we have multiple React's?

Any help would be much appreciated!!

This is the UI Kit's package.json

{
    "name": "react-ui-kit",
    "version": "0.0.15",
    "description": "UI Kit",
    "main": "dist/index",
    "module": "dist/index",
    "typings": "dist/index",
    "jest": {
        "setupFilesAfterEnv": [
            "<rootDir>/setupTests.js"
        ],
        "coverageReporters": [
            "json-summary",
            "text",
            "lcov"
        ]
    },
    "scripts": {
        "test": "jest --coverage",
        "test:badges": "npm run test && jest-coverage-badges input './coverage/coverage-summary.json' output './badges'",
        "test-update": "jest --updateSnapshot",
        "lint:css": "stylelint './src/**/*.js'",
        "storybook": "start-storybook -p 6006",
        "build-storybook": "build-storybook -c .storybook -o .out",
        "generate": "plop --plopfile ./.plop/plop.config.js",
        "build": "webpack --mode production",
        "prepare": "npm run build",
        "prepublishOnly": "npm run test:badges",
        "storybook-docs": "build-storybook --docs",
        "todo": "leasot './src/**/*.js'",
        "todo-ci": "leasot -x --reporter markdown './src/**/*.js' > TODO.md"
    },
    "license": "ISC",
    "peerDependencies": {
        "prop-types": "^15.7.2",
        "react": "^16.9.0",
        "react-dom": "^16.9.0",
        "recharts": "^1.7.1",
        "styled-components": "^4.3.2",
        "styled-normalize": "^8.0.6"
    },
    "devDependencies": {
        "@babel/cli": "^7.6.0",
        "@babel/core": "^7.6.0",
        "@babel/plugin-proposal-class-properties": "^7.5.5",
        "@babel/preset-env": "^7.6.0",
        "@babel/preset-react": "^7.0.0",
        "@storybook/addon-actions": "^5.2.1",
        "@storybook/addon-docs": "^5.2.1",
        "@storybook/addon-info": "^5.2.1",
        "@storybook/addon-knobs": "^5.2.1",
        "@storybook/addon-links": "^5.2.1",
        "@storybook/addon-viewport": "^5.2.1",
        "@storybook/addons": "^5.2.1",
        "@storybook/react": "^5.2.1",
        "babel-eslint": "^10.0.3",
        "babel-jest": "^24.9.0",
        "babel-loader": "^8.0.6",
        "babel-plugin-styled-components": "^1.10.6",
        "eslint": "^6.5.1",
        "eslint-plugin-react": "^7.15.0",
        "eslint-plugin-react-hooks": "^2.1.1",
        "jest": "^24.9.0",
        "jest-coverage-badges": "^1.1.2",
        "jest-styled-components": "^6.3.3",
        "leasot": "^8.2.0",
        "plop": "^2.4.0",
        "polished": "^3.4.1",
        "prop-types": "^15.7.2",
        "react": "^16.9.0",
        "react-dom": "^16.9.0",
        "react-test-renderer": "^16.9.0",
        "recharts": "^1.7.1",
        "storybook-styled-components": "github:merishas/storybook-styled-components",
        "styled-components": "^4.4.0",
        "styled-normalize": "^8.0.6",
        "stylelint": "^10.1.0",
        "stylelint-config-recommended": "^2.2.0",
        "stylelint-config-styled-components": "^0.1.1",
        "stylelint-processor-styled-components": "^1.8.0",
        "webpack": "^4.40.2",
        "webpack-cli": "^3.3.9"
    },
    "files": [
        "dist"
    ],
}

The UI Kit's webpack.config.js

const path = require('path');

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve('dist'),
        filename: 'index.js',
        libraryTarget: 'commonjs2',
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: 'babel-loader',
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            limit: 10000,
                            mimetype: 'application/font-woff',
                        },
                    },
                ],
            },
        ],
    },
    resolve: {
        alias: {
            components: path.resolve(__dirname, 'src/components/'),
            utils: path.resolve(__dirname, 'src/utils/'),
            themes: path.resolve(__dirname, 'src/themes/'),
        },
        extensions: ['.js', '.jsx'],
    },
    devtool: false,
};

How components are imported and implemented in project:

import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { FieldLabel, Button } from "react-ui-kit";

function App() {
  return (
    <div className="App">
      <FieldLabel>THIS IS THE ONE USING the useRef Hook</FieldLabel>
      <Button>This component is totally fine without FieldLabel, this isn't using Hooks</Button>
    </div>
  );
}

export default App;
4
  • Are you using npm link ? Your project runs on [email protected] and the lib runs on 16.9.0. If you are using npm link, this will lead to the error because the bundler will see both react versions. Commented Oct 19, 2019 at 3:59
  • No, we're not using npm link, our library is published on npm privately, so we install the library from there. Commented Oct 21, 2019 at 15:10
  • A quick solution would be to use react version 16.9.0 in your project. Because your UI kit has a peer dependency on React 16.9.0 Commented Oct 21, 2019 at 15:15
  • Also you could republish your UI kit package,as the react version is specified as ^16.9.0 which could potentially update UI Kit react version to 16.10.2. Commented Oct 21, 2019 at 15:32

1 Answer 1

3

Looking at the webpack config, I could see that, UI kit is getting bundled with react included which might be causing the issue.

To avoid this you could use webpack externals.

https://webpack.js.org/configuration/externals/

The externals configuration option provides a way of excluding dependencies from the output bundles. Instead, the created bundle relies on that dependency to be present in the consumer's environment. This feature is typically most useful to library developers, however there are a variety of applications for it.

So you could update UI Kit webpack config to not include react and the peerDependencies should take care of the dependency handling for any consumers of the library.

Updated webpack.config

const path = require("path");
module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: {
    path: path.resolve("dist"),
    filename: "index.js",
    libraryTarget: "commonjs2"
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules)/,
        use: "babel-loader"
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              limit: 10000,
              mimetype: "application/font-woff"
            }
          }
        ]
      }
    ]
  },
  resolve: {
    alias: {
      components: path.resolve(__dirname, "src/components/"),
      utils: path.resolve(__dirname, "src/utils/"),
      themes: path.resolve(__dirname, "src/themes/")
    },
    extensions: [".js", ".jsx"]
  },
  externals: {
        // Use external version of React
        react: "react"
 },
  devtool: false
};

I have published a test package to confirm this (react-ui-kit-dontuse).

Demo links

v0.0.21(Without webpack externals) 

https://stackblitz.com/edit/react-xyjgep

v0.0.23(With webpack externals) 

https://stackblitz.com/edit/react-ihnmrl

Source code of test package: https://github.com/nithinthampi/react-ui-lib-test

Hope this helps!

Sign up to request clarification or add additional context in comments.

1 Comment

You are welcome!!! Please mark as right answer/ upvote if this was helpful :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.