Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the proper way to publish a React component module in NPM without external dependencies inside?

I'm trying to publish in NPM a component library made with React.

I don't want that it have external dependencies, even React modules, to have smallest possible file size and because the user will add this dependencies in the app.

I'm using npm and webpack to manage the dependencies.

  • This is my package.json dependencies:

    "devDependencies": {
        "webpack": "^1.13.1",
        "webpack-dev-server": "^1.14.1",
        "webpack-merge": "^0.13.0",
        "babel-core": "^6.9.1",
        "babel-loader": "^6.2.4",
        "babel-preset-es2015": "^6.6.0",
        "babel-preset-react": "^6.5.0",
        "babel-preset-react-hmre": "^1.1.1",
        "react": "^15.0.2",
        "react-dom": "^15.0.2"
      },
     "peerDependencies": {
       "react": "^15.0.2",
       "react-dom": "^15.0.2"
     }
    
  • In my webpack.config.js file I have entry point as 'component.jsx' and output as 'lib.js' file

    // Source code entry
    entry: {
      lib: './src/components/component.jsx'
    },
    
    // Code Output 
    output: {
      path: PATHS.build,
      filename: 'lib.js'
    },
    
  • I also included the "externals" attribute with the react modules to avoid webpack including it in the 'lib.js' output.

    externals: {
      'react': 'React',
      'react-dom' : 'ReactDOM'
    }
    
  • Finally this is the simple React component that i want to publish:

    import React from 'react';
    
    export default class Component extends React.Component {
    
      constructor() {
        super();
      }
    
      render() {
        return (
          <h1>MY COMPONENT</h1>
        );
      }
    }
    

I published it to NPM and installed it in another project. When I tried to use it after import React statement, it gives me an error saying that React is not defined (bundle.js:28448 Uncaught ReferenceError: React is not defined)

  • My code to probe the component:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import Component from 'component';
    import $ from 'jquery';
    
    ReactDOM.render(
       <Component />,
       $("#app")
    );
    

Am I missing anything in the dependencies config?

Thanks

like image 509
ldoc Avatar asked Jun 06 '16 08:06

ldoc


1 Answers

Webpack externals defaults to your libraryTarget. Meaning that if you don't specify anything, it will output the external as var, and exepcts it to be a global variable.

Webpack output using global:

/* 76 */
/***/ function(module, exports) {

    module.exports = react;

/***/ },

You need to tell it to look for the dependency in the installed modules (to require it). in order to do that, change your externals to:

Required change (in webpack.config):

externals: {
  'react': 'commonjs react',
  'react-dom' : 'commonjs react-dom'
}

And then it will output it using commonjs.

Webpack output using commonjs:

/* 76 */
/***/ function(module, exports) {

    module.exports = require('react');

/***/ },

Reference to webpack docs here.

Notice that I changed your externals back to lower case, since the value should be the dependency name to look for (in that case, react and react-dom).

(By the way, if you don't want to bundle any node_module, I recommend using webpack-node-externals)

like image 53
lyosef Avatar answered Nov 03 '22 15:11

lyosef