zoukankan      html  css  js  c++  java
  • (转)react 项目构建

    原文:https://segmentfault.com/a/1190000016342792

    写在前面

    每次构建react项目的时候都会配置一大堆东西,时间久了就会忘记怎么配置。为了方便自己记忆也为了其他开发者在构建react应用时能够快速开发,故作此记录。

    本项目基于 create-react-app 脚手架进行配置。主要配置了一些项目开发中常用的方法,比如 webpack的 sassredux热加载代理以及其他工具库的引入等等。

    初始化项目

    首先,要先利用create-react-app创建一个react项目,可参考 https://github.com/facebookin...

    安装 create-react-app

    npm install -g create-react-app

    创建一个应用程序

    create-react-app my-app
    cd my-app

    注:my-app是指项目的名称,用户可以自定义项目名称

    这个时候可以在命令行输入

    npm start : 启动项目就能看到项目启动页面了。

    图片描述

    npm run build : 项目发布。

    这样一个简单的react项目就初始化完毕了。

    但是,默认所有配置是隐藏起来的,要想自定义配置,需要运行一个命令:npm run eject
    此时会提示,该命令不可逆,是否继续,输入y,这样所有配置项就都出来了。会生成一个config文件夹,这时候也可以做一些定制化的配置了。

    项目配置

    兼容IE

    引入element-react UI框架会报错 ReferenceError: “Symbol”未定义

    • 解决方案:

    项目中引入babel-polyfill,在app.js中导入即可

    配置webpack

    基于webpack的一些配置

    配置sass

    脚手架默认没有配置sass,项目中如果使用sass需要单独配置

    1、安装依赖 npm install --save-d node-sass sass-loader
    2、修改config下面的webpack.config.dev.jswebpack.config.prod.js,都需要修改,开发环境和发布环境是单独的配置。

    修改cssloader
    test: /.css$/, 修改为: test: /.(css|scss|sass)$/,即识别scss/sass文件

    最后添加
    sass-loader

    图片描述

    配置别名

    别名在项目中方便我们快速引入文件。比如我们项目中有一个公共文件目录为src/util/tools,例如有以下文件结构

    ├── src                                   
    │   ├── assets                            # 项目资源
    │   │   └── ...
    │   ├── containers                        # 页面容器
    │   │   └── pages
    │   │       └── pageA                     # 页面A     
    │   │           └───a.js                  # a.js           
    │   │── utils                             # 其他工具类
    │   │   └── tools
    │   ├── index.js                          # webpack打包入口文件
    

    在层级很深的组件内部a.js需要引入tools文件,我们会使用../../../util/tools去找到文件的相对位置,但是在使用webpack配置的别名后可以直接定位到/src目录下。

    // 未使用别名
    import tools from '../../../util/tools';
    
    // 使用别名后
    import tools from '@/util/tools';  // '@/' 指向 'src/'

    配置方式

    dev和prod环境都需要配置

    在resolve/alias进行配置

    其中 resolve 是一个自定义函数。

    function resolve(dir) {
        return path.join(__dirname, '..', dir)
    }

    也可以写成

    '@': path.join(__dirname, '..', 'src')

    图片描述

    配置热加载

    create-react-app项目中配置的有热加载,我们只需要在项目入口文件index.js中启用热加载就行,直接在末尾添加

    // index.js
    /* 热加载 */
    if (module.hot) {
      module.hot.accept();
    }

    图片描述

    配置代理服务器

    在前端开发中请求接口经常会遇到跨域的问题,处理跨域的方式有很多,多数webpack是配置dev_server,但这种方法在create-react-app 生成的应用中无效,对于这种应用应在package.json处进行代理

    // package.json
    "proxy": "http://api.enjoycut.com/"
    
    // 或者
    "proxy": {
        "/article": {
          "target": "http://api.enjoycut.com/",
          "changeOrigin": true,
          "secure": false
        }
      }
    // 下面的方式没有配置过

    配置路由

    react-router4的使用方式和以前的router版本使用方式不同

    react-router4文档地址

    配置redux

    配置 @connect装饰器

    在项目中可以直接通过@connect方式访问redux

    未配置
    图片描述

    配置后

    图片描述

    需要说明的是,这里用了装饰器,需要安装模块babel-plugin-transform-decorators-legacy

    然后在package.json里面配置plugins

    图片描述

    项目中其他工具配置

    classnames

    在react 中切换className比较麻烦,简单的可以使用三目运算,但是复杂一点的class就比较麻烦了,比如这个稍微复杂点的div动态切换多个className, 推荐一个工具库,可以简单方便的切换className.

    clsssnames使用文档

    图片描述

          <div className={classNames('clip_item', {
          'clip_active': isActive, 
          'effect_hover': activeDrag === 'video_inner',
           'dragging': is_dragging}
           )}>
          // 默认classNAme: 'clip_item'
          // isActive    === true 则添加className 'clip_active'
          // is_dragging === true 则添加className 'dragging'

    moment

    在项目中格式化时间的工具库,将时间格式化成你想要的任何格式!非常方便。

    moment().format('MMMM Do YYYY, h:mm:ss a'); // 九月 10日 2018, 7:04:30 晚上
    moment().format('dddd');                    // 星期一
    moment().format("MMM Do YY");               // 9月 10日 18
    moment().format('YYYY [escaped] YYYY');     // 2018 escaped 2018
    moment().format();                          // 2018-09-10T19:04:30+08:00

    moment.js文档地址:http://momentjs.cn/


    项目后期优化

    antd按需加载

    一般情况下,我们按照antd官网使用方式在css中导入整个ui的样式,@import '~antd/dist/antd.css';
    比如我们在项目中只使用了Button,和Table,但是这样实际上加载了全部的 antd 组件的样式(对前端性能是个隐患);
    因此我们需要使用按需加载,只加载我们使用过得组件样式。

    注意:如果是运行了eject ,webpack配置了babelrc: false ,单独根目录新建.babelrc会报错的,需要在webpack.dev.js配置,在module模块 ,loader: require.resolve('babel-loader')对象中的plugins数组中添加

    这里只展示允许eject暴露了webpack配置文件的配置方式,未暴露webpack配置方式请参考https://segmentfault.com/a/11...

    1. 安装babel-plugin-import

      npm install --save-dev babel-plugin-import

    2. 给 webpack 的 babel-loader plugins 加上 babel-plugin-import

    需要修改两个文件 /config/webpack.config.prod.js 和 /config/webpack.config.dev.js (修改的内容一样,升级后的create-react-app合并为一个文件 webpack.config.js)找到加载 babel-loader 的地方,往他的 plugins 加入如下代码

    [
        require.resolve('babel-plugin-import'),// 导入 import 插件
        {
          libraryName: 'antd',   //暴露antd
          style: 'css'
        }
      ]
    

    最后形成的配置如下(create-react-app 版本不同最后的配置可能不一样,原理一样):

       // Process application JS with Babel.
        // The preset includes JSX, Flow, TypeScript, and some ESnext features.
        {
          test: /.(js|mjs|jsx|ts|tsx)$/,
          include: paths.appSrc,
          loader: require.resolve('babel-loader'),
          options: {
            customize: require.resolve(
              'babel-preset-react-app/webpack-overrides'
            ),
            
            plugins: [
              [
                require.resolve('babel-plugin-named-asset-import'),
                {
                  loaderMap: {
                    svg: {
                      ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
                    },
                  },
                },
              ],
              // antd按需加载
              [
                require.resolve('babel-plugin-import'),// 导入 import 插件
                {
                  libraryName: 'antd',   //暴露antd
                  style: 'css'
                }
              ],
            ],
            // This is a feature of `babel-loader` for webpack (not Babel itself).
            // It enables caching results in ./node_modules/.cache/babel-loader/
            // directory for faster rebuilds.
            cacheDirectory: true,
            cacheCompression: isEnvProduction,
            compact: isEnvProduction,
          },
        },

    代码分隔(react-loadable)

    一个动态导入加载组件的高阶组件.

    未使用前

    import Home from'./Home';

    使用后

    import loadable from '@/utils/loadable'
    const Home = loadable(() => import('./Home '));

    loadable组件

    import React from 'react';
    import Loadable from 'react-loadable';
    
    //通用的过场组件
    const loadingComponent =()=>{
      return (
        <div></div>
      )
    };
    
    //过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
    export default (loader,loading = loadingComponent)=>{
      return Loadable({
        loader,
        loading
      });
    }

    参考链接

    预渲染配置 (Prerender SPA Plugin)

    构建阶段生成匹配预渲染路径的 html 文件(注意:每个需要预渲染的路由都有一个对应的 html)。构建出来的 html 文件已有部分内容。

    如果在项目中同时使用代码分隔预加载会导致页面闪屏。原因是会先加载预加载打包出来的html,渲染静态页面,然后会请求代码分隔后该页面的js。会导致html的root节点再次挂载。因此不推荐使用预加载的同时使用代码分隔。

    配置方式

    1.npm install prerender-spa-plugin

    2.找到 /config/webpack.config.prod.js文件

    const path = require('path')
    const PrerenderSPAPlugin = require('prerender-spa-plugin')
    
    module.exports = {
      plugins: [
        ...
        new PrerenderSPAPlugin({
          // Required - The path to the webpack-outputted app to prerender.
          staticDir: path.join(__dirname, '../build'),
          // Required - Routes to render.
          routes: ['/home', '/convert', '/trim', '/merge', '/watermark', '/remove', '/download'],
        })
      ]
    }
    

    3.如需添加路由则在 routes 里面添加,同时需要后端更改ngnix配置

    / -> home/index.html
    /home -> home/index.html
    /convert -> convert/index.html
    /trim -> trim/index.html
    /merge -> merge/index.html
    /watermark -> watermark/index.html
    /remove -> remove/index.html
    /download -> download/index.html
    
    除了上面的路径,其他路径全部指向 index.html
    

    单页应用多路由预渲染指南 https://juejin.im/post/59d49d976fb9a00a571d651d
    使用说明 https://github.com/chrisvfritz/prerender-spa-plugin


    源码

    为方便快速构建项目,本例所有配置的代码均放在github项目中。
    https://github.com/zhaosheng8...

  • 相关阅读:
    VS Code的常用备忘
    Echarts圆环,初始化时进度条效果
    nodejs 复制文件到 另一路径下 。可以在npm库看下mv 和 mvdir 有一点区别
    nginx启动报错(1113: No mapping for the Unicode character exists in the target multi-byte code page
    Echarts dataZome 横向移动动态显示数据
    flex布局时,会有兼容性问题,所以能少用flex布局的地方还是要避免下
    python 搭建 flask 和 orator框架开发
    直播 小测试
    对高并发的理解
    MySQL 中文分词原理
  • 原文地址:https://www.cnblogs.com/liujiacai/p/11202095.html
Copyright © 2011-2022 走看看