React16 + Webpack4 + Babel7 开发环境搭建


前置安装

点我返回目录

安装 cnpm

npm install cnpm -g --registry=https://registry.npm.taobao.org

安装 yarn

cnpm install -g yarn

初始化项目

生成 package.jsom

点我返回目录

npm init -y

创建项目目录

点我返回目录

项目根目录
├── assets //存放静态资源
│   ├── css //存放css
│   └── images //存放图片
├── public //存放html模板
├── src //代码
│   ├── common //公用类库
│   ├── components //组件 Dumb组件
│   │   ├── PostList //组件目录
│   │   │   └── index.js //采用 Saga 获取数据
│   │   ├── UserList //组件目录
│   │   │   └── index.js //采用 Thunk 获取数据
│   │   └── index.js //App.js 路由组件
│   ├── constant 公用常量
│   │   ├── actionTypes.js
│   │   └── url.js
│   └── redux
│       ├── reducer
│       └── sagas
└── package.json

在public目录下新建 index.html

点我返回目录

填入以下内容

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<!-- 移动端全屏 -->
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0" />
	<meta name="theme-color" content="#000000" />
	<!-- 防止页面缓存 -->
	<meta http-equiv="Pragma" content="no-cache">
	<meta http-equiv="Cache-Control" content="no-cache">
	<meta http-equiv="Expires" content="0">
	<title>React Demo</title>
</head>
<body>
	<div id="root"></div>
</body>
</html>

在src目录下新建 index.js

点我返回目录

填入以下内容

'use strict';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components';

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

在 src/components 目录下新建 home.js

点我返回目录

填入以下内容

import React from 'react';

function App() {
	return (<div>Hello, World!</div>)
}

export default App;

修改 package.jsom

点我返回目录

scripts 下填入以下内容

"scripts": {
	"build": "webpack --mode=production",
	"start": "webpack-dev-server --open --mode=development"
}

基础环境搭建

安装 Babel 7

点我返回目录

包名 说明
@babel/core Bable核心包
@babel/preset-env 根据配置的目标浏览器或运行环境,自动的将代码转为es5
@babel/preset-react 支持React
@babel/polyfill 支持新的(ES6+)API

安装

cnpm i -D @babel/core @babel/preset-env @babel/preset-react
cnpm i -S @babel/polyfill

新建配置 .babelrc.js

点我返回目录

const presets = ["@babel/preset-env","@babel/preset-react"];
const plugins = [];

module.exports = { presets, plugins };

安装 Webpack 4

点我返回目录

包名 说明
webpack webpack主包
webpack-cli 支持命令行
babel-loader 加载babel
style-loader 将处理结束的css代码存储在js中,运行时嵌入<style>后挂载到html页面上
css-loader 使webpack可以识别css文件
clean-webpack-plugin 清除之前的打包文件
html-webpack-plugin 支持html
webpack-dev-server 开发服务器

loader的加载顺序是从右往左,从下往上

安装

//安装 webpack
cnpm i -D webpack webpack-cli
//安装loader
cnpm i -D babel-loader style-loader css-loader 
//安装 插件
cnpm i -D clean-webpack-plugin html-webpack-plugin webpack-dev-server

配置 webpack.config.js

点我返回目录

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

const ENTRYPATH = path.resolve(__dirname, './src/index.js');
const OUTPUTPATH = path.resolve(__dirname, './dist');

module.exports = {
	//入口
	entry: ENTRYPATH,
	//出口
	output: {
		filename: "bundle.js",
		path: OUTPUTPATH,
	},
	//加载器
	module: {
		rules: [
			{
				test: /\.js|jsx$/,
				exclude: /node_modules/,
				loader: 'babel-loader'
			},
			{
				test: /\.css$/,
				use: ['style-loader', 'css-loader']
			}
		]
	},
	plugins: [
		new CleanWebpackPlugin(),
		new HtmlWebpackPlugin({
			minify: { // 压缩HTML文件
				removeComments: true, // 移除HTML中的注释
				collapseWhitespace: true, // 删除空白符与换行符
				minifyCSS: true// 压缩内联css
			},
			template: './public/index.html',
			filename: './index.html',
			hash: true,
			showErrors: true,
		})
	],
	devServer: {
		contentBase: OUTPUTPATH,
		historyApiFallback: true, // 该选项的作用所有的404都连接到index.html
		compress:true //压缩
	}
}

