React16 + Webpack4 + Babel7 开发环境搭建


一、基础环境搭建

1. 创建项目

返回目录

$ mkdir example #创建项目目录
$ cd example #进入项目目录
$ npm init -y #生成 package.jsom

2. 项目目录结构(参考)

返回目录

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

3. 安装 React + Babel + Webpack

返回目录

  1. 需要安装的包
    包名说明环境
    reactreact 主程序生产
    react-dom让 react 支持 dom 操作生产
    react-router-dom路由dom操作生产
    @babel/coreBabel 核心包开发
    @babel/preset-env根据配置的目标浏览器或运行环境,自动的将代码转为es5开发
    @babel/preset-react支持React开发
    @babel/polyfill支持新的(ES6+)API生产
    webpackwebpack 主程序开发
    webpack-cli支持命令行开发
    webpack-dev-server开发服务器开发
    babel-loader用 babel 处理 js 或 jsx 文件开发
    css-loader使 webpack 可以识别 css 文件开发
    style-loader将处理完的 css 存在 js 中,运行时嵌入<style>挂载到 html 页面上开发
    html-webpack-plugin处理 html开发
    clean-webpack-plugin清除之前的打包文件开发
  2. 执行 npm 命令安装这些包
    #安装 React 主程序 dom操作    路由
    $ npm i -S react react-dom react-router-dom
    #安装babel
    $ npm i -D @babel/core @babel/preset-env @babel/preset-react
    $ npm i -S @babel/polyfill
    #安装webpack 主程序  支持命令行   本地开发用web服务
    $ npm i -D webpack webpack-cli webpack-dev-server 
    #安装webpack 加载器
    $ npm i -D babel-loader css-loader style-loader
    #安装webpack 插件
    $ npm i -D html-webpack-plugin clean-webpack-plugin
    

4. 开始写 React 代码

返回目录

  1. 新建 public/index.html,作为 “React 的 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">
    	<!-- 页面标题 html-webpack-plugin 插件替换 -->
    	<title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
    	<!-- React根节点 -->
    	<div id="root"></div>
    </body>
    </html>
    
  2. 新建 src/pages/home.js,作为本项目的首页
    import React from 'react'; //引入 react
    
    function Home() {
    	return (<div>Hello, World!</div>)
    }
    
    export default Home;
    
  3. 新建 src/main.js,作为 “React 的入口文件”。
    'use strict';
    import React from 'react'; //引入 react
    import ReactDOM from 'react-dom'; //引入 react-dom
    import Home from './pages/home'; //引入本项目的首页
    
    //把首页渲染到 html 模版的 react 根节点上
    ReactDOM.render(<Home />, document.getElementById('root'));
    

5. 配置 Babel 和 Webpack

  1. 新建配置 .babelrc.js
    const presets = ["@babel/preset-env","@babel/preset-react"];
    const plugins = [];
    
    module.exports = { presets, plugins };
    
  2. 新建配置 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: {
        main: ENTRYPATH        //入口路径
      },
      output: {
        filename: "bundle.js", //输出的文件名
        path: OUTPUTPATH,      //出口路径
      },
      module: { //配置加载器
        rules: [
          {
            test: /\.js|jsx$/, //匹配 js 文件
            exclude: /node_modules/, //排除文件夹
            use: [
              { loader: 'babel-loader' }, //使用babel
              {
                loader: 'eslint-loader', //使用 eslint
                options: {
                  enforce: 'pre', //在加载前执行
                  fix: true, //自动修复
                  include: [path.resolve(__dirname, 'src')], //指定检查的目录
                  formatter: require('eslint-friendly-formatter') //指定错误报告的格式规范
                }
              }
    		]
          },
          {
            test: /\.css$/, //匹配 css 文件
            use: ['style-loader', 'css-loader']
          }
        ]
      },
      plugins: [ //插件
      	new CleanWebpackPlugin(),
    	new HtmlWebpackPlugin({ //处理 html,配置多个会生成多个 html
    	  title: 'Example for React + Babel + Webpack', //html的标题
    	  filename: './index.html', //生成的 html 文件
    	  template: './public/index.html', //使用的 html 模版
    	  favicon: '',//html页面图标
    	  inject: "body", // script标签的未知,body,head,true(同body),false
    	  hash: true, //给js生成hash值
    	  showErrors: true, //显示错误信息
    	  minify: { // 压缩HTML文件
    	    minifyJS: true,  //压缩内联js
    	    minifyCSS: true, //压缩内联css
    	    removeComments: true, //移除HTML中的注释
    	    removeCommentsFromCDATA: true, //从脚本和样式删除的注释
            removeRedundantAttributes: true, //删除多余的属性
            collapseWhitespace: true, // 删除空白符与换行符
    	  }
        })
      ], 
      devServer: { //配置 webpack-dev-server
        contentBase: OUTPUTPATH,
        historyApiFallback: true, // 该选项的作用所有的404都连接到index.html
        compress:true //压缩
      }
    }
    

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

