基于原生js封装react 组件_如何基于antd封装自己的react组件并发布到npm

b75551f2250fa2177e45d5d669cec6db.png

引言

在前端项目开发过程中,有大量重复的内容,比如布局相似的模块,较多的功能表单等,我们可以提炼成组件来提升效率,减少重复建设。文章以实际工作中的项目为例,介绍如何将项目中常用的组件进行封装并发布到npm中。

1 前提要求

在开始前你需要具备以下条件:

  • 安装了Node & npm
  • 安装了Git
  • 基本掌握npm ,git使用方法
  • 熟练使用 JavaScript & ES6 & CSS
  • 基本掌握React
  • 熟悉React ,antd

2 开始

2.1 配置git和npm

本次将我的组件库命名为nsc-components

首先配置git ,在github上创建一个新的远程仓库nsc-components,在本地运行git clone 命令,将nsc-components克隆到本地

$ git clone https://github.com/你的账户名/nsc-components

配置 npm,运行npm login,登录你的npm账号。然后运行npm init 初始化生成一个新的package.json文件.

$ npm init
name: (nsc-components)
version: (1.0.0) 0.1.0
description: an example component library with React!
entry point: (index.js) 
test command:
git repository:
keywords:
Author:
license: (ISC)
About to write to /Users/alanbsmith/personal-projects/trash/package.json:

{
  "name": "nsc-components",
  "version": "0.1.0",
  "description": "an example component library with React!",
  "main": "dist/index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": ,
  "license": "ISC"
}

Is this ok? (yes)

在根目录下添加以下配置文件

touch .babelrc .eslintrc .gitignore .npmignore README.md
  • .babelrc包含编译阶段一些有用的转转码规则(presets)
  • .eslintrc包含linter配置
  • .gitignore和.npmignore分别用于忽略来自 git 和 npm 的文件
  • README.md也非常重要。这是我们和开源社区交流的主要方式

.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
      ["import", {"libraryName": "antd", "libraryDirectory": "lib", "style":"css"
      }],
  ]
}

注:这里踩了很多坑

加入["import", {"libraryName": "antd", "libraryDirectory": "lib", "style": true }]配置是必要的,该配置使用babel-plugin-import 按需加载 antd样式,不加该配置信息antd组建的样式会无法显示。

babel-plugin-import 在 babel 运行时,将类似import { ModuleName } from 'libiaryName'的代码转化为组件所在的路径,这样实际引用的就是这个组件的模块而不是整个 Library

// babel 前
import { Icon } from 'antd';

// babel 后
import _Icon from 'antd/lib/icon';
import 'antd/lib/dropdown/style/css';

.gitignore 添加不需要push的文件

.DS_Store
dist
node_modules
*.log

.npmignore用于忽略不用发布到npm的文件

.babelrc
src
CODE_OF_CONDUCT.md
node_modules
.gitignore
webpack.config.js
yarn.lock
.eslintrc

在初始化的package.json文件里添加以下命令

"scripts": {
 "test": "echo "Error: no test specified" && exit 1",
 "build": "webpack --config webpack.config.js -p",
 "prepublish": "npm run build"
  },
  "files": [
    "dist"
  ],
  • build将运行根目录下webpack.config.js文件对src目录下的内容如何进行转码然后导出到dist目录。需要在webpack.config.js文件设置入口src/index.js。
  • npm会在我们运行npm publish之前执行这个脚本。 这将确保我们在dist的资源是最新的版本。
  • "files"属性的值是一个数组,内容是模块下文件名或者文件夹名,也可以在模块根目录下创建一个".npmignore"文件(windows下无法直接创建以"."开头的文件,使用linux命令行工具创建如git bash),写在这个文件里边的文件即便被写在files属性里边也会被排除在外,写法与".gitignore"类似。

2.2 安装依赖

package.json文件中添加以下字段:

"devDependencies": {
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-class-properties": "^7.2.3",
    "@babel/plugin-proposal-object-rest-spread": "^7.2.0",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.6",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-1": "^6.24.1",
    "babel-plugin-import": "^1.12.0",
    "classnames": "^2.2.6",
    "css-loader": "^3.2.0",
    "eslint": "^6.2.1",
    "eslint-plugin-import": "^2.18.2",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.14.3",
    "eslint-watch": "^6.0.0",
    "less": "^3.10.2",
    "less-loader": "^5.0.0",
    "polished": "^3.4.1",
    "prop-types": "^15.7.2",
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "style-loader": "^1.0.0",
    "webpack": "^4.39.3",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.8.0"
  },
  "dependencies": {
    "antd": "^3.22.0",
    "axios": "^0.19.0",
    "lodash": "^4.17.15",
  },
  "peerDependencies": {
    "antd": "^3.22.0",
    "prop-types": "^15.7.2",
    "react": "^16.9.0",
    "react-dom": "^16.9.0"
  }
  • dependencies字段指定了项目运行所依赖的模块,该类型依赖一般属于运行项目业务逻辑需要依赖的第三方库。
  • devDependencies指定项目开发所需要的模块。
  • peerDependencies中声明的依赖,如果项目没有显式依赖并安装,则不会被npm 自动安装,转而输出warning日志,告诉项目开发者,你需要显式依赖了,不要再依靠我了。

2.3 添加组件

创建src/components目录,在目录下依次添加TooltipButton.js,Toolbar.js,Toolbar.css文件

