📖
Reactコンポーネントのnpmライブラリを作成してみた
Reactコンポーネントのnpmライブラリを作成する
storybookを使用してreactコンポーネントの開発をするための環境を整備しました。
作成したコンポーネントはnpmパッケージとして保存して、他プロジェクトで使用できるようにします。
ライブラリ作成なので、webpackではなく、rollupを使用しています
最終的な構成
react-component $ tree -a -I "node_modules|.git"
.
├── .babelrc
├── .gitignore
├── .npmignore
├── .storybook
│ ├── main.js
│ └── preview.js
├── dist
│ └── index.cjs.js
├── package-lock.json
├── package.json
├── rollup.config.js
└── src
├── index.js
└── stories
├── Button.jsx
├── Button.stories.jsx
├── Header.jsx
├── Header.stories.jsx
├── Introduction.stories.mdx
├── Page.jsx
├── Page.stories.jsx
├── assets
│ ├── code-brackets.svg
│ ├── colors.svg
│ ├── comments.svg
│ ├── direction.svg
│ ├── flow.svg
│ ├── plugin.svg
│ ├── repo.svg
│ └── stackalt.svg
├── button.css
├── header.css
└── page.css
5 directories, 28 files
mkdir
mkdir react-component
cd react-component
npm init -y
mkdir src
git init
git init
touch .gitignore
.gitignore
node_modules
rollup install
npm install rollup --save-dev
babel install
npm install @babel/cli @babel/core @babel/preset-env @babel/preset-react @rollup/plugin-babel --save-dev
runtime install
npm install @babel/runtime
npm install @babel/plugin-transform-runtime --save-dev
rollup plugin install
npm install rollup-plugin-styles autoprefixer --save-dev
npm install --save-dev rollup-plugin-delete
sourcemap install
npm install rollup-plugin-sourcemaps --save-dev
.babelrc
.babelrc
{
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}
rollup.config.js
rollup.config.js
import styles from "rollup-plugin-styles";
import babel from '@rollup/plugin-babel';
import sourcemaps from 'rollup-plugin-sourcemaps';
import del from 'rollup-plugin-delete';
const autoprefixer = require('autoprefixer');
const conf = {
input: 'src/index.js',
output: {
file: `dist/index.cjs.js`,
format: "cjs",
exports: "auto"
},
// this externelizes react to prevent rollup from compiling it
external: ["react", /@babel\/runtime/],
plugins: [
// these are babel comfigurations
babel({
exclude: 'node_modules/**',
plugins: ['@babel/transform-runtime'],
babelHelpers: 'runtime'
}),
// this adds sourcemaps
sourcemaps(),
del({targets:'dist/*'}),
// this adds support for styles
styles({
postcss: {
plugins: [
autoprefixer()
]
}
})
]
}
export default conf;
storybook install
npx -p @storybook/cli sb init --type react
package.json 編集
package.json
"main": "dist/index.cjs.js",
"scripts": {
"build": "rollup -c",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
index.js作成
import { Header } from './stories/Header.jsx'
const returnLibrary = () => {
return {
Header: Header
// you can add here other components that you want to export
}
}
export default returnLibrary()
build
npm run build
Error対応
[!] Error: Could not resolve './Button' from src/stories/Header.jsx
Button.jsxの拡張子つけると治る
Header.jsx
import { Button } from './Button.jsx';
つけなくていいはずなのに...原因不明??
警告 対策
react-component $ npm run build
> @marumarumeruru/react-component@1.0.10 build
> rollup -c
src/index.js → dist/index.cjs.js...
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
prop-types (imported by src/stories/Header.jsx, src/stories/Button.jsx)
created dist/index.cjs.js in 569ms
下記の情報を参考に対応できた
npm install @rollup/plugin-commonjs --save-dev
npm install @rollup/plugin-node-resolve --save-dev
rollup.config.js編集
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
plugins: [
nodeResolve({preferBuiltins: false }),
commonjs(),
]
storybook run
react-component $ npm run storybook
サンプルとして、Button、そのButtonを使用したHeader、そのHeaderを使用したPageが表示されている
後で、このHeaderコンポーネントを使ってみる
publish
srcなどは対象外にするために.npmignoreファイルを作成する
.npmignore
## the src folder
src
.babelrc
rollup.config.js
## node modules folder
node_modules
## incase you have a git repositiory initiated
.git
.gitignore
CVS
.svn
.hg
.lock-wscript
.wafpickle-N
.DS_Store
npm-debug.log
.npmrc
config.gypi
package-lock.json
.storybook
storybook-static
npm version patch
#事前にnpm https://www.npmjs.com/ にユーザー登録しておく
npm login
#初回のみpublicであることを明示しないとエラーになる
npm publish --access=public
#2回目以降
npm publish
rollup.config.js 最終形
import commonjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import styles from "rollup-plugin-styles";
import babel from '@rollup/plugin-babel';
import sourcemaps from 'rollup-plugin-sourcemaps';
import del from 'rollup-plugin-delete';
const autoprefixer = require('autoprefixer');
const conf = {
input: 'src/index.js',
output: {
file: `dist/index.cjs.js`,
format: "cjs",
exports: "auto"
},
// this externelizes react to prevent rollup from compiling it
external: ["react", /@babel\/runtime/],
plugins: [
// these are babel comfigurations
babel({
exclude: 'node_modules/**',
plugins: ['@babel/transform-runtime'],
babelHelpers: 'runtime'
}),
// this adds sourcemaps
nodeResolve({preferBuiltins: false }),
commonjs(),
sourcemaps(),
del({targets:'dist/*'}),
// this adds support for styles
styles({
postcss: {
plugins: [
autoprefixer()
]
}
})
]
}
export default conf;
package.json 最終形
{
"name": "@marumarumeruru/react-component",
"version": "1.0.12",
"description": "",
"main": "dist/index.cjs.js",
"scripts": {
"build": "rollup -c",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.16.7",
"@babel/core": "^7.16.7",
"@babel/plugin-transform-runtime": "^7.16.7",
"@babel/preset-env": "^7.16.7",
"@babel/preset-react": "^7.16.7",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.1.3",
"@storybook/addon-actions": "^6.4.9",
"@storybook/addon-essentials": "^6.4.9",
"@storybook/addon-links": "^6.4.9",
"@storybook/react": "^6.4.9",
"autoprefixer": "^10.4.2",
"babel-loader": "^8.2.3",
"rollup": "^2.63.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-styles": "^3.14.1"
},
"dependencies": {
"@babel/runtime": "^7.16.7"
}
}
作成したパッケージを利用する
reactの別プロジェクトを作成して、Headerコンポーネントを使用してみる
create-react-app
npx create-react-app use-component
cd use-component
npm install
npm install @marumarumeruru/react-component
@marumarumeruru/react-componentの部分は、npmにpublishしたパッケージ名
App.jsx編集
App.jsx
import logo from './logo.svg';
import './App.css';
import component from '@marumarumeruru/react-component';
function App() {
return (
<div className="App">
<component.Header/>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<component.AwesomeButton>Suceess!!</component.AwesomeButton>
</header>
</div>
);
}
export default App;
run
npm start
Headerが表示できた!
link
Discussion