发布一个React组件到npm

2022-04-27  本文已影响0人  麦西的西

1. 创建项目

mkdir component-template && cd component-template
npm init

npm init会弹出项目名称、版本、描述等信息,按照自己需要填写即可。
执行完以上 shell 命令后会生成一个含有package.json的空项目, 我们修改文件目录如下:

component-template
├─ config
│  ├─ webpack.config.base.js
│  ├─ webpack.config.dev.js
│  └─ webpack.config.prod.js
├─ demo // 测试组件用
│  ├─ index.html
│  └─ index.js
├─ src // 源代码目录
│  ├─ index.js
│  └─ index.less
├─ babel.config.json
└─ package.json

2. 安装依赖

npm i react react-dom --save-dev
npm i webpack webpack-cli webpack-dev-server webpack-merge clean-webpack-plugin --save-dev

其中,clean-webpack-plugin 是为了每次打包清除掉前一次的内容。

npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react --save-dev
npm i babel-loader --save-dev
npm i style-loader css-loader less less-loader --save-dev

3. 配置 webpack

const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          },
          'less-loader'
        ]
      },
      {
        test: /\.(jpg|jpeg|png|gif|svg)$/,
        type: 'asset',
        parser: {
          // 转base64条件
          dataUrlCondition: {
            maxSize: 8 * 1024
          }
        },
        generator: {
          filename: 'img/[name].[hash:6][ext]'
        }
      }
    ]
  },
  // 配置下别名和扩展名优先级, 为了引入时书写方便
  resolve: {
    alias: {
      '@': path.resolve(__dirname, '../src/')
    },
    extensions: ['.js', '.jsx', '.json']
  }
};
const path = require('path');
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.config.base.js');

const devConfig = {
  mode: 'development',
  entry: path.join(__dirname, '../demo/index.js'),
  output: {
    path: path.join(__dirname, '../demo/'),
    filename: 'bundle.js'
  },
  devServer: {
    static: path.join(__dirname, '../demo/'),
    compress: true,
    host: '127.0.0.1',
    port: 8899,
    open: true
  }
};

module.exports = merge(devConfig, baseConfig);

需要注意的是, 开发配置是为了实时预览效果,入口是 demo/index.js。打包产生的 bundle.js 在内存中,不会在 demo 文件夹实际生成。

const path = require('path');
const { merge } = require('webpack-merge');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const baseConfig = require('./webpack.config.base.js'); // 引用公共的配置

const prodConfig = {
  mode: 'production',
  entry: path.join(__dirname, '../src/index.js'),
  output: {
    path: path.join(__dirname, '../lib/'),
    filename: 'index.js',
    libraryTarget: 'umd',
    libraryExport: 'default' 
  },
  plugins: [new CleanWebpackPlugin()],
  optimization: {
    minimize: true
  },
  externals: {
    // 外部依赖
    react: {
      root: 'React',
      commonjs2: 'react',
      commonjs: 'react',
      amd: 'react'
    },
    'react-dom': {
      root: 'ReactDOM',
      commonjs2: 'react-dom',
      commonjs: 'react-dom',
      amd: 'react-dom'
    }
  }
};

module.exports = merge(prodConfig, baseConfig);

4. 配置 babel

babel.config.js中配置:

module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react']
};

至此,所有配置已完成。接下来我们开发组件。

5. 开发组件

我们写一个简单的组件。一个宽高各 200px 的盒子,文本水平、垂直居中。

// src/index.js:
import React from 'react';
import styles from './index.less';

const Test = (props) => {
  const { text = '测试' } = props;
  return (
    <>
      <div className={styles.box}>{text}</div>
    </>
  );
};

export default Test;
// src/index.less
.box {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 200px;
    height: 200px;
    font-size: 16px;
    color: #fff;
    background-color: #ff0000;
}

6. 测试效果

demo/index.html添加如下代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="./bundle.js"></script>
</body>

</html>

demo/index.js 添加以下代码:

import React from 'react';
import { render } from 'react-dom';

import Test from '../src';
const App = () => (
  <div style={{ width: '100vw', height: '100vh' }}>
    <Test text='哈哈' />
  </div>
);

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

修改package.json里的运行脚本,如下:

  ...
  "scripts": {
    "start": "webpack-dev-server --config config/webpack.config.dev.js",
    "build": "webpack --config config/webpack.config.prod.js",
    "pub": "npm run build && npm publish"
  },
  ...

npm run start看一下组件效果。确认没问题,那我们就npm run build打包。

7. 发布

根据自己需要,书写使用文档 README.md, 添加一下.npmignore,如下:

node_modules/
src/
demo/
config/
babel.config.json
.gitignore

npm login登录自己的账号
在项目根目录,npm publish即可发布自己的 npm 包。
到 npm 平台上打开自己的账户,就可以查看自己的 npm 包了。

上一篇下一篇

猜你喜欢

热点阅读