在发布为 npm 包之前使用 npm 链接测试组件时出现重复的 ReactJS 导入问题 [英] Duplicate ReactJS import issue when using npm link to test component before publishing as npm package

查看:107
本文介绍了在发布为 npm 包之前使用 npm 链接测试组件时出现重复的 ReactJS 导入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的简单组件.

I have a simple component like this.

import React, {useState} from 'react';

function MyComponentWithState(props) {
    const [value, setValue] = useState(0);

    return (
        <p>My value is: {value}</p>
    ) 
}

export default MyComponentWithState;

我想将它作为一个单独的包发布在 NPM 上.所以,为此我准备了 package.jsonwebpack.config.js,如下所示.

and I want to publish it on NPM as a separate package. so, to do that I prepared package.json and webpack.config.js like below.

package.json:

{
  "name": "try-to-publish",
  "version": "0.0.1",
  "description": "Just a test",
  "main": "build/index.js",
  "scripts": {
    "start": "webpack --watch",
    "build": "webpack"
  },
  "author": {
    "name": "Behnam Azimi"
  },
  "license": "ISC",
  "peerDependencies": {
    "react": "16.9.0",
    "react-dom": "16.9.0"
  },
  "dependencies": {
    "react": "16.9.0",
    "react-dom": "16.9.0",
    "prop-types": "15.7.2",
    "react-scripts": "3.1.1",
    "webpack": "4.39.3"
  },
  "devDependencies": {
    "@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",
    "babel-loader": "8.0.6",
    "babel-plugin-transform-object-rest-spread": "6.26.0",
    "babel-plugin-transform-react-jsx": "6.24.1",
    "css-loader": "3.2.0",
    "node-sass": "4.12.0",
    "sass-loader": "8.0.0",
    "style-loader": "1.0.0",
    "webpack-cli": "3.3.8",
    "webpack-external-react": "^1.1.2"
  }
}

webpack.config.json:

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'index.js',
        libraryTarget: 'commonjs2'
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src'),
                use: {
                    loader: "babel-loader"
                }
            },
        ]
    },
    resolve: {
        alias: {
            'react': path.resolve(__dirname, 'node_modules/react'),
            'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
        }
    },
    externals: {
        'react': "commonjs react",
        'react-dom': "commonjs react-dom"
    },
};

这是我的 .babelrc:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

当我将组件发布到 NPM 并使用 `npm install 将其安装在我的另一个 ReactJs 项目中时,这些配置就像魅力一样工作,但我的重点是本地测试!

These configs work like charm when I publish my component to NPM and install it in my another ReactJs project with `npm install , but my point is the local test!

我想在发布之前测试这个组件/库.为此,我使用 npm link 功能将我的组件与我的主要 ReactJS 项目链接起来.

I want to test this component/lib before publish. To do this I use npm link feature to link my component with my main ReactJS project.

正如你在上面看到的,我的组件是功能性的,我也使用了钩子.所以当我将本地链接的 lib 注入到我的主要 ReactJs 项目时,会遇到这个错误,

As you saw above, my component is functional and I used hooks too. So when I inject the locally linked lib to my main ReactJs project face this error,

无效的钩子调用.钩子只能在函数组件的主体内部调用.这可能是由于以下原因之一造成的:1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)2. 你可能违反了 Hooks 规则3. 你可能在同一个应用中拥有多个 React 副本

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 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

我的问题与 3td 原因有关.我的项目使用 ReactJs 并导入一次,我的组件也将导入 React!我的意思是在一个项目中两次导入 React!.

My issue is related to the 3td reason. My project uses ReactJs and import it once and also my component will import React! I mean twice React import in one project!.

我的 Webpack 配置中还有关于 reactreact-domexternals 配置.

I also have externals config about react and react-dom in my Webpack config.

我该怎么做才能解决这个问题?我的错误在哪里?

What should I do to solve that? Where is my mistake?

更新:我也试过@sung-m-kim 和@eddie-cooro 所说的,但没有奏效!意思是,我更改了 package.json 并从 dependencies 中删除了 reactreact-dom 并将它们添加到 devDpendencies.

Update: I also tried what @sung-m-kim and @eddie-cooro say but it not worked! Mean, I change the package.json and removed react and react-dom from dependencies and add them to devDpendencies.

推荐答案

我解决了我的问题.我使用 RollupJS 而不是 Webpack 作为捆绑工具进行捆绑.

I solved my issue. I used RollupJS instead of Webpack for bundling as bundle tool.

这是我的rollup.config.js:

import {uglify} from 'rollup-plugin-uglify'
import babel from 'rollup-plugin-babel'

export default {
    input: "./src/index.js",
    external: ['react', 'react-dom'],
    output: {
        name: 'test-lib',
        format: "cjs",
    },
    plugins: [
        babel({
            exclude: "node_modules/**"
        }),
        uglify(),
    ],
};

和我的package.json:

{
  "name": "test-lib",
  "version": "1.0.0",
  "main": "dist/test-lib.min.js",
  "scripts": {
    "build": "rollup -c -o dist/test-lib.min.js"
  },
  "author": "Behnam Azimi",
  "license": "ISC",
  "peerDependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0"
  },
  "devDependencies": {
    "@babel/core": "^7.6.0",
    "@babel/preset-env": "^7.6.0",
    "@babel/preset-react": "^7.0.0",
    "rollup": "^1.21.4",
    "rollup-plugin-babel": "^4.3.3",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-uglify": "^6.0.3"
  }
}

经过这些更改后,npm link 在我的 ReactJS (Hooks) 项目中真正发​​挥了作用.

After these changes, npm link worked truly in my ReactJS (Hooks) project.

请注意,这只是一个简单的 Rollup 配置来展示我的解决方案,您可以向配置中添加多种内容,例如热重载、样式加载器和许多其他插件.

Notice that it's just a simple Rollup config to show my solution and you can add many kinds of stuff like hot reloading, styles loaders, and many other plugins to the config.

这篇关于在发布为 npm 包之前使用 npm 链接测试组件时出现重复的 ReactJS 导入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