Use webpack to publish reactjs npm package
React is a very easy and light-weight way to build componentized website. Sometimes we need to share the components among projects, build component and publish it to npm repository is the most convinient way to share and maintain.
The next will cover:
- Set up private npm server
- Write a ‘HelloMessage’ React Component
- Publish npm package & configuration
Local npm server
If you want to keep the components private, one way is to use the private function in npm, the other is to set a local(or private) npm server.
It’s very easy to set up a private npm server with sinopia.
Copy the Installation scripts here from it’s page:
#installation and starting (application will create default
# config in config.yaml you can edit later)
$ npm install -g sinopia
$ sinopia
# npm configuration
$ npm set registry http://localhost:4873/
Then, access http://localhost:4873/ to see the local npm server.
Write A HelloMessage Component.
We want to keep the component as simple as possible.
# create root folder
mkdir component
# create folder for component 'HelloMessage'
cd component
npm init
pm install react react-dom jsx-loader --save
mkdir hello
touch hello.jsx
# init package
npm init
# install react
npm install react jsx-loader --save
Implement the HelloMessage Component:
'use strict'
var React = require('react');
module.exports = React.createClass({
displayName: 'HelloMessage',
render: function(){
return <div className="hello">
(Hello React.
{this.props.children}
)
</div>
}
})
Then, goto the root folder to add index.html, loader.jsx, and webpack.config.js.
This is the loader.jsx:
var HelloMessage = require('./hello/hello.jsx');
ReactDOM.render(
<HelloMessage >
<div>this is from loader</div>
</HelloMessage>,
document.getElementById('content')
);
This is the index.html:
<html>
<head>
<title>Component Container</title>
<script src="./node_modules/react/dist/react.js"></script>
<script src="./node_modules/react-dom/dist/react-dom.js"></script>
</head>
<body>
<div id="content">
This is the container.
</div>
<script src="./dist/loader.js"></script>
</body>
</html>
Next, we need to add webpack to build bundle file and put it in dist folder.
Here is the webpack.config.js:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'dist');
var APP_DIR = path.resolve(__dirname, '.');
var config = {
devtool:'source-map',
entry: APP_DIR + '/loader.jsx',
output: {
path: BUILD_DIR,
filename: 'loader.js'
},
module : {
loaders: [
{ test: /\.jsx$/, loader: "jsx-loader" },
],
}
};
module.exports = config;
Make sure webpack
, jsx-loader
, react
and react-dom
installed.
Run webpack
under root folder to build bundle file.
Start a local server to check the result:
python -m SimpleHTTPServer
(or run python -m http.server
if you are using python3)
Then, visit http://localhost:8000
Publish to local npm server
Actually, if we run npm publish
under hello folder, we will be able to see it in npm repo.
This is just pack all the files under hello folder into the npm package.
There are several things we need to consider:
The entry
It’s the main
config in pacakge.json file, the value was set when running npm init
, in our example, it should be set to hello.jsx
Sometimes, it’s not a good choice to expose a ‘jsx’ entry file, as you don’t really want to look into the npm packages folder to decide what loaders do you need to use to import this module.
We can use babel
to compile the jsx files into ES5.
Goto the hello
folder to install babel-cli:
npm install --save-dev babel-cli babel-preset-es2015 babel-preset-react
Then, add the following to package.json file:
"main": "index.js",
"scripts": {
...
"build": "babel hello.jsx -o hello.js"
},
"babel": {
"presets": [
"es2015",
"react"
]
}
Run npm run build
to compile it.
An alternative way to build the component
In some project, react is just used to build some part of one page. In order to simplify the use of component, we can build it as a library(like jquery) to expose a global variable.
Add this webpack.config.js into hello folder:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'dist');
var APP_DIR = path.resolve(__dirname, '.');
var config = {
devtool:'source-map',
entry: APP_DIR + '/hello.jsx',
output: {
path: BUILD_DIR,
filename: 'hello.lib.js',
library:'HelloMessage',
libraryTarget:'var'
},
module : {
loaders: [
{ test: /\.jsx$/, loader: "jsx-loader" },
],
}
};
module.exports = config;
After run webpack
, we got a hello.lib.js
file in dist folder.
Change the index.html file, replace
<script src="./dist/loader.js"></script>
with
<script src="./hello/dist/hello.lib.js"></script>
<script>
ReactDOM.render(React.createElement(HelloMessage),
document.getElementById('content'));
</script>
In this way, we got rid of the loader.jsx
file.
The sample code can be found here:
https://github.com/qszhuan/npm-webpack-react-component-sample/tree/basic
blog comments powered by Disqus