安装 Reactjs 16

点我返回目录

包名 说明
react react主包
react-dom react支持dom
cnpm i -S react react-dom

调试/构建项目

点我返回目录

npm run start //调试项目
npm run build //构建项目

//或者
yarn start
yarn build

开发环境搭建

让 webpack-dev-server 支持热更新

点我返回目录

安装

cnpm i -D react-hot-loader

使用

  1. 修改 /src/components/index.js
import { hot } from 'react-hot-loader/root'; //引入hot
const App = () => <div>Hello World!</div>; //根组件
export default hot(App); //包裹根组件
  1. 修改 .babelrc.js
const plugins = ["react-hot-loader/babel"];
  1. 修改 package.json -> scripts 添加 --hot
"start": "webpack-dev-server --open --hot --mode=development"
  1. 执行 yarn start

ESLint 代码校验

点我返回目录

包名 说明
eslint 包体
eslint-loader webpack加载器
eslint-plugin-html 用于检查在写在 script 标签中的代码
eslint-friendly-formatter 规定报错时输入的信息格式
eslint-plugin-react 用于React的ESLint规则

安装

cnpm i -D eslint eslint-loader eslint-friendly-formatter eslint-plugin-html eslint-plugin-react

使用

  1. 在console中执行命令,生成 .eslintrc.js
//window
node_modules\.bin\eslint --init

您想如何使用ESLint?
? How would you like to use ESLint? (Use arrow keys)
> To check syntax, find problems, and enforce code style

您的项目使用什么类型的模块?
? What type of modules does your project use? (Use arrow keys)
> JavaScript modules (import/export)

您的项目使用哪个框架?
? Which framework does your project use? (Use arrow keys)
> React

你的代码在哪里运行?(按<space>选择,<a>切换所有,<i>反转选择)
? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Browser

您想如何为您的项目定义一个样式?
? How would you like to define a style for your project? (Use arrow keys)
> Answer questions about your style
> JavaScript
> Tabs
> Single 
> Unix
y
  1. 修改 .eslintrc.js
"extends": ["eslint:recommended", "plugin:react/recommended"],
//清空rules
'rules': { }
  1. 修改 webpack.config.js -> module -> rules
{
	test: /\.js|jsx$/,
	loader: 'eslint-loader',
	enforce: "pre", // 编译前检查
	exclude: /node_modules/, // 不检测的文件
	include: [path.resolve(__dirname, 'src')], // 指定检查的目录
	options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine 
		formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范
	}
}

CSS 引用图片

点我返回目录

包名 说明
file-loader 可以解析项目中的url引入(不仅限于css)
url-loader Loads files as base64 encoded URL

安装

cnpm i -D file-loader url-loader

使用
修改 webpack.config.js -> module -> rules 下添加

{
	test: /\.(png|jpg|gif|svg)$/,
	use: [
		{
			loader: 'url-loader',
			options: {
				name: 'assets/[name]-[hash:5].[ext]',
				limit: 8192 //超过限制会使用file-loader
			}
		}
	]
}

CSS 分离打包

点我返回目录

包名 说明
extract-css-chunks-webpack-plugin 分离css
mini-css-extract-plugin 分离css
  • extract-css-chunks-webpack-plugin
    安装
    cnpm i -D extract-css-chunks-webpack-plugin
    
    修改 webpack.config.js
    //引入
    const ExtractCssChunks = require("extract-css-chunks-webpack-plugin");
    //module -> rules -> css里将 style-loader 替换为
    {
    	loader: ExtractCssChunks.loader,
    	options: {
    		hot: true, // if you want HMR
    		reloadAll: true, // when desperation kicks in - this is a brute force HMR flag
    	}
    }
    //plugins 里添加
    new ExtractCssChunks(
    	{
    		filename: "[name].css",
    		chunkFilename: "[id].css",
    		orderWarning: true,
    	}
    )
    
  • mini-css-extract-plugin
    安装
    cnpm i -D mini-css-extract-plugin
    
    修改 webpack.config.js
    //引入
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    //module -> rules -> css里将 style-loader 替换为
    {
        loader: MiniCssExtractPlugin.loader,
        options: {
            // you can specify a publicPath here
            // by default it uses publicPath in webpackOptions.output
            publicPath: '../',
            hmr: process.env.NODE_ENV === 'development',
        },
    },
    //plugins 里添加
    new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // all options are optional
        filename: '[name].css',
        chunkFilename: '[id].css',
        ignoreOrder: false, // Enable to remove warnings about conflicting order
    }),
    

