基于react+less+webpack+babel从零开始搭建npm仓库UI组件库(类似Ant Design)的开发环境并发布至npm

本文是我的个人网站G笔记中的内容,最新的内容可访问G笔记

React组件开发教程

用webpack从零开始搭建开发react组件库(npm包)的环境,将介绍如何开发npm包,并可以通过npm install的方式进行依赖使用。

初始化

1. 新建一个项目

mkdir example
cd example
npm init

根据提示输入配置信息后,将看到 package.json 文件已创建。

2. 安装依赖包:

npm install react react-dom prop-types -S
npm install webpack webpack-cli webpack-dev-server -D
npm install @babel/core @babel/preset-env @babel/preset-react babel-loader -D
npm install html-webpack-plugin -D
npm install style-loader css-loader less less-loader -D

这里用的版本号需要注意一下,下面的版本号已亲测有效。

"dependencies": {
    "prop-types": "^15.7.2",
    "react": "^16.8.4",
    "react-dom": "^16.8.4"
},
"devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "css-loader": "^2.1.1",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "less": "^3.9.0",
    "less-loader": "^4.1.0",
    "webpack": "^4.28.3",
    "webpack-cli": "^3.2.3",
    "webpack-dev-server": "^3.2.1"
}

3. 修改package.json

{
    "main": "dist/index.js",
    "scripts": {
        "build": "webpack --env.NODE_ENV=production",
        "start": "webpack-dev-server --hot --open"
    },
    "files": [
        "dist"
    ]
}
  • main为打包后的出口文件;
  • scripts为webpack命令配置;
  • files为推送到npm仓库所包括的文件。

4. 配置babel

根目录下新建 .babelrc 文件

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

5. 创建webpack相关文件

  • webpack.config.js
  • webpack.dev.config.js
  • webpack.prod.config.js

webpack.config.js文件内容

module.exports = (env) => {
    if (env && env.NODE_ENV === 'production') {
        return require('./webpack.prod.config.js');
    } else {
        return require('./webpack.dev.config.js');
    }
};

webpack.dev.config.js文件内容

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

module.exports = {
    mode: 'development',
    entry: './src/app.js',
    output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.(le|c)ss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'less-loader', options: {
                            javascriptEnabled: true
                        }
                    }
                ]
            }
        ]
    },
    devServer: {
        contentBase: './dist',
        port: 8888
    },
    plugins: [
        new htmlWebpackPlugin({
            template: 'public/index.html'
        })
    ]
};

webpack.prod.config.js文件内容

const path = require('path');

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.(le|c)ss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'less-loader', options: {
                            javascriptEnabled: true
                        }
                    }
                ]
            }
        ]
    }
};

6. 创建开发目录src和静态资源目录public

  • public
    index.html
  • src
    • components
      • button
        • index.js
        • style
          • index.less
    • style
      • themes
        default.less
    • app.js #这个是开发环境的入口
    • index.js #这个是生产环境打包的入口

7. 文件内容(只是例子)

public/index.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>模板htmltitle>
    <style>
        html,body,#app {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            border: 0;
        }
    style>
head>
<body>
    <div id="app">div>
body>
html>

src/components/button/index.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './style/index.less';

class Button extends Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (<button {...this.props} className='my-btn-style'><span>{this.props.children}</span></button>);
    }
}

Button.propTypes = {};

export default Button; //这里必须export default导出

src/components/button/style/index.less

.my-btn-style {
    color: red
}

src/style
这个文件夹下的内容都是公用的样式,不做详细介绍

src/app.js

import React from 'react';
import ReactDOM from 'react-dom';

// 自定义的组件
import Button from './components/button/index';

class App extends React.Component {

    render() {
        return (<div><Button title='这是按钮的提示'>这是一个按钮</Button></div>);
    }

}

ReactDOM.render(<App />, document.getElementById('app')); //app即为挂载点,在模板html中。

src/index.js

import Button from './components/button/index';

export { Button };

开发&发布

启动和编译

启动

npm start

编译

npm run build

发布至npm仓库

在进行以下操作步骤之前请先注册npm账号,点击npm官网注册。(在项目根目录下进行)

  • 首先需要切换npm源(如果使用了taobao的镜像)
npm config set registry http://registry.npmjs.org
  • 然后设置package.json中的version版本号,如:0.1.1
  • 添加npm账号,根据提示完成信息输入
npm adduser
  • 推至npm仓库
npm publish

至此已经完成了基本npm包的开发与发布,就可以在其他项目中使用npm install就可以了。

如何使用?

npm install example-ui -S

// 在项目中
import { Button } from 'example-ui';

其他

使用eslint语法检查

npm install eslint eslint-loader eslint-plugin-react eslint-friendly-formatter --save-dev

安装完依赖之后,根目录下新建.eslintrc.json文件,下面是我的配置,更多规则详见eslint官网。

{
    "parserOptions": {
        "ecmaVersion": 6,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        }
    },
    "env": {
        "es6": true,
        "browser": true,
        "node": true
    },
    "rules": {
        "no-debugger": "error",
        "linebreak-style": [
            "error",
            "unix"
        ],
        "semi": [
            "error",
            "always"
        ],
        "comma-dangle": [
            "error",
            "never"
        ],
        "no-cond-assign": [
            "error",
            "always"
        ]
    }
}

webpack.dev.config.js中的module--->rules中添加规则:

module:{
    rules:[
        {
            test: /\.(js|jsx)$/,
            loader: 'eslint-loader',
            enforce: 'pre',
            include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'test')],
            options: {
                formatter: require('eslint-friendly-formatter')
            }
        }
    ]
}

对图片、字体等的路径进行处理

npm install url-loader file-loader -save-dev

在webpack配置文件中添加规则,同上eslint配置,rules中加入:

{
    test: /\.(jpg|jpeg|git|png|svg|bmp)$/,
    use: [{
        loader: 'url-loader',
        options: {
            limit: 10000,
            name: 'images/[name]-[hash:8].[ext]'
        }
    }]
},
{
    test: /\.(ttf|svg|eot|woff|woff2)$/,
    use: [{
        loader: 'url-loader',
        options: {
            name: 'fonts/[name]-[hash:8].[ext]'
        }
    }]
}

至此,开发完整的React UI组件并发布至npm的教程已结束,如有疑问或可改进的请留言。

你可能感兴趣的:(前端,教程)