importing custom npm package results in empty/null object

All we need is an easy explanation of the problem, so here it is.

I am able to import MyComponent in the same package and have it render on the page, but I am unable to link or download the MyComponent package and import the component.

package.json:

{
  "name": "my-component",
  "version": "1.0.0",
  "main": "dist/index.js",
  "directories": {},
  "dependencies": {},
  "devDependencies": {
    "babel-loader": "^6.2.3",
    "babel-preset-es2015": "",
    "babel-preset-react": "",
    "css": "^2.2.1",
    "css-loader": "^0.23.1",
    "file-loader": "^0.8.5",
    "node-sass": "^3.4.2",
    "react": "^0.14.7",
    "react-dom": "^0.14.7",
    "sass": "^0.5.0",
    "sass-loader": "^3.1.2",
    "style": "0.0.3",
    "style-loader": "^0.13.0",
    "webpack": "^1.12.13",
    "webpack-dev-server": "^1.14.1"
  }
}

webpack.config.js:

var path = require('path');

module.exports = {
  entry: './src/MyComponent.jsx',
  output: {
    path: './dist/',
    filename: './index.js'
  },
  module: {
    loaders: [{
      test: /\.jsx$/,
      include: path.resolve(__dirname),
      exclude: /node_modules/,
      loader: 'babel-loader',
      query: {
        presets: ['react', 'es2015']
      }
    },
    {
      test: /\.scss$/,
      include: /.scss$/,
      loader: 'style!css!sass'
    },
    {
      test: /\.html$/,
      loader: "file?name=[name].[ext]",
    },]
  }
};

./src/MyComponent.jsx

import React from 'react';

export default class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>Hello World.</div>
    );
  }
}

MyComponent.propTypes = {
  class: React.PropTypes.string
}
MyComponent.defaultProps = {
  class: ''
}

console.log(MyComponent)

Using webpack dev server, I’m able to import this component in another file and render it to the page.

When I link and/or install the results of the webpack build in another project, I expect to be able to be able to do the same, like this:

new-app.jsx:

import React from 'react'
import ReactDOM from 'react-dom'
import MyComponent from 'my-component'
console.log(MyComponent)
ReactDOM.render(MyComponent, document.body)

When I import the module from ‘my-component’ the console.log statement that exists in MyComponent.jsx logs the “function MyComponent(props) {…” as expected, but the console.log statement in the new application logs an empty object.

console output when rendering new-app.jsx: I believe the first log is the log coming from MyComponent.jsx and the second log is coming from my new application.

index.js:19783 MyComponent(props) {
            _classCallCheck(this, MyComponent);

            return _possibleConstructorReturn(this, Object.getPrototypeOf(MyComponent).call(this, props));
          }
index.js:58 Object {}

Am I missing anything in my configs? Am I exporting/importing in an incorrect way?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

The solution was to add this to the output in webpack.config.js

library: 'MyComponent',
libraryTarget: 'umd'

Method 2

I had a similar problem

import {MySingleton} from "../../../dist/my-bundle-webpack-package";

MySingleton.instance.foo();

Error:

Cannot read property 'instance' of undefined

The index.ts of my package file was:

export class MySingleton{
   ...
}
module.exports = MySingleton;

The solution to the problem was removing module.exports:

export class MySingleton{
   ...
}

Method 3

Adding libraryTarget: 'umd' didn’t help here.

I had the exact some problem while trying to use npm package as a lib via npm link. The culprit in my case was the duplicated dependencies on both projects – Project and Lib were importing the same modules. Webpack fails silently here.

Managed to fix it by adding "externals" to my webpack configration in the Lib to tell those packages will exist in the project

externals: {
    "pixi.js": "pixi.js",
    immer: "immer",
    redux: "redux",
    lodash: "lodash",
    gsap: "gsap",
  },

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply