انتشار یک کامپوننت ری اکتی(Reactjs) در npm




امروز تصمیم گرفتم یک کامپوننت hello world با هم در npm منتشر کنیم . نتیجه کار رو میتونید در مخازن ان پی ام من ببینید :

https://github.com/nimahkh/react-helloworld-component


https://www.npmjs.com/package/@nimahkh/reacthelloworldcomponent

نحوه نصب :

npm i @nimahkh/reacthelloworldcomponent

و در آخر داخل کامپوننت خود به شکل زیر میتونید از این پکیج استفاده کنین :

mport React, from 'react';
import ReactDOM from 'react-dom';
import Hello from '@nimahkh/reacthelloworldcomponent/lib';
import * as serviceWorker from './serviceWorker';

const classes={
  fontSize:12,
  color:'red',
  width:'100%',
  margin:'0 auto',
  padding:10
}

const App = () => {
  return <HelloWorld classes={classes} greetings={"Hello IRC"} />;
};

ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();

خوب برای نوشتن این پکیج باید اول از همه یک سری پیش نیاز رو بدونیم . مثل اینکه چجوری میشه یک پروژه با ری اکت نوشت که نیازی به CRA نداشته باشه . برای این کار من یک package.json اماده کردم که میتونید مشاهده کنین .اما قبل از اون اول دستور npm i رو بزنید و package.json رو برای خودتون داخل یک مسیر خالی بسازید .

بعد از اینکه این مسیر رو ایجاد کردید ، باید یک سری پکیج نصب کنیم . کد زیر رو وارد کنین :

npm i --dev @babel/core @babel/plugin-proposal-object-rest-spread @babel/preset-env @babel/preset-react babel-eslint babel-loader webpack webpack-cli webpack-dev-server eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react html-webpack-plugin react-testing-library
npm i react react-dom

در نهایت package.json به شکل زیر باید داشته باشیم :

{
  "name": "@nimahkh/reacthelloworldcomponent",
  "version": "1.1.24",
  "description": "IRC hello world component",
  "main": "index.js",
  "jest": {
    "setupFiles": [
      "<rootDir>/scripts/throw-on-prop-type-error.js"
    ]
  },
  "files": [
    "lib"
  ],
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "test": "jest ./test",
    "build": "yarn autoclean && cross-env NODE_ENV=production babel src -d lib --copy-files"
  },
  "author": "IRC (iran react community)",
  "license": "MIT",
  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
    "@babel/preset-env": "^7.4.4",
    "@babel/preset-react": "^7.0.0",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.6",
    "cross-env": "^5.2.0",
    "eslint": "^5.16.0",
    "eslint-config-airbnb": "^17.1.0",
    "eslint-config-prettier": "^4.3.0",
    "eslint-plugin-import": "^2.17.2",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-react": "^7.13.0",
    "html-webpack-plugin": "^3.2.0",
    "jest": "^24.8.0",
    "jest-dom": "^3.2.2",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-test-renderer": "^16.8.6",
    "react-testing-library": "^7.0.0",
    "webpack": "^4.31.0",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.4.1"
  },
  "dependencies": {
    "prop-types": "^15.7.2"
  },
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  }
}

بعد از انجام دو دستور بالا ، یک سری فایل کانفیگ باید بسازیم برای babel و eslint , webpack . خوب فال های زیر رو با محتوای زیر بسازید :

.babelrc

