【react】如何制作react npm包(例如UI组件Text)上传到npm

在这里插入图片描述

学习本文,可以在公司需要自定义自己的各类组件,避免重复造轮子的情况下,使用Npm进行统一复用。以及类似的应用场景也能够应对。

PS:本指南只是从无到有的全过程,如果部分童鞋已经处理了部分,请自行忽略

一、注册npm账号(已注册可自行忽略)

地址:https://www.npmjs.com/signup
注意:需要注意自己注册填写的邮箱是否能正常接收npm系统短信,否则后面的上传步骤会报错403

二、创建空的工程

  • 1、创建新的文件夹
  • 2、进入该文件夹,使用cmd命令,npm进入安装项目流程

安装->创建初始化的package.json

npm init
  • 3、对应的字段:
package name:   组件包名称,注意不能和npm上面已经存在的同名
version: (1.0.0)   版本
description:  描述
entry point: (index.js)   入口文件,默认为index
test command:  (可以为空) 测试命令
git repository:  (可以为空) 指定git仓库
keywords:  (可以为空)
author: 作者名称
license: (ISC) 许可证,一般默认enter就可以

创建完成后,该目录下会多一个package.json文件,内容如下

{
    
    
  "name": "custom-npm-copm-text",
  "version": "1.0.0",
  "description": "通用自定义UI组件Text",
  "main": "index.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "author": "huangzhixin",
  "license": "ISC"
}

以上的package.json文件配置可以根据情况自行修改,但是发布时候需遵守以下规则:

  • 1、版本号必须每次都修改
  • 2、名称保持和上一次不变

三、安装工程需要的依赖包

npm install react react-dom -D
npm install @babel/cli @babel/core @babel/plugin-syntax-jsx @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react  -D
npm install style-loader css-loader babel-loader less-loader less -D
npm install html-webpack-plugin webpack webpack-cli webpack-dev-server -D

上面的依赖安装我们可以分成四部分:

  • 1、react基础部分,react依靠react、react-dom(vue的话可以自行查看需要啥)
    react :react语法
    react-dom:react和页面的dom打交道依赖
  • 2、编译必须要的模块
    @babel/cli: babel配置的脚手架
    @babel/core: 把开发的nodejs编译成前端可以运行的js代码
    @babel/preset-react: 把react编译成可执行js
    @babel/preset-env: 将es6代码转成es5
    @babel/plugin-transform-runtime: 自动移除语法转换后内联的辅助函数以及做API转换,对内置对象进行重命名,以防止污染全局环境
    参考:cnblogs.com/zhishaofei/p/13896056.html
    @babel/plugin-syntax-jsx
  • 3、项目各种loader依赖
    style-loader:处理 dom style 标签里面的css(处理行内样式)
    css-loader:处理css样式
    less-loader :处理less样式
    less:less样式依赖(样式我用less,需要scss的同学自行安装scss)
    babel-loader:负责调用上面所有@babel的依赖模块
  • 4、webpack脚手架
    webpack:webpack主程序 ,webpack-cli:webpack编译工具脚手架
    html-webpack-plugin: 插件,处理html的工具
    webpack-dev-server: 编译运行工具,npm run start 实际调用的方法
    其中 - D的意思是将依赖安装到devDependencies这里,一般来会默认安装到dependencies字段里,区别是dependencies会在打包时候进dist文件夹

有需要可以自行安装自己要的依赖,上面几个是我写组件必要的几个依赖,因为我没有写对应的依赖版本所以安装时候会以最新版本安装。

四、开始配置工程

  • 1、新建如下目录结构和文件

#目录结构如下
├── package.json 依赖包管理文件
├── .gitignore 上传git时候忽略不传的文件
├── public
├── index.html html静态页面
└── app.js webpack入口文件
└── src 组件包源码文件夹
├── index.jsx
├── index.less
├── index.js 暴露你的组件入口文件,即引用组件包时的入口文件,文件名和package.json中main字段同名
├── webpack.config.js webpack配置文件
├── babel.config.js @babel的配置文件(webpack4版本的叫做.babelrc )

  • 2、编写webpack.config.js的配置,以下是最基础的配置
const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 * webpack插件将打包好的文件注入到html模板里
 * @type {HtmlWebpackPlugin}
 */
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    
    
    template: path.join(__dirname, "./public/index.html"),
    filename: "./index.html"
});

module.exports = {
    
    
    mode: 'development',
    entry: path.join(__dirname, "./public/app.js"),   //入口文件
    output: {
    
    
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
    
    
        rules: [{
    
    
            test: /\.js$|.jsx/,   //正则匹配文件名称
            use: "babel-loader",    //会去调用babel.config.js里的所有babel的配置
            exclude: /node_modules/
        },  {
    
    
             test: /\.css|.less$/,
             use: ["style-loader", "css-loader", "less-loader"]
            }]
    },
    plugins: [htmlWebpackPlugin],   //插件:自动注入编译打包好的文件
    resolve: {
    
    
        extensions: [".js", ".jsx"]
    },
    devServer: {
    
    
        port: 8000,  //端口号
        open: true, // 自动打开浏览器
        compress: true, // 启动gzip压缩
    }
};

上面的less-loader没有启用less modules模块化,这会存在全局样式污染的问题,例如我们项目有好几个组件,使用模块化就可以通过导入指定的文件名,在编译时转换成对应的[path][name]-[local]-[hash:5]hash类名避免重复,即模块化就可以避免我们不同组件之间样式互相污染,如果不开启就不生效,参考如下:

