/react-env

webpack react

Primary LanguageJavaScript

react环境配置

tips

  1. 路由跳转时还改变组件的状态,使组件重新渲染。而使用redux时可以保持组件的状态。

遇到的问题

  1. 解析.jsx的配置
  2. fetch的兼容,whatwg-fetch
  3. autoprefixer
  4. jest测试

目录

环境初始化

  1. 需要安装node环境,使用node自带的npm或者使用cnpm(速度更快)来下载依赖包。
  2. 初始化npm,如果不加--y,你就需要填写项目的有关信息,直接连续按enter就行。
mkdir react-env
cd react-env
npm init --y 
  1. 既然是react的项目,那么就需要安装react相关的依赖,还需要使用webpack来构建项目。这里我使用的是cnpm,安装cnpm(npm install -g cnpm)。还需要说明一下,webpack最好安装在本项目中(即加上--save),如果进行全局安装,可能在后面打包时出现找不到依赖包的错误。
cnpm i --save react react-dom
cnpm i --save webpack

webpack的基本用法

  1. 安装babel-core,babel-preset-env,babel-preset-react
  1. 基本的webpack配置文件
const path = require('path');

module.exports = {

    /*入口*/
    entry: path.join(__dirname, 'src/index.js'),
    
    /*输出到dist文件夹,输出文件名字为bundle.js*/
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },

    /* 配置loader */
    module: {
      rules: [
        {
          test: /\.jsx?$/, //匹配的文件
          exclude: /node_modules/, //
          include: path.join(__dirname, 'src'),
          use: [
            {
              loader: 'babel-loader?cacheDirectory=true',
              // options: {
              //   presets: ['@babel/preset-env'],
              //   plugins: []
              // }
            }
          ]
        }
      ]
    }
};
  1. 在src中添加入口文件index.js和相关的组件页面
  2. 执行./node_modules/.bin/webpack --config webpack.config.dev.js,在dist文件夹中加上index.html作为模板容器就能查看了。
  3. 上一步执行的./node_modules/.bin/webpack是因为webpack是在在项目中安装的,如果全局安装就可以不加./node_modules/.bin/。为了简化命令可以在package.jsonscripts中加上"build-dev": "webpack --config webpack.config.dev.js"。接下来进行构建时可以直接用npm run build-dev

使用webpackDevServer

  1. 安装webpack-dev-server,webpackDevServer的基本配置,配置完成后运行./node_modules/.bin/webpack-dev-server --config webpack.config.dev.js --color --progress,同样也可以在package.json中简化命令
/* 开发使用的服务器 */
  devServer: {
    contentBase: path.join(__dirname,'./dist'),
    // after(app) {},
    // allowedHosts: [],
    // before(app) {},
    // clientLogLevel: "none",
    // compress: true,
    historyApiFallback: true,
    hot: true,
    // https: true,
    // index: index.html,
    // port: 7070,
    proxy: {
      context: ["/queryProducts"],
      target: "http://192.168.11.176:8080"
    }
  }
  1. webpack自带的模块热替换 - 用两种用法

    • 使用命令行webpack-dev-server --config webpack.config.dev.js --color --progress --hot,后面加了一个--hot
    • 使用配置文件webpack.config.dev.js
    const webpack = require('webpack')
    
    plugins: [
      new webpack.webpack.HotModuleReplacementPlugin()
    ]
    
    • 两种用法最后都要在index.js中加上
    if(module.hot) {
      module.hot.accept()
    }
    
  2. 使用react-hot-loader - webpack自带的模块热替换能够仅仅刷新改变的模块而不用刷新整个页面,但是不能保存react的state。react-hot-loader不仅能够实现热替换功能,同时也能够保存react的state - react-hot-loader的使用,使用前需要先开启webpack自带的模块热替换 ``` //webapck.config.dev.js entry: [ 'react-hot-loader/patch', path.join(__dirname, 'src/index.js') ]

//index.js
  import React from 'react'
  import { render } from 'react-dom'
  import { AppContainer } from 'react-hot-loader'

  import getRouter from './router/router.jsx'

  //webpack自带的模块热替换
  // if(module.hot) {
  //   module.hot.accept()
  // }

  //react-hot-loader
  const renderWithHotReload = ( RootElement ) => {
    render(
      <AppContainer>
        {RootElement}
      </AppContainer>
      ,
      document.querySelector('#app')
    )
  }

  //初始化
  renderWithHotReload(getRouter())
  /* 模块热替换 */
  if(module.hot) {
    module.hot.accept('./router/router.jsx', () => {
      const getRouter = require('./router/router.jsx').default
      renderWithHotReload(getRouter())
    })
  }
```

文件路径优化

resolve: {
  alias: {
    pages: path.join(__dirname, 'src/pages'),
    components: path.join(__dirname, 'src/components'),
    router: path.join(__dirname, 'src/router')
  }
}

添加redux

  • npm i --save redux react-redux

devtool优化

  • inline-source-map

编译css

  • style-loader, css-loader, postcss

编译图片

  • file-loader, url-loader

按需加载

  • 按路由进行按需加载
    • babel-loader,
    • react-loadable
  • 按功能进行按需加载

缓存

  //保证vendor的hash值不改变
  new webpack.HashedModuleIdsPlugin(),
  //保证vendor的hash值不改变,必须在vendor后面引用
  new webpack.optimize.CommonsChunkPlugin({
      name: 'runtime'
  })

index.html模板

  • html-webpack-plugin

提取公共代码

entry: {
  app: [
    'react-hot-loader/patch',
    path.join(__dirname, 'src/index.js')
  ],
  vender: ['react','react-dom','react-router-dom','redux','react-redux']
}

 new webpack.optimize.CommonsChunkPlugin({
    name: 'vender'
  })