最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use React components from local npm package - Stack Overflow

programmeradmin1浏览0评论

I'm trying to create an npm package with some React ponents that I use for virtually all of my projects. Here's the folder structure and file contents:

  • /
    • dist/
      • bundle.js
    • src/
      • MyComponent.jsx
      • index.js
    • package.json
    • webpack.config.js

MyComponent.jsx

import React, { Component } from 'react';

class MyComponent extends Component {
    render() {
        return (
            <p>Hello, world!</p>
        );
    }
}

export default MyComponent;

index.js

// eventually there will be more ponents imported/exported here
import MyComponent from './MyComponent.jsx';
exports.MyComponent = MyComponent;

webpack.config.js

module.exports = {
    entry: './src/index.js',
    output: {
        path: './dist',
        filename: 'bundle.js'
    },
    // some loaders...
};

package.json

{
    "name": "my-library",
    "files": [
        "dist",
        "src"
    ],
    "main": "dist/bundle.js",
    // the usual stuff...
}

This is my understanding of the process. First, I build the src files with webpack. This looks at /src/index.js, imports the MyComponent class, then exports it, making it available as MyComponent. This is all added to a bundle.js file in /dist.

Next, I pack the module with npm pack. This creates an archive file with the /src and /dist directories in it.

Then I go over to my other project and run npm install ../path/to/archive/file. This adds the module to my node_modules directory. The problem is that when I try to import and use MyComponent...

import React, { Component } from 'react';
import MyComponent from 'my-library';

class App extends Component {
    render() {
        console.log(<MyComponent />);
        return (
            <MyComponent />
        );
    }
}

export default App;

...and render that ponent, I get this warning and error:

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for posite ponents). Check the render method of `App`.

Uncaught Error: Element type is invalid: expected a string (for built-in ponents) or a class/function (for posite ponents) but got: object. Check the render method of `App`.

The output of the console.log is a React object, but the type is Object, which seems like what the warning is alluding to (it should be a string instead, I guess).

Any idea what I'm missing?


EDIT:

Well, I'm closer. I added library options to my webpack config:

output: {
    library: 'my-library',
    libraryTarget: 'umd'
}

...and then I was able to use the ponent like this:

import MyLibrary from 'my-library';
const MyComponent = MyLibrary.MyComponent;

But I don't want to have to do that for every ponent. My goal is this:

import { MyComponent, MyOtherComponent } from 'my-library';

I'm trying to create an npm package with some React ponents that I use for virtually all of my projects. Here's the folder structure and file contents:

  • /
    • dist/
      • bundle.js
    • src/
      • MyComponent.jsx
      • index.js
    • package.json
    • webpack.config.js

MyComponent.jsx

import React, { Component } from 'react';

class MyComponent extends Component {
    render() {
        return (
            <p>Hello, world!</p>
        );
    }
}

export default MyComponent;

index.js

// eventually there will be more ponents imported/exported here
import MyComponent from './MyComponent.jsx';
exports.MyComponent = MyComponent;

webpack.config.js

module.exports = {
    entry: './src/index.js',
    output: {
        path: './dist',
        filename: 'bundle.js'
    },
    // some loaders...
};

package.json

{
    "name": "my-library",
    "files": [
        "dist",
        "src"
    ],
    "main": "dist/bundle.js",
    // the usual stuff...
}

This is my understanding of the process. First, I build the src files with webpack. This looks at /src/index.js, imports the MyComponent class, then exports it, making it available as MyComponent. This is all added to a bundle.js file in /dist.

Next, I pack the module with npm pack. This creates an archive file with the /src and /dist directories in it.

Then I go over to my other project and run npm install ../path/to/archive/file. This adds the module to my node_modules directory. The problem is that when I try to import and use MyComponent...

import React, { Component } from 'react';
import MyComponent from 'my-library';

class App extends Component {
    render() {
        console.log(<MyComponent />);
        return (
            <MyComponent />
        );
    }
}

export default App;

...and render that ponent, I get this warning and error:

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for posite ponents). Check the render method of `App`.

Uncaught Error: Element type is invalid: expected a string (for built-in ponents) or a class/function (for posite ponents) but got: object. Check the render method of `App`.

The output of the console.log is a React object, but the type is Object, which seems like what the warning is alluding to (it should be a string instead, I guess).

Any idea what I'm missing?


EDIT:

Well, I'm closer. I added library options to my webpack config:

output: {
    library: 'my-library',
    libraryTarget: 'umd'
}

...and then I was able to use the ponent like this:

import MyLibrary from 'my-library';
const MyComponent = MyLibrary.MyComponent;

But I don't want to have to do that for every ponent. My goal is this:

import { MyComponent, MyOtherComponent } from 'my-library';
Share Improve this question edited Dec 21, 2016 at 15:08 jacobsowles asked Dec 19, 2016 at 22:05 jacobsowlesjacobsowles 3,0037 gold badges37 silver badges56 bronze badges 2
  • Are you tried with: import { MyComponent } from 'my-ponent'; ? – saeta Commented Dec 20, 2016 at 1:12
  • I tried import { MyComponent } from 'my-ponent'; and const MyComponent = require('my-ponent').MyComponent; and got the same warning/error in both cases. – jacobsowles Commented Dec 20, 2016 at 15:27
Add a ment  | 

2 Answers 2

Reset to default 0

You have to export your ponent from the ponent index.js file like shown below

import MyComponent from './MyComponent.jsx';
import MyOtherComponent from './MyOtherComponent.jsx';
export {
    MyComponent,
    MyOtherComponent
}

Then in your Main project, Import them using

import { MyComponent, MyOtherComponent } from 'my-library';

It looks like the issue is with how your package exports ponents. Your index.js uses:

exports.MyComponent = MyComponent;

This makes MyComponent a property of the default export, which is why you had to do:

import MyLibrary from 'my-library';
const MyComponent = MyLibrary.MyComponent;

The Fix Instead of using exports, try this in src/index.js:

export { default as MyComponent } from './MyComponent.jsx';

This way, when you import your package like this:

import { MyComponent } from 'my-library';

…it will work as expected.

发布评论

评论列表(0)

  1. 暂无评论