{
  "presets": ["@babel/env", "@babel/react"],
  "plugins": ["@babel/plugin-proposal-object-rest-spread"]
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const htmlWebpackPlugin = new HtmlWebpackPlugin({
  template: path.join(__dirname, 'output/src/index.html'),
  filename: './index.html',
});

module.exports = {
  entry: path.join(__dirname, 'output/src/index.js'),
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        use: 'file-loader',
        test: /\.(woff(2)?|ttf)(\?v=\d+\.\d+\.\d+)?$/,
      },
      {
        test: /\.(gif|png|jpe?g|svg)$/i,
        use: [
          'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              disable: true,
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [htmlWebpackPlugin],
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  devServer: {
    port: 3000,
  },
  devtool: 'source-map',
};

خوب بعد از کارهای بالا یک پوشه میسازیم به اسم src و یک index.js و کامپوننت رو مینویسیم :

import React from "react"
import PropTypes from 'prop-types';

const Hello=(props)=>{
    const {greetings , classes}=props;
    return (
        <div style={classes}>
            {greetings!==undefined ? greetings:"Hello world"}
        </div>
    )
}

Hello.propTypes={
    classes:PropTypes.object.isRequired,
    greetings:PropTypes.string
}

export default Hello

مرحله بعدی اینه که بتونیم داخل محیط develop ، برنامه رو تست کنیم . فرض میکنیم دقیقا یک کمپوننت طراحی شده که باید داخل یک محیط ری اکتی وارد بشه و کار بشه . این محیط رو شبیه سازی میکنم . یک پوشه میسازیم به اسم output و یک پوشه به اسم src و داخل این فایل هم یک index.js با محتوای زیر

import React from 'react';
import ReactDOM from 'react-dom';
import HelloWorld from '../../src';

const classes={
  fontSize:12,
  color:'red',
  width:'100%',
  margin:'0 auto',
  padding:10
}

const App = () => {
  return <HelloWorld classes={classes} greetings={"Hello IRC"} />;
};

ReactDOM.render(<App />, document.getElementById('root'));

خوب کنار همین فایل هم یک index.html میسازیم دقیقا با محتوای index.html ری اکت :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Iran React Community (IRC)</title>
</head>
<body>
  <noscript>
      You need to enable JavaScript to run this app.
  </noscript>
  <div id="root"></div>
</body>
</html>

بعد از انجام این کار باید package.json رو تغییر بدیم :

...
"scripts": {
  "start": "webpack-dev-server --mode development",
  "test": "jest ./test",
  "build": "yarn clean && cross-env NODE_ENV=production babel src -d lib --copy-files"
},
...

خوب حالا دستور npm run start رو بزنین و روی پورت 3000 میبینید که یک hello world کوچیک قرمز بالا سمت چپ دیده میشه .

یادتون باشه همیشه باید تست نویسی انجام بشه .

یک فولدر به اسم test بسازید و داخل اون فایلی به اسم helloworld.test.js با محتوای زیر قرار بدید

import React from "react"
import HelloWorld from '../src/index';
import {render} from 'react-testing-library';
import 'jest-dom/extend-expect'

describe('Helloworld Component', () => {
  test("check props",()=>{
    const classes={};
    const {container} = render(
        <HelloWorld classes={classes}/>,
    );
    expect(container).toHaveTextContent("Hello world")
  })

  test("change props",()=>{
    const classes={};
    const greetings="Hello IRC";
    const {container} = render(
        <HelloWorld classes={classes} greetings={greetings}/>,
    );
    expect(container).toHaveTextContent(greetings)
  })
});

خوب الان که npm run test رو بزنید ، تست ها با موفقیت اجرا میشن .

مرحله بالا بردن پروژه روی npm

وارد سایت npm بسید و یک حساب باز کنین . بعد از اینکه حساب شما ایجاد شد ، به ترمینال برید و بنویسید

npm login

مشخصاتی که از شما سوال میشه پاسخ بدید . بعد از اون میتونید پروژه رو به شکل public منتشر کنین .

npm publish --access public

خوب کار تمومه . هر تغییری که میدین روی پروژه ، با نسخه بندی های npm version minor یا npm version major یا pm version patch میتونین تنظیم کنین و مجدد دستور publish رو بزنین تا منتشر بشه .

نسخه ها به این شکل هستند

major.minor.patch

مثلا نسخه 1.0.0 به معنی اینکه major برابر 1 و باقی برابر 0هستند .