6. 调试/构建项目

返回目录

  1. 修改 package.jsom,在 “scripts” 下添加运行和构建命令
    {
      "scripts": {
        "build": "webpack --mode=production",
        "start": "webpack-dev-server --open --mode=development"
      }
    }
    
  2. 用 npm 执行脚本命令
    $ npm run start //调试项目
    $ npm run build //构建项目
    

二、开发环境搭建

1. 热更新

返回目录

  1. 要安装的包

    包名说明环境
    react-hot-loader让 react-dev-server 支持热更新开发
  2. 安装

    $ npm i -D react-hot-loader
    
  3. 修改 /src/pages/home.js

    import React from 'react';
    import { hot } from 'react-hot-loader/root'; //引入hot
    
    function Home() {
    	return (<div>Hello, World!</div>)
    }
    	
    export default hot(Home); //包裹根组件
    
  4. 修改 .babelrc.js

    const plugins = ["react-hot-loader/babel"];
    
  5. 修改 package.json -> scripts -> start 添加参数 --hot

    "start": "webpack-dev-server --open --hot --mode=development"
    
  6. 执行调试命令,改显示内容,不用再重新加载整个页面了

    $ npm start #同 npm run start
    

2. 代码校验 ESLint

返回目录

  1. 要安装的包
    包名说明环境
    eslint主程序开发
    eslint-loaderwebpack加载器开发
    eslint-plugin-html用于检查写在 script 标签中的代码开发
    eslint-friendly-formatter报错时输出的信息格式开发
    eslint-plugin-react用于React的ESLint规则开发
  2. 安装
    $ npm i -D eslint eslint-loader eslint-friendly-formatter eslint-plugin-html eslint-plugin-react
    
  3. 在命令行中执行 eslint 命令,生成 .eslintrc.js
    $ 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
    
    #您的项目使用 typescript 吗?
    ? Does your project use TypeScript? (y/N) > n
    
    #你的代码在哪里运行?(按<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 #自定义格式
    #代码格式化风格?
    ? What format do you want your config file to be in? > JavaScript
    #用tab还是空格
    ? What style of indentation do you use? > Spaces
    #字符串用单引号还是双引号?
    ? What quotes do you use for strings? > Single
    #行结束符
    ? What line endings do you use? > Unix
    #需要分号吗?
    ? Do you require semicolons? (Y/n) > y
    
  4. 修改 .eslintrc.js
    //在 env 里添加,
    'amd': true, //表示使用amd模块规范,支持 require
    'node': true, //支持node
    
  5. 修改 webpack.config.js -> module -> rules 参考
    {
      //...
      module: {  //加载器
        rules: [ //规则
          {
            test: /\.js|jsx$/,            //匹配文件
            exclude: /node_modules/,      //排除文件夹
            use: [
              { loader: 'babel-loader' }, // babel 加载器
              { loader: 'eslint-loader',  // eslint 加载器
                options: {                // eslint 选项
                  enforce: 'pre',         //在加载前执行
                  fix: true,              //自动修复
                  include: [path.resolve(__dirname, 'src')], //指定检查的目录
                  formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范
                }
              },
            ]
          },
          //其它 loader ...
        ]
      }
      //...
    }
    

3. JS

a. JS 压缩

返回目录

  1. 需要安装的包
    包名说明环境
    uglifyjs-webpack-plugin压缩js代码,加快 load 速度开发
  2. 安装
    $ npm i -D uglifyjs-webpack-plugin
    
  3. 修改 webpack.config.js
    const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
    //...
    {
        plugins: [
        	new UglifyJSPlugin({
        		sourceMap: true //支持devtools
        	})
        ]
    }
    

b. 第三方包

返回目录

包名说明环境
moment.js时间处理生产
axioshttp 请求生产
视频播放

返回目录

  1. 需要安装的包
    包名说明环境
    video.js视频播放库生产
    videojs-flashrtmp 需要 flash 播放生产
  2. 安装
    $ npm i -S video.js videojs-flash
    
  3. 使用
    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;
    
  4. 修改 webpack.config.js 中的 module -> rules
    {
      test: /\.(woff|woff2|eot|ttf)$/,
      loader: 'url-loader?limit=100000',
    }
    

4. CSS

a. CSS Module

返回目录

  1. 修改 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]'
    						},
    					}
    				}]
    			}
    		]
    	},
    }
    
  2. 修改 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;
    

b. 引用图片