PostCSS 处理 CSS 压缩去重自动前缀转换

点我返回目录

包名 说明
postcss-loader 加载器
precss 转换现代CSS,
包含postcss-preset-env
包含Autoprefixer 自动前缀
cssnano css 优化处理器,压缩去重
postcss-import 让 css 不支持 http 等远程的 URL 链接的处理
postcss-scss 支持现代css语法

postcss-normalize|Use the parts of normalize.css (or sanitize.css) you need from your browserslist

sass-loader|加载器,使webpack可以识别sass/scss文件,默认使用node-sass进行编译,

安装

cnpm i -D postcss-loader precss cssnano postcss-import postcss-scss

新建 postcss.config.js 填入以下内容

const precss = require('precss');

module.exports = {
	loader: 'postcss-loader',
	parser: 'postcss-scss',
	plugins: [
		precss(),
		require('postcss-import'),
		require('cssnano')({
			preset: ['default', { discardComments: { removeAll: true } }]
		})
	]
}

修改 webpack.config.js -> module -> rules

{
	test: /\.css$/,
	use: [
		'style-loader',
		{ loader: 'css-loader', options: { importLoaders: 1 }},
		'postcss-loader'
	]
}

在vscode里按下ctrl + ,;搜索设置 files.associations,填入以下代码

"files.associations": {
  "*.css": "scss"
}

JS 压缩

点我返回目录

  • uglifyjs-webpack-plugin:用来对js文件进行压缩,从而减小js文件的大小,加速load速度
cnpm i -D uglifyjs-webpack-plugin

使用 webpack.config.js

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
//...
{
    plugins: [
    	new UglifyJSPlugin({
    		sourceMap: true //支持devtools
    	})
    ]
}

JS 按需加载

  • webpack-bundle-analyzer,
    这个插件会清晰的展示出打包后的各个bundle所依赖的模块:
    npm i webpack-bundle-analyzer -D
    
    引入:
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    
    使用,在plugins数组中添加即可:
    new BundleAnalyzerPlugin()
    
  • require.ensure()
    webpack 的遗留功能
    // 空参数
    require.ensure([], function(require){
        var = require('module-b');
    });
    
    // 依赖模块 "module-a", "module-b",会和'module-c'打包成一个chunk来加载
    // 不同的分割点可以使用同一个chunkname,这样可以保证不同分割点的代码模块打包为一个chunk
    require.ensure(["module-a", "module-b"], function(require) {
        var a = require("module-a");
        var b = require("module-b");
        var c = require('module-c');
    },"custom-chunk-name");
    
  • import()
    import("./module").then(module => {
        return module.default;
    }).catch(err => {
        console.log("Chunk loading failed");
    });
    
    import() 会针对每一个读取到的module创建独立的chunk。
    function route(path, query) {
      return import(`./routes/${path}/route`)
        .then(route => new route.Route(query));
    }
    
  • bundle-loader
    用于分离代码和延迟加载生成的 bundle
    // 在require bundle时,浏览器会立即加载
    var waitForChunk = require("bundle!./file.js");
     
    // 使用lazy模式,浏览器并不立即加载,只在调用wrapper函数才加载
    var waitForChunk = require("bundle?lazy!./file.js");
     
    // 等待加载,在回调中使用
    waitForChunk(function(file) {
        var file = require("./file.js");
    });
    
    默认普通模式wrapper:
    var cbs = [],data;
    module.exports = function(cb) {
        if(cbs) cbs.push(cb);
        else cb(data);
    },
    require.ensure([], function(require) {
        data = require('./file.js');
        var callbacks = cbs;
        cbs = null;
        for(var i = 0, l = callbacks.length; i < l; i++) {
            callbacks[i](data);
          }
    });
    
    lazy模式wrapper:
    module.exports = function (cb) {
      require.ensure([], function(require) {
        var app = require('./file.js');
        cb(app);
      });
    };
    
    使用bundle-loader在代码中require文件的时候只是引入了wrapper函数,而且因为每个文件都会产生一个分离点,导致产生了多个打包文件,而打包文件的载入只有在条件命中的情况下才产生,也就可以按需加载。
    • 支持自定义Chunk名称:
      require("bundle-loader?lazy&name=my-chunk!./file.js");
      
  • promise-loader
    类似于 bundle-loader ,但是使用了 promise API
    // 使用Bluebird promise库
    var load = require("promise?bluebird!./file.js");
    
    // 使用全局Promise对象
    var load = require("promise?global!./file.js");
    
    load().then(function(file) {
    
    });
    
    wrapper函数:
    var Promise = require('bluebird');
    
    module.exports = function (namespace) {
      return new Promise(function (resolve) {
        require.ensure([], function (require) {
          resolve(require('./file.js')[namespace]));
        });
      });
    }
    

