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...

  • 相关阅读:
    Infopath Notify 弹出提示信息
    window.showModalDialog 返回值
    【转】获得正文内容中的所有img标签的图片路径
    Json Datable Convert
    Sharepoint 列表 附件 小功能
    Surgey 权限更改
    SQL 触发器用于IP记录转换
    Caml语句 查询分配给当前用户及当前组
    jquery 1.3.2 auto referenced when new web application in VSTS2010(DEV10)
    TFS diff/merge configuration
  • 原文地址:https://www.cnblogs.com/liujiacai/p/11202095.html
Copyright © 2011-2022 走看看