jacobsowles
jacobsowles

Reputation: 3003

How to use React components from local npm package

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

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 components 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 component, 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 composite components). Check the render method of `App`.

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) 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 component like this:

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

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

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

Upvotes: 7

Views: 10991

Answers (1)

ankur kushwaha
ankur kushwaha

Reputation: 478

You have to export your component from the component 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';

Upvotes: 0

Related Questions