js公共资源分割

点我返回目录

wepack4采用了runtimeChunkPlugin,可以将每个entry chunk中的runtime部分的函数分离出来,只需要一个简单的配置

  runtimeChunk: "single"
  // 等价于
  runtimeChunk: {
    name: 'minifest'
  }

css资源分割

点我返回目录

按模块加载

点我返回目录

按路由加载

点我返回目录
react-router的 标签有一个叫做getComponent的异步的方法去获取组件。他是一个function接受两个参数,分别是location和callback。当react-router执行回调函数 callback(null, ourComponent)时,路由只渲染指定组件ourComponent

  • getComponent异步方法
    <Router history={history}>
        <Route 
            path="/"
            getComponent={(nextState, callback) => {
                callback(null, HomePage)
            }}
        />
         <Route
            path="/faq"
            getComponent={(nextState, callback) => {
              callback(null, FAQPage);
            }}
        />
    </Router>
    

CSS-Module

点我返回目录

  • 修改 webpack.config.js
    module.exports = {
    	module: {
    		rules: [
    			{
    				test: /\.css$/,
    				exclude: /\.module\.css$/, //排除css模块
    				use: ['style-loader', 'css-loader']
    			},
    			{
    				test: /\.module\.css$/,
    				use: ['style-loader', {
    					loader: 'css-loader',
    					options: {
    						importLoaders: 1,
    						modules: {
    							localIdentName: '[path][name]__[local]--[hash:base64:5]'
    						},
    					}
    				}]
    			}
    		]
    	},
    }
    
  • 修改 home.js
    import React from 'react';
    import '../../assets/css/home.css';
    import css from '../../assets/css/test.module.css';
    
    function App() {
    	return (<div>
    		<ul>
    		    <!-- 全局css -->
    			<li className="global">Hello, World!</li>
    			<!-- 模块css -->
    			<li className={css.global}>I am Test!</li>
    		</ul>
    	</div>)
    }
    
    export default App;
    

SCSS/SASS/LESSe —— 暂时pass

点我返回目录

"node-sass": "^4.5.3",
"sass-loader": "^4.0.2",
"less": "^2.6.1",    
"less-loader": "^4.0.3",

生产环境 构建 —— 暂时pass

点我返回目录

包名 说明
webpack-merge 合并webpack配置

安装

cnpm i -D  webpack-merge

在webpack.common.conf.js

const path = require('path');
module.exports = {
    //...配置
});

在webpack.dev/prod.conf.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
    //...配置
});

webpack.common.js 公共配置

点我返回目录

// webpack.base.conf.js
'use strict'
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // 入口
    entry: {
        app: './src/index.js',
    },
    // 输出
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: "[name].js",
    },
    // 解析
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json','.jsx']
    },
    // loader
    module: {
        rules: [{
            test: /\.js|jsx$/,
            exclude: /node_modules/,// 屏蔽不需要处理的文件(文件夹)(可选)
            loader: 'babel-loader'
        },{
            test: /\.css$/,
            use: ['style-loader','css-loader']
        }]
    },
    // 插件
    plugins: [
        new HtmlWebpackPlugin({
            filename: './public/index.html',
            template: './public/index.html',
            inject: 'body'
        })
    ]
}