TooltipButton.js

import React from 'react'
import PropTypes from 'prop-types'
import { Tooltip, Button } from 'antd'

const TooltipButton = props => {
  const { children, tip, placement, ...restProps } = props
  return (
    <Tooltip title={tip} placement={placement}>
      <Button {...restProps}>{children}</Button>
    </Tooltip>
  )
}

TooltipButton.propTypes = {
  tip: PropTypes.string.isRequired,
  placement: PropTypes.string.isRequired
}

TooltipButton.defaultProps = {
  placement: 'top'
}

export default TooltipButton

Toolbar.js

import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import styles from './Toolbar.css'

const Toolbar = ({ children, inline, compact, ...restProps }) => {
  const classes = classNames({
    [styles.toolbarInline]: inline,
    [styles.toolbar]: !inline,
    [styles.compact]: compact
  })

  return (
    <div className={classes} {...restProps}>
      {children}
    </div>
  )
}

Toolbar.propTypes = {
  inline: PropTypes.bool.isRequired,
  compact: PropTypes.bool.isRequired
}

Toolbar.defaultProps = {
  inline: false,
  compact: false
}

const Group = ({ children }) => {
  return (
    <span className={styles.group}>
      {children}
    </span>
  )
}

const Tool = ({ children }) => {
  return (
    <span className={styles.tool}>
      {children}
    </span>
  )
}

Toolbar.Group = Group
Toolbar.Tool = Tool

export default Toolbar

Toolbar.css

.toolbar {
  display: block;
}

.toolbarInline {
  display: inline-block;
}

.tool {
  margin: 0 2px 0 0;
}

.group {
  margin: 0 8px 0 0;
}

.compact .tool {
  margin: 0 1px;
}

.compact .group {
  margin: 0 4px
}

src/index.js

import Toolbar from './lib/components/Toolbar'
import TooltipButton from './lib/components/TooltipButton'

2.4 webpack配置

利用webpack将文件打包

在根目录下添加webpack.config.js文件,添加配置信息如下

var path = require('path')
var webpack = require('webpack')
module.exports = {,
  entry:'./src/index.js', //入口文件路径
  output: {
    filename: 'main.js',
    library: 'nsc-components', 
    libraryTarget: 'umd',
    libraryExport: 'default'
  },
  module: {
    rules: [
      {
        test: /.js[x]?$/,  // 用正则来匹配文件路径,这段意思是匹配 js 或者 jsx
        exclude: /node_modules/,
        include: [path.resolve(__dirname, 'src')],
        loader: 'babel-loader' // 加载模块 "babel-loader" 
      },
       {
         test: /.less$/,
         use: [
           'style-loader',
           { loader: 'css-loader', options: { importLoaders: 1 } },
           'less-loader',
           { loader: 'less-loader', options: { javascriptEnabled: true } }
         ]
       },
      {
        test: /.css$/,
        use: [{
          loader: "style-loader"
        }, 
        {
          loader: 'css-loader',
          options:{ 
            modules: {
              mode: 'local',
              localIdentName: '[name]-[local]',
            },
          }
        }
        ]
      },
      
    ]
  },
  plugins: [
      new webpack.HotModuleReplacementPlugin(),
     ],
  }
  • entry:是入口文件所处的目录的绝对路径的字符串
  • output:output.filename:输出文件名output.library:此配置适用于webpack 用于打包 JavaScript library的时候,例如本例中开发一个名为'nsc-components' 的library,配置output.library设置 library 的名称为'nsc-components'output.libraryTarget:配置了output.library后,还需要在配置文件中添加libraryTarget属性,控制 library 如何以不同方式暴露的选项。
    可以通过以下方式暴露 library:
      • 变量:作为一个全局变量,通过 script 标签来访问(libraryTarget:'var'
      • this:通过 this 对象访问(libraryTarget:'this'
      • window:通过 window 对象访问,在浏览器中(libraryTarget:'window'
      • UMD:在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:'umd'
  • module.rules:
    创建模块时,匹配请求的规则数组,这些规则能够对模块(module)应用 loader。

2.5 打包文件

运行以下命令,将文件打包输出

npm run build

3 创建测试应用

我们需要一个本地环境去试用我们的组件,在本地利用脚手架或者手动新建一个小应用项目,本次我手动新建了一个测试应用,你需要从GitHub上把它clone下来并安装依赖。

$ git clone https://github.com/aaxuyun/demo.git

运行npm run startyarn start,在你的浏览器上打开http://localhost:9100,页面出现‘hello',修改test/index.js文件,将热加载更新。

在之前组件库的根目录运行

pwd

复制组件库地址

在当前测试应用的根目录运行

npm link [组件库地址]

在测试应用调用组件

在test/index.js中我们将像使用其他外部库一样引入和调用我们的组件:

import React from 'react';
import { render} from 'react-dom';
import { TooltipButton } from 'nsc-components'
const App = () => {
 return (
    <div style={{position:"absolute",top:'100px',left:'50%'}}>
        <TooltipButton tip='hi' icon='edit'/>
    </div>
)};
render(<App />, document.getElementById("root"));

保存之后,在页面中将看到以下按钮在界面中显示

c5e9acc2391c38ac342976919da5698b.png

4 发布到npm

运行以下命令将组件发布到npm

npm publish
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值