返回目录

  1. 要安装的包
    包名说明环境
    file-loader解析 url 方法引入的文件(不限于css)开发
    url-loaderLoads files as base64 encoded URL开发
  2. 安装
    $ npm i -D file-loader url-loader
    
  3. 修改 webpack.config.js -> module -> rules 下添加
    { //在处理 “css” 的下面添加
      test: /\.(png|jpg|jpeg|gif|svg)$/,
      use: [
        { loader: 'url-loader',
          options: {
            outputPath: 'imgs/', //输出路径
            name: '[name]-[hash:5].[ext]', //文件名
            limit: 8192, //超过限制会使用file-loader
            esModule: false, //支持 require("imgUrl") 方式
          }
        }
      ]
    },//其他 laoder
    

c. 分离打包

返回目录

  1. 要安装的包
    包名说明环境
    extract-text-webpack-plugin分离css,支持webpack1/2/3开发
    mini-css-extract-plugin分离css,官方推荐,最近提交在2个月之前开发
    extract-css-chunks-webpack-plugin分离css,最近提交在4天前开发
mini-css-extract-plugin

返回目录

  1. 安装
    $ npm i -D mini-css-extract-plugin
    
  2. 修改 webpack.config.js
    const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //引入
    //module -> rules -> css里将 style-loader 替换为
    {
      loader: MiniCssExtractPlugin.loader,
      options: {
        publicPath: '../',
        hmr: process.env.NODE_ENV === 'development',
      },
    },
    //plugins 里添加
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
      ignoreOrder: false,
    }),
    
extract-css-chunks-webpack-plugin

返回目录

  1. 安装
    $ npm i -D extract-css-chunks-webpack-plugin
    
  2. 修改 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,
      }
    }
    //plugins 里添加
    new ExtractCssChunks({
      filename: "[name].css",
      chunkFilename: "[id].css",
      orderWarning: true,
    })
    

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

返回目录

  1. 要安装的包

    包名说明环境
    postcss-loaderwebpack 加载器开发
    precss支持现代 CSS 语法(SASS,SCSS)
    包含 postcss-preset-env 转换为浏览器识别的 CSS
    包含 Autoprefixer 自动添加(浏览器)前缀
    开发
    cssnanocss 优化处理,压缩去重开发
    postcss-scss解析 SCSS 语法开发
    postcss-calc在编译阶段进行计算开发
    postcss-import转换 @import 规则 用于内联内容开发
    postcss-normalize提取 normalize.css 中支持浏览器的部分(去重)开发
    postcss-plugin-px2rempx 转 rem开发
  2. 安装

    $ npm i -D postcss-loader precss cssnano postcss-import postcss-scss postcss-calc postcss-plugin-px2rem postcss-normalize normalize.css
    
  3. 新建 postcss.config.js 填入以下内容

    module.exports = ({ file, options, env }) => {
      parser: require('postcss-scss'),
      plugins: [
      	require('postcss-import'),
        require('postcss-normalize')({
          forceImport:true, //强制插入
          browsers: 'last 2 versions' //浏览器近2个版本
        }),
    	require('precss'), //支持“现代css”(Sass,Scss)语法,并转成 css
    	require('postcss-calc'), //编译前计算
    	require('postcss-plugin-px2rem')({ rootValue: 100, minPixelValue: 2 }), //px 转 rem
        require('cssnano')({preset: ['default', { discardComments: { removeAll: true } }]}) //压缩css,去除所有注释
    	]
    }
    
  4. 修改 webpack.config.js -> module -> rules

    {
    	test: /\.css$/,
    	use: [
    		'style-loader',
    		{ loader: 'css-loader', options: { importLoaders: 1 }},
    		'postcss-loader'
    	]
    }
    
  5. 在vscode里按下"ctrl + ,";搜索设置 files.associations,填入以下代码.
    关联 css 和 scss,可以略过

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

e. 第三方包

返回目录

包名说明环境
normalize.css标准 css,让各个浏览器的默认标签显示一致开发
flex.css让移动端浏览器支持 flex 布局生产

5. 按需加载「待整理」

返回目录

  1. 需要安装的包,可略过,需要时再安装。

    包名说明环境
    webpack-bundle-analyzer展示出打包后的各个bundle所依赖的模块开发
    react-loadable
    SplitChunksPlugin
  2. 安装

    $ npm i -D webpack-bundle-analyzer
    
  3. 修改 webpack.config.js

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin //引入
    //在 plugins 数组中添加即可
    new BundleAnalyzerPlugin()
    

a. 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");

b. 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));
}

c. 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");
    

d. 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的异步的方法去获取组件。他是一个functionn接受两个参数,分别是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>
    

三、生产环境 构建 —— 暂时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, {
    //...配置
});

1. 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'
        })
    ]
}

2. 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',
    }
});

3. 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',
                }
            }
        }
    }
});

四、UI库

1. 轮播图支持

返回目录

安装

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;

2. 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"
]

八、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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值