0.0.8 • Published 2 years ago

@shen9401/react-dialog v0.0.8

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

1.拉取一份 react创建的工程 地址


2. 开发 思路

  • 分两个文件夹
  • dev 开启一个react开发项目
  • src 为具体库的实现代码
  • 然webpack配置一个正常的react项目,入口设置为dev下面的index
  • 这样启动这个webpack,就可以在线开发src下面的库了

2.1 以实现一个react弹窗组件为例,先写一个弹窗组件

// src\index.tsx

import React, { Component } from 'react';
import { createPortal } from 'react-dom';
import './index.scss';

export interface IDialogProps{
  hideDialog:Function
}
export default class Dialog extends Component<IDialogProps> {
  node:HTMLElement;

  constructor(props:IDialogProps) {
    super(props);

    this.node = document.createElement('div');
    this.node.classList.add('dialog');
  }

  componentDidMount() {
    document.body.appendChild(this.node);
  }

  componentWillUnmount() {
    document.body.removeChild(this.node);
  }

  render() {
    const { hideDialog, children } = this.props;
    return createPortal(
      <div className="dialog-model">
        {children}
        {typeof hideDialog === 'function' && (
        <button onClick={() => hideDialog()} type="button">关闭窗口</button>
        )}
      </div>, this.node,
    );
  }
}

2.2 在example开启react开发项目,并且使用src导出的Dialog

// example\index.tsx

import React, {  useState } from 'react'
import ReactDOM from 'react-dom';

import Diallog from '../src/index'

function App(){
  const [isShowDialog,setIsShowDialog] = useState(false)
  return (
    <div>
      <h3>DialogPage</h3>
      <button onClick={() => setIsShowDialog(true)}>
          toggle
      </button>
      {isShowDialog && <Diallog children="hello" hideDialog={() => setIsShowDialog(false)} />}
    </div>
    )
}


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

2.3 配置 example 的webpack

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

module.exports = {
    entry: './dev/index.tsx',
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'build'),
    },
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './build',
        // 启动gzip 压缩0
        compress: true,
        // 端口号
        port: 8080,
        open: true,
        hot: true,
    },
    plugins: [
      new HtmlWebpackPlugin({ template: './index.html' }),
    ],
    module: {
        rules: [
            {
              test: /\.html$/i,
              // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
              loader: 'html-loader',
            },
            {
              test: /\.(ts|js)x?$/,
              exclude: /node_modules/,
              loader: 'babel-loader',
            },
            {
              test: /\.(png|svg|jpg|jpeg|gif)$/i,
              type: 'asset/resource',
              generator: {
                filename: 'static/images/[hash][ext][query]',
              },
            },
            {
              test: /\.(woff|woff2|eot|ttf|otf)$/i,
              type: 'asset/resource',
              generator: {
                filename: 'static/font/[hash][ext][query]',
              },
            },
            {
                test: /\.((c|sa|sc)ss)$/i,
                use: [
                    "style-loader",
                    "css-loader",
                    'sass-loader'
                ]
            }
        ]
    },
    optimization: {
      splitChunks: {
        chunks: 'all',
      },
    },
    resolve: {
      // 配置省略文件路径的后缀名
      extensions: ['.tsx', '.ts', '.js'],
    },
}

2.4 最后 npm run start 就可以愉快的开发自己的库了


3.打包思路

  • 开启一个webpack,配置为library
  • 排除用到的 react
  • 去掉corejs

3.1 配置一个生产环境的webpack

const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './src/index.tsx',
    mode: 'production',
    devtool: 'source-map',
    output: {
      filename: 'index.js',
      path: path.resolve(__dirname, 'dist'),
      library:'react-dialog',
      libraryTarget: 'umd'
    },
    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: 'style.css',
            chunkFilename: '[id].css',
        }),
    ],
    module: {
        rules: [
            {
              test: /\.(ts|js)x?$/,
              exclude: /node_modules/,
              loader: 'babel-loader',
            },
            {
              test: /\.(png|svg|jpg|jpeg|gif)$/i,
              type: 'asset/resource',
              generator: {
                filename: 'static/images/[hash][ext][query]',
              },
            },
            {
              test: /\.(woff|woff2|eot|ttf|otf)$/i,
              type: 'asset/resource',
              generator: {
                filename: 'static/font/[hash][ext][query]',
              },
            },
            {
                test: /\.((c|sa|sc)ss)$/i,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    // 将css文件变成commonjs模块加载js中,里面内容是样式字符串
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2,
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ],
            },
        ]
    },
    resolve: {
      // 配置省略文件路径的后缀名
      extensions: ['.tsx', '.ts', '.js'],
    },
    externals:{
      react:'react',
      'react-dom':'react-dom'
    }
}
  • library:'react-dialog'是库名称,libraryTarget: 'umd'编译库的目标,umd 代表ES2015,CommonJS可以使用
  • externals,用户会导入的库,这里不用引入,减少打包体积

3.2 去掉corejs,这里不引入减少打包体积,放给用户去引入

// .babelrc

{
    "presets": [
        "@babel/env",
        "@babel/preset-react",
        "@babel/preset-typescript"
    ],
    "plugins": [
        "@babel/plugin-proposal-class-properties"
    ]
}

3.3 运行npm run build,会打包我们的组件库


4. 推送到npm

4.1 修改package.json

  "name": "@shen9401/react-dialog",
  "main": "dist/index.js",
  "module": "dist/index.js",
  "style": "dist/style.css",
  "files": [
    "dist"
  ],
  • main node和浏览器所需要的文件 ; module 是node和浏览器ES模块需要的文件
  • "sideEffects": false ,会忽略css

4.2 登录到自己的npm账户

npm adduser --registry=https://registry.npmjs.org/
  • 会提示输入用户名,密码,邮箱,以及注册邮箱的验证码

4.3 使用 nrm use npm 切换到npm 源

4.4 npm publish --access public 发布公共包


5.新建一个react项目

5.1 执行 npm i @shen9401/react-dialog 按照包

5.2 引入并使用

import Diallog from '@shen9401/react-dialog'
import '@shen9401/react-dialog/dist/style.css'
function App() {
  const [isShowDialog,setIsShowDialog] = useState(false)
  return (
    <div className="App">
      <button onClick={() => setIsShowDialog(true)}>
          toggle
      </button>
      {isShowDialog && <Diallog children="hello" hideDialog={() => setIsShowDialog(false)} />}
    </div>
  );
}

6. 合并js和css, 修改webpack 配置,避免引入组件之后还要引入样式

            {
                test: /\.((c|sa|sc)ss)$/i,
                use: [
                  "style-loader",
                    // 将css文件变成commonjs模块加载js中,里面内容是样式字符串
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2,
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ],
            },
  • 去掉 MiniCssExtractPlugin,改用style-loader

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago