记一次 react 15.3.1 老项目升级到 react 16.7.0 之路

互相交流学习,请加我微信: iyangyuanjian,QQ:624508914

1、前言

  • 该项目是公司内部服务与外部服务的中台系统,我称之为大杂烩
  • 项目始于:2015年10月8号 18:31:39秒
  • 恩,没错,到写文章为止,已经迭代了整整 3年2个月18天

2、为什么要升级?

  • 因为实在是太慢了,删除缓存的情况下,要编译启动起来得花 250
  • 有缓存的情况下启动得 120 多秒
  • 热更新也慢得 10 秒左右
  • 发布就更不用说了,都是泪,出了 BUG 要修复的话,最少得等 20 分钟才能修复

3、升级之后达到的效果

  • 没有缓存的情况下编译启动 40 秒左右
  • 有缓存的情况下编译启动 20 秒左右
  • 热更新 1 ~ 3

4、老项目架构

  • express
  • webpack
  • react
  • redux
  • 具体请看 package.json 在尾部

5、新项目架构

  • 基本不变,做了很多启动时的调整和优化

6、踩坑之路开始

6.1、梳理 package.json

  • 把一些老项目中没有用到的包给干掉
  • 区分清楚 dev 依赖

6.2、创建新的开发环境

  • babel + webpack + express + react + react-redux 都是最新版, 其余的升级后面再看
  • react-router 升级到 3.x 最新版(支持 react 16.x )
  • 相关包在测试中慢慢升级
  • 自动监听端口是否被暂用,端口暂用后可以输入新端口启动
  • 启动之后自动打开浏览器

上面两部流程完了之后,开始迁移老项目到新开发环境中,不要直接在老项目改动

6.3、老项目测试启动

  • 之前老项目存在 typescript 写法,居然可以正常运行这么多年,奇葩,关键还能编译成功,批量替换掉
  • 删除 package.json 中没有被应用
  • 发现系统大量用了 reactPropTypes,在 16 之后就拆分成单独的包了,批量替换成新包
  • 有一些 babel 语法问题,找方法修复
  • 嗯,顺利启动

总结

  • 其中过程曲折太多了,尝试了两个礼拜,期间进行了 5-6 次升级尝试
  • 作为一个后端,我感觉要学的东西太多了,有种有心无力的感觉
  • 整个项目最难的地方在于 babel 因为是老项目,存在 module.exports 写法,以及一些其他的配置,都是临时看官方文档,谷歌,Stack Overflow去找解决方案,当然也受益匪浅
  • 还有些老项目的东西需要完成,比如 eslint, typescript 接入,打包发布

新项目的 package.json

{
  "name": "xxx 敏感信息",
  "version": "1.0.0",
  "description": "xxx 敏感信息",
  "repository": "xxx 敏感信息",
  "author": "smithyj<[email protected]>",
  "private": true,
  "scripts": {
    "start": "webpack-dashboard -- npm run start:pure",
    "start:nodemon": "webpack-dashboard -- npm run start:pure:nodemon",
    "start:pure": "cross-env NODE_ENV=development babel-node ./server/app.js",
    "start:pure:nodemon": "cross-env NODE_ENV=development nodemon ./server/app.js --exec babel-node",
    "build": "npm run build:prod",
    "build:prod": "cross-env NODE_ENV=production webpack",
    "build:test": "cross-env NODE_ENV=test webpack",
    "serve": "cross-env BUILD_SERVE=true npm run build:test && serve dist",
    "rsync:remote:test": "xxx 敏感信息",
    "rsync:remote:prod": "xxx 敏感信息",
    "deploy:remote:test": "npm run build:test && npm run rsync:remote:test",
    "deploy:remote:prod": "npm run build:prod && npm run rsync:remote:prod",
    "deploy:remote": "npm run deploy:remote:test && npm run deploy:remote:prod"
  },
  "devDependencies": {
    "@babel/cli": "^7.2.0",
    "@babel/core": "^7.2.0",
    "@babel/node": "^7.2.0",
    "@babel/plugin-proposal-class-properties": "^7.2.1",
    "@babel/plugin-proposal-decorators": "^7.2.2",
    "@babel/plugin-proposal-do-expressions": "^7.2.0",
    "@babel/plugin-proposal-export-default-from": "^7.2.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.2.0",
    "@babel/plugin-syntax-decorators": "^7.2.0",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/polyfill": "^7.0.0",
    "@babel/preset-env": "^7.2.0",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.4",
    "babel-plugin-add-module-exports": "^1.0.0",
    "body-parser": "^1.18.3",
    "cache-loader": "^1.2.5",
    "chalk": "^2.4.1",
    "clean-webpack-plugin": "^1.0.0",
    "clipboardy": "^1.2.3",
    "cookie-parser": "^1.4.3",
    "copy-webpack-plugin": "^4.6.0",
    "cross-env": "^5.2.0",
    "css-loader": "^2.0.1",
    "detect-port": "^1.3.0",
    "express": "^4.16.4",
    "extract-css-chunks-webpack-plugin": "^3.2.1",
    "file-loader": "^2.0.0",
    "happypack": "^5.0.0",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.9.0",
    "less-loader": "^4.1.0",
    "mini-css-extract-plugin": "^0.5.0",
    "morgan": "^1.9.1",
    "nodemon": "^1.18.8",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "progress-bar-webpack-plugin": "^1.11.0",
    "react-dev-utils": "^6.1.1",
    "serve": "^10.1.1",
    "serve-favicon": "^2.5.0",
    "style-loader": "^0.23.1",
    "uglifyjs-webpack-plugin": "^2.0.1",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2",
    "webpack-dashboard": "^2.0.0",
    "webpack-dev-middleware": "^3.4.0",
    "webpack-hot-middleware": "^2.24.3",
  },
  "dependencies": {
    "ali-oss": "^5.2.0",
    "antd": "^2.13.10",
    "autobind": "^1.0.3",
    "core-decorators": "^0.20.0",
    "create-react-class": "^15.6.3",
    "jump.js": "^1.0.2",
    "lodash": "^4.16.4",
    "lodash-decorators": "^4.5.0",
    "md5": "^2.2.1",
    "moment": "^2.19.4",
    "pdfjs-dist": "^1.9.528",
    "prop-types": "^15.6.2",
    "qrcode.react": "^0.7.2",
    "query-string": "^6.2.0",
    "rc-queue-anim": "^1.6.10",
    "rc-tween-one": "^1.7.2",
    "react": "^16.7.0",
    "react-addons-update": "^15.6.2",
    "react-color": "^2.14.1",
    "react-copy-to-clipboard": "^5.0.1",
    "react-dnd": "^2.1.2",
    "react-dnd-html5-backend": "^2.1.2",
    "react-dom": "^16.7.0",
    "react-drag-listview": "0.0.9",
    "react-mixin": "^5.0.0",
    "react-redux": "^6.0.0",
    "react-router": "^3.2.1",
    "react-string-replace": "^0.4.0",
    "redux": "^3.3.1",
    "redux-form": "^5.3.3",
    "redux-logger": "^2.7.0",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^1.0.0",
    "simditor": "2.3.22",
    "simditor-fullscreen": "^0.1.1",
    "simditor-html": "^1.1.1"
  }
}

复制代码

老项目的 package.json

{
  "name": "crm",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "webpack-dashboard -- cross-env NODE_ENV=development  node ./server/bin/www",
    "start:pure": "NODE_ENV=development  node ./server/bin/www",
    "clean": "rimraf client/dist/",
    "clean:cache": "rimraf ./.cache",
    "build": "cross-env BABEL_ENV=production  webpack --config webpack.config.js",
    "build:test": "NODE_ENV=test npm run build",
    "build:prod": "NODE_ENV=production npm run build",
    "rsync:test": "xxx 敏感信息",
    "rsync:prod": "xxx 敏感信息",
    "deploy:test": "npm run build:test && npm run rsync:test",
    "deploy:prod": "npm run build:prod && npm run rsync:prod",
    "rsync:remote:test": "xxx 敏感信息",
    "rsync:remote:prod": "xxx 敏感信息",
    "deploy:remote:test": "npm run build:test && npm run rsync:remote:test",
    "deploy:remote:prod": "npm run build:prod && npm run rsync:remote:prod",
    "deploy:remote": "npm run deploy:remote:test && npm run deploy:remote:prod",
    "lint": "eslint --ext .js --ext .jsx client/src",
    "fix": "eslint --fix --ext .js --ext .jsx client/src",
    "prettier:fix": "prettier --write '**/*.{js,jsx,less,css.scss,html}'",
    "prebuild": "npm run clean",
    "commit": "commit-wizard"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,jsx,less,css,scss,html}": [
      "prettier --write",
      "git add"
    ],
    "*.{js,jsx}": [
      "eslint --fix",
      "git add"
    ]
  },
  "dependencies": {
    "ali-oss": "^5.2.0",
    "antd": "^2.13.10",
    "assets-webpack-plugin": "^3.4.0",
    "autobind-decorator": "^2.1.0",
    "axios": "^0.15.3",
    "bluebird": "^3.3.4",
    "body-parser": "^1.15.1",
    "connect-multiparty": "^2.1.0",
    "cookie-parser": "~1.4.0",
    "core-decorators": "^0.20.0",
    "css-loader": "^0.28.7",
    "debug": "~2.2.0",
    "del": "^3.0.0",
    "express": "^4.14.0",
    "fs-extra": "^4.0.3",
    "genny": "^0.5.6",
    "glob": "^7.0.0",
    "hbs": "~4.0.0",
    "history": "^1.13.0",
    "html-webpack-plugin": "^1.6.2",
    "immutable": "^3.7.5",
    "jump.js": "^1.0.2",
    "less": "^2.7.3",
    "less-loader": "^4.0.5",
    "lodash": "^4.16.4",
    "lodash-decorators": "^4.5.0",
    "logrocket": "^0.5.2",
    "md5": "^2.2.1",
    "method-override": "*",
    "moment": "^2.19.4",
    "morgan": "^1.6.1",
    "nodejieba": "^2.2.4",
    "pdfjs-dist": "^1.9.528",
    "pinyin": "^2.8.0",
    "qrcode.react": "^0.7.2",
    "raw-loader": "*",
    "rc-animate": "^2.4.4",
    "rc-queue-anim": "^0.12.6",
    "rc-tween-one": "^1.7.2",
    "react": "15.3.1",
    "react-addons-css-transition-group": "^15.6.2",
    "react-addons-update": "^15.6.2",
    "react-color": "^2.14.1",
    "react-copy-to-clipboard": "^5.0.1",
    "react-dnd": "^2.1.2",
    "react-dnd-html5-backend": "^2.1.2",
    "react-dom": "15.3.1",
    "react-drag-listview": "0.0.9",
    "react-froala-wysiwyg": "^2.8.1",
    "react-loadable": "^4.0.5",
    "react-mixin": "^4.0.0",
    "react-pure-render": "^1.0.2",
    "react-redux": "^5.0.6",
    "react-router": "^2.8.1",
    "react-string-replace": "^0.4.0",
    "redbox-react": "^1.5.0",
    "redux": "^3.3.1",
    "redux-form": "^5.3.3",
    "redux-logger": "^2.7.0",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^1.0.0",
    "rimraf": "^2.4.3",
    "serve-favicon": "^2.4.5",
    "simditor": "^2.3.19",
    "simditor-fullscreen": "^0.1.1",
    "simditor-html": "^1.1.1",
    "text-loader": "*",
    "url-loader": "^1.0.1"
  },
  "devDependencies": {
    "babel-core": "^6.18.0",
    "babel-eslint": "^8.2.1",
    "babel-loader": "^7.1.2",
    "babel-plugin-add-module-exports": "^0.2.1",
    "babel-plugin-import": "^1.6.3",
    "babel-plugin-lodash": "^3.3.2",
    "babel-plugin-react-transform": "^3.0.0",
    "babel-plugin-transform-class-properties": "^6.16.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-regenerator": "^6.26.0",
    "babel-polyfill": "^6.16.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.16.0",
    "babel-preset-es2015-loose": "^8.0.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-react-hmre": "^1.1.1",
    "babel-preset-stage-0": "^6.16.0",
    "babel-standalone": "^6.4.4",
    "clean-webpack-plugin": "^0.1.8",
    "cross-env": "^5.1.3",
    "eslint": "^4.15.0",
    "eslint-config-prettier": "^3.3.0",
    "eslint-config-standard": "^10.2.1",
    "eslint-config-standard-jsx": "^4.0.1",
    "eslint-config-standard-react": "^5.0.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-node": "^5.2.1",
    "eslint-plugin-prettier": "^3.0.0",
    "eslint-plugin-promise": "^3.6.0",
    "eslint-plugin-react": "^7.5.1",
    "eslint-plugin-standard": "^3.0.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.6",
    "husky": "^1.2.0",
    "lint-staged": "^8.1.0",
    "prettier": "^1.15.2",
    "progress-bar-webpack-plugin": "^1.3.0",
    "react-hot-loader": "^3.1.3",
    "react-router-loader": "^0.5.4",
    "react-transform-catch-errors": "^1.0.0",
    "react-transform-hmr": "^1.0.4",
    "source-map-loader": "^0.2.1",
    "style-loader": "^0.19.0",
    "transfer-webpack-plugin": "^0.1.4",
    "uglifyjs-webpack-plugin": "^1.1.6",
    "webpack": "^3.10.0",
    "webpack-bundle-analyzer": "^2.9.2",
    "webpack-dashboard": "^0.4.0",
    "webpack-dev-middleware": "^1.12.2",
    "webpack-dev-server": "^2.10.1",
    "webpack-hot-middleware": "^2.21.0",
    "webpack-md5-hash": "^0.0.5",
    "workbox-webpack-plugin": "^1.0.1"
  },
  "engines": {
    "node": ">=6"
  }
}

复制代码

转载于:https://juejin.im/post/5c1cc13ff265da61257815be

你可能感兴趣的:(记一次 react 15.3.1 老项目升级到 react 16.7.0 之路)