-
在前端开发时,一些常见的组件(如select)往往不能满足现实开发需求,需要对组件进行重新的封装和优化
-
重新封装优化的组件往往会用在不同的几个项目,这个时候如果要在另外一个项目中使用这个组件,就只能把组件代码重新copy一份,这样存在很多弊端,第一点就是代码冗余;第二点是如果要对这个组件进行升级修改,这个时候得去每个项目下修改一遍,想想就头大
为了解决这个问题,做了以下探索,特此记录以下操作的流程,中间有很多细节本文不详细解释,因为还有很多配置不是很明白,找个机会系统讲一下npm相关知识
- 为什么要搭建npm私有仓库(私服)
eg:
1.有三个项目A、B 、C
2.在A项目写了一个select组件,又不能将这个组件发布到npm公共社区里
没有npm私服时的做法:
-
这时如果B和C项目要用带这个组件的话,只能去A项目里复制一份粘贴到B和C项目
-
如果后面select组件更新了的话,又只能复制粘贴
如上这种情况,耗费时间。有时还会忘了哪个项目的组件时最新的。一个组件都这么麻烦,如果是多个组件和多个项目,维护简直要疯了。
如果我们有npm私有仓库的做法:
-
将select组件发布到私有仓库里
-
每个项目启动前,执行npm 命令重新下载更新组件即可
私有npm私有仓库的好处
-
便于管理企业内的业务组件或者模块
-
私密性
-
确保npm服务快速稳定(私服通常搭建在内部的服务器里)
-
控制npm模块质量和安全(防止恶意代码植入)
- 自定义组件发布到私有仓库的流程(Windows系统)
1.创建组件
md gldSelect
cd gldSelect
2.创建以下文件或文件夹
md build
md src
package.json
"name": "gld-select",
"version": "1.0.1",
"description": "This is an optimized Select component",
"main": "build/index.js",
"peerDependencies": {
"react-dom": "^16.12.0",
"react": "^16.4.0"
"scripts": {
"start": "webpack --watch",
"build": "webpack"
"author": {
"name": "szyy"
"license": "ISC",
"dependencies": {
"antd": "^3.26.5",
"prop-types": "^15.7.2",
"react": "^16.4.0",
"react-dom": "^16.12.0",
"webpack": "^4.12.0"
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"webpack-cli": "^3.3.10"
webpack.config.js
var path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2'
module: {
rules: [
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components|build)/,
use: {
loader: 'babel-loader',
options: {
presets: ["env", "stage-0"]
externals: {
'react': 'commonjs react'
.babelrc
"presets": ["env", "stage-0"],
"plugins": [
"transform-object-rest-spread",
"transform-react-jsx",
"transform-class-properties"
3.将自定义组件写入到src/index.js
src/index.js
import React from "react";
import { Select } from "antd";
import PropTypes from "prop-types";
export default class GldSelect extends Select {
static propTypes = {
dataSource: PropTypes.array,
onChange: PropTypes.func,
static defaultProps = {
dataSource: [],
init(source, isSearch) {
this.pageNum = 1;
this.scrollPos = 0;
this.dataSource = source;
this.setState({
displayVals: this.dataSource.length > this.pageSize ?
this.dataSource.slice(0, this.pageSize * this.pageNum) : this.dataSource,
isSearch: isSearch,
});
constructor(props) {
super(props);
this.pageSize = 20;
this.pageNum = 1;
this.scrollPos = 0;
this.dataSource = props.dataSource;
this.state = {
displayVals: this.dataSource.length > this.pageSize ?
this.dataSource.slice(0, this.pageSize * this.pageNum) : this.dataSource,
isSearch: false,
componentDidUpdate(prevProps, prevState, snapshot) {
const { dataSource } = this.props;
const ds = [].concat(dataSource);
const preDs = [].concat(prevProps.dataSource);
if (preDs.sort().toString() !== ds.sort().toString()) {
this.init(dataSource)
handleChange = v => {
const { onChange, dataSource } = this.props;
const { isSearch } = this.state;
onChange && onChange(v);