webpack.dev.js 开发配置

点我返回目录

//webpack.dev.conf.js
'use strict'
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');

const path = require('path');
const webpack = require('webpack');

module.exports = merge(baseWebpackConfig, {
    // 模式
    mode: "development",
    // 调试工具
    devtool: 'inline-source-map',
    // 开发服务器
    devServer: {
        contentBase: false,// 默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录
        historyApiFallback: true,// 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
        compress: true,// 启用gzip压缩
        inline: true,// 设置为true,当源文件改变时会自动刷新页面
        hot: true,// 模块热更新,取决于HotModuleReplacementPlugin
        host: '127.0.0.1',// 设置默认监听域名,如果省略,默认为“localhost”
        port: 8703// 设置默认监听端口,如果省略,默认为“8080”
    },
    // 插件
    plugins: [
        // 热更新相关
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    optimization: {
        nodeEnv: 'development',
    }
});

webpack.prod.js 生产配置

点我返回目录

//webpack.prod.conf.js
'use strict'
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');

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

module.exports = merge(baseWebpackConfig, {
    // 模式
    mode: "production",
    // 调试工具
    devtool: '#source-map',
    // 输出
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: "js/[name].[chunkhash].js",
    },
    // 插件
    plugins: [
        new CleanWebpackPlugin(),
        new webpack.HashedModuleIdsPlugin(),
    ],
    // 代码分离相关
    optimization: {
        nodeEnv: 'production',
        runtimeChunk: {
            name: 'manifest'
        },
        splitChunks: {
            minSize: 30000,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            name: false,
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendor',
                    chunks: 'initial',
                }
            }
        }
    }
});

功能第三方库

点我返回目录

时间处理 moment.js

npm install moment --save

CSS 相关

点我返回目录

包名 说明
flex.css 支持flex布局
normalize.css 在默认的HTML元素样式上提供了跨浏览器的高度一致性

异步加载组件 跳过

react-loadable
SplitChunksPlugin

http请求 跳过

点我返回目录

"axios": "^0.16.2", //http请求

视频播放

点我返回目录

包名 说明
video.js 视频播放库
videojs-flash rtmp需要flash播放

安装

cnpm i -S video.js videojs-flash

使用

import React, { Component } from 'react';
import Videojs from 'video.js';
require('!style-loader!css-loader!video.js/dist/video-js.css');
//import "video.js/dist/video-js.css";
import VideojsFlash from "videojs-flash";

class Video extends Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    componentDidMount() {
        this.cfg = {
            autoplay: true,
            controls: true,
            sources: [{
                // rtmp 格式流
                'src': "rtmp://202.69.69.180:443/webcast/bshdlive-pc",
                'type': 'rtmp/flv'

                // hls 格式流
                // 'src': "http://localhost:8000/live/1/index.m3u8",
                // 'type': 'application/x-mpegURL'
            }]
        };
        this.player = Videojs(this.videoNode, this.cfg, function onPlayerReady() {
            console.log('onPlayerReady', this);
        });
    }
    componentWillUnmount() {
        if (this.player) {
            this.player.dispose();
        }
    }
    render() {
        return (
            <div className="Video">
                <div data-vjs-player>
                    <video ref={node => this.videoNode = node} className="video-js Video-Player"></video>
                </div>
            </div>
        );
    }
}

export default Video;

修改 webpack.config.js module -> rules

{
	test: /\.(woff|woff2|eot|ttf)$/,
	loader: 'url-loader?limit=100000',
}

UI第三方库

轮播图支持

点我返回目录

安装

cnpm i -S swiper

使用 参考swiper中文网

import React, { Component } from 'react';
import Swiper from 'swiper/dist/js/swiper.js';
import 'swiper/dist/css/swiper.min.css';

class Banner extends Component {
    constructor(props) {
        super(props);
        this.state = { list: ['1', '2', '3', '4'] };
    }
    componentDidMount() {
        var mySwiper = new Swiper('.swiper-container', {
            effect : 'cube',
            direction: 'horizontal', // 水平切换选项
            autoplay: true,
            loop: true,
            speed: 300,
            pagination: {
                el: '.swiper-pagination',
                clickable: true,
            }
            on: {
				click: function (e) {

				},
				touchEnd: function(e){
					e.activeLoopIndex //循环索引
					e.activeIndex //非循环索引
				}
			},
        })
    }

