この記事なに?
最近Reactを使って動くものが作れるようになった!という人向けに、もう一歩踏み込んで作ったコンポーネントをnpmで公開するための方法を共有したいと思います。
対象ユーザー
- 最近Reactを使って動くものが作れるようになった!という人
- gulpはなんとなくだけど使える
- npmでパッケージを公開したことがない人
- 作ったコンポーネントを見せつけてドヤリングしたい人
(参考資料)npmについての基本的な知識や、パッケージの公開方法
フロントエンド開発の3ステップ(npmことはじめ)
http://qiita.com/hashrock/items/15f4a4961183cfbb2658
3分でできるnpmモジュール
http://qiita.com/fnobi/items/f6b1574fb9f4518ed520
3時間でできるnpmモジュール
http://qiita.com/cognitom/items/75736e27cc7de151a7d5
やったこと
まずはじめに、上記の参考文献で書いてあるようにnpmのユーザー登録を行っておいてください。
これがないとnpmに登録することができません。登録ができたらコマンドラインでnpm adduser
するのも忘れないでください。
続いてsrcに配置したjsxをjsにコンパイルし、gulpを使ってビルドします。
それぞれのソースファイルはこちら。
まずはこのgulpfileでjsxをjsにコンパイルします。
コンパイルするjsxも載せておきますが本当にただのjsxです。
$ gulp
'use strict';
var gulp = require('gulp'),
react = require('gulp-react'),
concat = require('gulp-concat'),
sass = require('gulp-sass'),
plumber = require('gulp-plumber');
gulp.task('compile:scss', function() {
gulp.src('./css/*.scss')
.pipe(plumber())
.pipe(sass())
.pipe(concat('index-filter.css'))
.pipe(gulp.dest('./css'))
});
gulp.task('default', function () {
return gulp.src('./src/index-filter.jsx')
.pipe(react({
harmony: true
}))
.pipe(concat('index.js'))
.pipe(gulp.dest('./lib'));
});
'use strict';
var React = require('react'),
FontAwesome = require('react-fontawesome');
var FilterItem = React.createClass({
getInitialState: function() {
return {
isMouseOver: false
}
},
toggleChecked: function() {
this.props.toggleChecked(this.props);
},
setIconVisibility: function() {
if (this.props.hasChecked === true) {
return ''
} else {
return 'index-filter_invisible'
}
},
setTextColor: function() {
if (this.props.hasChecked === true) {
return 'index-filter_checked'
} else {
return ''
}
},
toggleIconStyle: function() {
this.setState({ isMouseOver: !this.state.isMouseOver})
},
getIconStyle: function() {
if (this.state.isMouseOver === true) {
return 'times-circle';
} else {
return 'check';
}
},
render: function() {
return(
<li className={"index-filter__item-wrapper " + this.setTextColor()}>
<div className="index-filter__item ui-checkbox" onClick={this.toggleChecked} onMouseOver={this.toggleIconStyle} onMouseOut={this.toggleIconStyle} >
<div className="index-filter__image-wrapper"><img className="index-filter__image" src={this.props.iconUrl} /></div>
<div className="index-filter__label">{this.props.id}</div>
<FontAwesome className={"index-filter__check-icon " + this.setIconVisibility() } name={this.getIconStyle()} size='lg' />
</div>
</li>
)
}
});
var IndexFilter = React.createClass({
getInitialState: function() {
return {
options: this.props.options,
isRevealed: true
}
},
toggleFilterOption: function(){
this.setState({
isRevealed: !this.state.isRevealed
});
},
toggleChecked: function(selectedOption) {
var options = this.state.options
.filter(function(option) {
return option.id === selectedOption.id;
})
.map(function(option){
return option.hasChecked = !option.hasChecked;
})
this.setState({ options: this.state.options });
},
render: function() {
var rows = [];
this.state.options.forEach(function(option) {
rows.push(
<FilterItem key={option.id} id={option.id} iconUrl={option.iconUrl} hasChecked={option.hasChecked} toggleChecked={this.toggleChecked} />
)
}.bind(this));
return(
<div className="index-filter">
<h5 className="index-filter__header" onClick={this.toggleFilterOption} >{this.props.title}<FontAwesome name="chevron-down" rotate={ this.state.isRevealed ? "180" : null } size='lg' /></h5>
<ul className={"index-filter__item-list " + (this.state.isRevealed ? 'index-filter_revealed' : '')}>
{rows}
</ul>
</div>
);
}
})
module.exports = IndexFilter;
そのあとはpackage.jsonを修正します。
重要なのはmain と keywordsです。
mainには先ほどコンパイルして配置したlib/index.jsを指定しないと動きません。
keywordsにはreact-componentと入れておくと、
react-components.comというサイトからの検索に引っかかるので、こちらも記入するようにしてください。
(参考)React Components
http://react-components.com/
ちなみに自分のpackage.jsonはこんなかんじです。
{
"name": "react-index-filter",
"version": "0.1.0",
"description": "",
"keywords": "react-component",
"main": "lib/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "takayuki-ochiai",
"license": "ISC",
"dependencies": {
"font-awesome": "^4.4.0",
"react": "^0.13.3",
"react-fontawesome": "^0.2.5"
},
"devDependencies": {
"babelify": "^6.2.0",
"browser-sync": "^2.8.2",
"browserify": "^11.0.1",
"gulp": "^3.9.0",
"gulp-concat": "^2.6.0",
"gulp-plumber": "^1.0.1",
"gulp-react": "^3.0.1",
"gulp-sass": "^2.0.4",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.3.1"
}
}
package.jsonを記入したらあとはコマンド一発です。
$ npm publish
おめでとうございます!これでコンポーネントの公開は終了です!
あとはできればgithubにソースコードをプッシュしたりREADMEを充実させたりしてみてください!
最後に
自分も先日初めてnpmにパッケージを公開したばかりなので、この記事の内容はBestの内容ではないと思います。
もし明らかな間違いがあったり、よりよい方法がある、という場合はご指摘いただけるとありがたいです。