在material-ui基础上分装自己的组件库并发布到npm

一. webpack构建项目,创建一个项目文件,文件结构如下

package.json

注意:所有依赖都安装在 devDependencies中;

这里有用到peerDependencies,这里的意思是避免重复依赖,比如@material-ui/core在我的组件库被引入一次,在使用项目中又会再次被引入,避免两次安装冗余,以及两个版本差异带来的分险,所以用到了peerDependencies,具体左右可百度。

{
  "name": "test-library-hybird-libs",
  "version": "1.0.5",
  "description": "",
  //包的入口地址 "main": "dist/src/widget/index.js", "files": [ "dist" ], "keywords": [], "author": "", "license": "MIT", "private": false,
//仓库地址 "repository": { "type": "git", "url": "https://www.npmjs.com/package/test-library-hybird-libs" },
//包的主页url "homepage": "https://www.npmjs.com/package/test-library-hybird-libs", "scripts": { "start": "webpack-dev-server --config webpack.dev.config.js", "dev": "webpack-dev-server --config webpack.dev.config.js", "build": "rimraf ./dist & rimraf ./dist.zip && md dist && webpack --config webpack.prod.config.js " }, "dependencies": { }, "devDependencies": { "@babel/core": "7.15.8", "@babel/plugin-transform-runtime": "7.16.0", "@babel/preset-env": "7.2.3", "@babel/preset-react": "7.16.0", "@babel/runtime": "7.16.0", "babel-loader": "8.2.2", "css-loader": "0.28.9", "eslint-config-airbnb-base": "14.2.1", "eslint-plugin-eslint-plugin": "3.6.1", "file-loader": "6.2.0", "html-webpack-plugin": "^5.5.0", "prop-types": "15.7.2", "style-loader": "0.19.1", "webpack": "5.58.1", "webpack-cli": "4.9.0", "webpack-dev-server": "^4.5.0", "react": "17.0.2", "react-dom": "17.0.2", "copy-webpack-plugin": "^4.6.0", "@date-io/moment": "1.3.13", "@material-ui/core": "4.12.2", "@material-ui/data-grid": "4.0.0-alpha.37", "@material-ui/icons": "4.11.2", "@material-ui/lab": "4.0.0-alpha.60", "@material-ui/pickers": "3.3.10", "@material-ui/styles": "4.11.4", "@material-ui/system": "4.12.1", "@mui/x-data-grid": "4.0.0", "@mui/x-data-grid-pro": "4.0.0" }, "peerDependencies": { "react": "17.0.2", "react-dom": "17.0.2", "@date-io/moment": "1.3.13", "@material-ui/core": "4.12.2", "@material-ui/data-grid": "4.0.0-alpha.37", "@material-ui/icons": "4.11.2", "@material-ui/lab": "4.0.0-alpha.60", "@material-ui/pickers": "3.3.10", "@material-ui/styles": "4.11.4", "@material-ui/system": "4.12.1", "@mui/x-data-grid": "4.0.0", "@mui/x-data-grid-pro": "4.0.0" } }

  webpack.prod.config.js

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  mode: 'production',
 // 配置 entry 属性,即构建时的入口。例如:此时组件入口是widget下的index.js。 entry: { main: './src/widget/index.js', }, output: { path: path.resolve(__dirname, './dist'), publicPath: '/dist', filename: 'build.js',
// 配置 library 和 libraryTarget 属性 library: 'test-library-hybird-libs', libraryTarget: 'umd', }, resolve: { extensions: ['.js', '.jsx'], }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, { test: /\.(js|jsx)$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', }, }, { test: /\.(woff|woff2|ttf|eot|ico)$/, use: [ { loader: 'file-loader', }, ], }, ], }, plugins: [ new CopyWebpackPlugin([ { from: path.resolve(__dirname, './src'), to: path.resolve(__dirname, './dist/src'), }, ]), ], };

  

 二.编写组件

widget/index.js

import Checkbox from './Checkbox';

export { Checkbox };

widget/Checkbox.js 

import React from 'react';
import { Checkbox as HACheckbox } from '@material-ui/core';
import PropTypes from 'prop-types';
import checkoutStyles from './style';
import theme from '../../themes/theme';

const CheckBox = ({ className, ...props }) => {
  const classes = checkoutStyles(props);
  return <HACheckbox
    className = {`${classes.checkboxRoot} ${className}`}
    inputProps={{"aria-label":'checkbox'}}
    checked={props.checked}
    onChange={props.onChange}
    color={['default','info','secondary','warning'].indexOf(props.color)>-1?props.color:'default'}
  />
};

CheckBox.propTypes = {
  /**
   * Checkbox color
   */
  color: PropTypes.oneOf(Object.keys(theme.themeColorList)),
  /**
   * Checkbox width
   */
  width: PropTypes.number,
  /**
   * Optional checked
   */
  checked: PropTypes.bool,
  /**
   * Optional default Checked
   */
  defaultChecked: PropTypes.bool,
  /**
   * class Name
   */
  className: PropTypes.string,
  /**
   * Optional change handler
   */
  onChange: PropTypes.func,
};

CheckBox.defaultProps = {
  defaultChecked: false,
  checked: false,
  color: 'default',
};

export default CheckBox;

  widget/style.js

import { makeStyles } from '@material-ui/core/styles';

const checkoutStyles = makeStyles((theme) => ({
  checkboxRoot: {
    padding: '2px',
    '@global': {
      '.MuiSvgIcon-root': {
        fill: (props) => theme.themeColorList[props.color] || theme.themeColorList.Primary,
        width: (props) => props.width || '20px',
        height: (props) => props.width || '20px'
      }
    }
  }
}));

export default checkoutStyles;

  

三.安装依赖并打包组件

npm  i
npm run build

四. 本地模拟发布

打包完成后,继续在组件源码根目录下,执行命令:

npm pack

  命令执行后,会在根目录下生成一下.tgz包,然后在需要引入组件的项目中执行以下命令:npm install 本地包路径,本地包路径为刚才生成的.tgz包路径,注意命令中斜杠方向!!!

 

 

 安装后,package中会出现一条依赖,但本条记录会显示文件路径,因为是本地模拟安装的。

到这一步就可以直接测试组件

 

五.发布组件到npm

   1. 注册npm账号,这里不多说了

   2. 切换到需要发包的项目根目录下,登录npm账号,输入用户名、密码、邮箱

npm login //登录

npm publish //发布

  每次发布到npm上需要更改版本号,即package.json 里的 version 字段不可与已发布的包版本号相同

  3.安装组件 

npm install 组件名称

  

 六,使用组件

import { MuiThemeProvider, CssBaseline } from '@material-ui/core';
import {CheckBox} from 'test-library-hybird-libs';
import theme from './themes/theme';
import GlobalStyles from './themes/GlobalStyles';

function App() {
  console.log(CheckBox)
  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline />
      <GlobalStyles />
      test
      <CheckBox color="Primary" checked/> 
    </MuiThemeProvider>
  );
}

export default App;

  

 

posted @ 2022-02-10 18:00  Tiramisu.man  阅读(286)  评论(0编辑  收藏  举报