index.jsx文件:

import './styl1.less'; //普通用法
import styles from './styl2.less'; //less  module写法
...
return (<div className='box'>  
  <p className={
    
    styles.pf}>如果没有启用模块化这种写法样式将不生效,dom元素上不会有class样式</p>
</div>)

所以得将webpack.config.js修改如下:

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
/**
 * webpack插件将打包好的文件注入到html模板里
 * @type {HtmlWebpackPlugin}
 */
const htmlWebpackPlugin = new HtmlWebpackPlugin({
    
    
    template: path.join(__dirname, "./public/index.html"),
    filename: "./index.html"
});

module.exports = {
    
    
    mode: 'development',   //这个值有3种:production、development、none
    entry: path.join(__dirname, "./public/app.js"),
    output: {
    
    
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js"
    },
    module: {
    
    
        rules: [{
    
    
            test: /\.js$|.jsx/,
            use: "babel-loader",
            exclude: /node_modules/
        },
            {
    
    
                test: /\.css$/,
                use: [
                    {
    
    loader: "style-loader"},
                    {
    
    loader: "css-loader"}],   //打包处理css样式表的第三方loader
            }, {
    
    
                //只为less启用模块化
                test: /\.less$/,
                use: [
                    {
    
    loader: "style-loader"},
                    {
    
    
                        loader: "css-loader", options: {
    
    
                            modules: {
    
    localIdentName: "[path][name]-[local]-[hash:5]"}
                        }
                    },
                    {
    
    loader: "less-loader"},
                ]
            }]
    },
    plugins: [htmlWebpackPlugin],   //插件:自动注入编译打包好的文件
    resolve: {
    
    
        extensions: [".js", ".jsx"]
    },
    devServer: {
    
    
        port: 8000,  //端口号
        open: true, // 自动打开浏览器
        compress: true, // 启动gzip压缩
    }
};

接下来往babel.config.js添加编译时候需要的loader配置:

module.exports = {
    
    
    "presets": ["@babel/preset-env", "@babel/preset-react"],
    "plugins": ["@babel/plugin-syntax-jsx", "@babel/plugin-transform-runtime"]
}
  • 3、编写组件
    这个是核心部分,就是说这里是你的组件
    ./src/index.jsx
import React, {
    
    Component, useState, memo} from 'react';
import styles from './index.less';
function Index() {
    
    
    return <div className={
    
    styles.fontBlue}>
        Text组件上传demo
    </div>
}

export default memo(Index);

./src/index.less

.fontBlue {
    
    
  color: blue;
}
  • 4、对外暴露组件,编辑根目录下的index.js文件
    我这里叫Test,使用组件包引入时候就是Test组件。别人在引用组件包时候会从该文件作为入口(package.json的main字段可以配置),这个文件有两种写法:

第一种:

import Test from './src/index.jsx'

export default Test

第二种:

'use strict';
var Test = require('./src/index.jsx');

module.exports = Test;
  • 5、编写webpack读取的入口文件 public/app.js
    webpack启动、编译、打包都会从这个文件作为入口(webpack那边配置的)
import React from 'react'
import {
    
     render } from 'react-dom'
import ReactTextDemo from '../src/index.jsx'    //引入组件

const App = () => {
    
    
    return <ReactTextDemo />
};
render(<App/>, document.getElementById('root'));   //获取虚拟dom的挂载节点
  • 6、编写html模板,public/index.html文件。
    我们知道spa单页面都是依据一个html模板上面引入js创建虚拟dom生成到这个html上面,所以需要有一个挂载的实例模板。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>npm上传的Text组件包demo</title>
</head>
<body>
	<div id="root"></div>
</body>
</html>
  • 7、编写.gitignore文件
    这个文件可以配置git上传时候忽略哪些文件不想传上去,同时发布组件包的时候它也会按照这个文件来,忽略哪些不上传。
node_modules/
dist/
  • 8、添加项目启动命令:修改package.json文件
    给该文件的scripts里添加两个系统命令,一个是启动命令,一个是打包命令(制作组件包用的比较少)。注意webpack4的版本可能不是 webpack server --mode development,这个需要自己对应版本
  "scripts": {
    
    
    "start": "webpack server --mode development",
    "build": "webpack --mode development"
  },

接下来本地启动试下看下效果,命令:npm run start ,如果启动时候报错:[webpack-cli] ReferenceError: BigInt is not defined

说明是node版本问题,需要安装高点版本的node,可以使用nvm来管理node版本,这里不多说,我切换为node 12.0.0版本就可以。

五、发布

到此为止,我们已经配置好了工程,接下来需要把组件包发布上去

  • 1、发布规则

    • 组件包名称不能与npm上已经存在的一致,必须唯一性
    • 每次发布必须修改版本号
    • 发布的源必须是npm,有的设置了淘宝或者其他源,需要设置回npm源。

例如你是淘宝源你需要:
查看设置过的所有的源:npm config get registry
设置当前源为npm:npm config set registry https://registry.npmjs.org/
发布完成后设置回淘宝源:npm config set registry https://registry.npm.taobao.org

  • 2、发布流程

    • 登录注册好的npm账号:npm login
      输入对应的账号、密码、邮箱即可
    • 发布上去:npm publish
      没有报错则表示成功

完毕!

猜你喜欢

转载自blog.csdn.net/hzxOnlineOk/article/details/130058962