    render() {
        return (
            <div className="Banner">
                <div class="swiper-container">
                    <div class="swiper-wrapper">
                        <div class="swiper-slide">Slide 1</div>
                        <div class="swiper-slide">Slide 2</div>
                        <div class="swiper-slide">Slide 3</div>
                    </div>
                    <!-- 如果需要分页器 -->
                    <div class="swiper-pagination"></div>
                    <!-- 如果需要导航按钮 -->
                    <div class="swiper-button-prev"></div>
                    <div class="swiper-button-next"></div>
                    <!-- 如果需要滚动条 -->
                    <div class="swiper-scrollbar"></div>
                </div>
            </div>
        );
    }
}
export default Banner;

Ant Design

点我返回目录

安装

cnpm i -S antd
cnpm i -S antd-mobile

使用


Antd 官网


Antd mobile 官网

按需加载


babel-plugin-import: 在 Babel 配置中引入该插件,可以针对 antd, antd-mobile, lodash, material-ui等库进行按需加载.

cnpm i -D babel-plugin-import

修改 .babelrc.js

//在 plugins 中添加
[
	"import",
	{
		"libraryName": "antd",
		"libraryDirectory": "lib"
	},
	"ant"
],
[
    "import",
    {
        "libraryName": "antd-mobile",
        "libraryDirectory": "lib"
    },
    "antd-mobile"
]

Router/Rudux/Hooks

点我返回目录

安装 Router

点我返回目录

cnpm i -S react-router-dom

安装 Redux

点我返回目录

安装

cnpm i -S redux react-redux

redux-thunk 异步处理

点我返回目录

安装

cnpm i -S redux-thunk

redux-saga 异步处理

点我返回目录

安装

cnpm i -S redux-saga

安装插件

cnpm i -D  @babel/plugin-transform-runtime
//在转换 ES2015 语法为 ECMAScript 5 的语法时,babel 会需要一些辅助函数,例如 _extend。babel 默认会将这些辅助函数内联到每一个 js 文件里,这样文件多的时候,项目就会很大。
//所以 babel 提供了 transform-runtime 来将这些辅助函数“搬”到一个单独的模块 babel-runtime 中,这样做能减小项目文件的大小。

修改 .babelrc.js

//在 plugins 里添加 '@babel/plugin-transform-runtime'
const plugins = ["@babel/plugin-transform-runtime"];

redux-logger 日志工具

点我返回目录

安装

cnpm i -S redux-logger

Hooks

点我返回目录

安装

cnpm i -D eslint-plugin-react-hooks

修改 .eslintrc.js 在 rules 下填入

"plugins": [
	//...
	"react-hooks"
],
"rules": {
	"react-hooks/rules-of-hooks": "error",
	"react-hooks/exhaustive-deps": "warn"
},

数据唯一

点我返回目录

包名 说明
immutable 数据唯一
redux-immutable redux 数据唯一

安装

cnpm i -S immutable redux-immutable

使用 在 rules 下填入

// reducer.js下
import { fromJS } from 'immutable';
const defaultState = fromJS({
  list: false
})

import { combineReducers } from 'redux-immutable';

Other

    "es6-promise": "^4.1.0",
    "query-string": "^4.3.4",    
    "body-parser": "^1.15.1",
    "sugarss": "^1.0.0",
    "get-next-page": "1.0.0",
    "obj-merged": "^1.0.5",
yarn add webpack-bundle-analyzer //分析打包后的文件体积
yarn add compression-webpack-plugin //build生成gizp压缩文件
  1. webpack-bundle-analyzer 在yarn start后默认在浏览器localhost:8888可以查看打包分布图
  2. compression-webpack-plugin 在yarn build 可以直接在build文件夹中生成 .gz后缀的文件

npm install --save react-pullload

发布了33 篇原创文章 · 获赞 2 · 访问量 2015

猜你喜欢

转载自blog.csdn.net/wwwmewww/article/details/102557773