create-react-app配置总结
create-react-app配置總結
最近在用react全家桶做一個管理后臺的項目,項目采用的create-react-app腳手架,用的ui框架是ant design與ant design pro。中間碰到了一些問題,在這里總結一下。
2018年十月初,create-react-app 2.0發布。這次 create-react-app 的更新主要是解決其所依賴的相關工具的更新,create-react-app所依賴的許多工具均發布了新的功能和版本,例如 Babel 7、Webpack 4、Jest 23,因此 create-react-app 在這次更新中將一年中值得更新的依賴全部進行了更新。
下面是它這次更新的全部內容:
1. 添加less支持,css module配置 antd配置
項目中添加less less-loader antd
yarn add --dev less less-loader yarn add antd ant-design-pro修改webpack.config.js
const lessRegex = /\.less$/ const lessModuleRegex = /\.module\.less$/ const antdRegex = /\.(css|less)$/// 添加第三個參數otherConfig const getStyleLoaders = (cssOptions, preProcessor, otherConfig) => {...if (preProcessor) {loaders.push({loader: require.resolve(preProcessor),options: {sourceMap: isEnvProduction && shouldUseSourceMap,...otherConfig}})}return loaders }// Add antd setting ... {test: lessRegex,exclude: /node_modules|antd\.css/,use: getStyleLoaders({importLoaders: 2,sourceMap: isEnvProduction && shouldUseSourceMap,localIdentName: '[name]__[local]__[contenthash:base64:5]',modules: true},'less-loader',{javascriptEnabled: true} ),sideEffects: true }, {test: lessModuleRegex,use: getStyleLoaders({importLoaders: 2,sourceMap: isEnvProduction && shouldUseSourceMap,modules: true,getLocalIdent: getCSSModuleLocalIdent},'less-loader',{javascriptEnabled: true} ) }, {test: antdRegex,include: /node_modules|antd\.css/,use: getStyleLoaders({importLoaders: 2,sourceMap: isEnvProduction && shouldUseSourceMap},'less-loader',{javascriptEnabled: true} ),sideEffects: true }, ...2. 生產環境去除console
修改webpack.config.js
compress: {ecma: 5,warnings: false,drop_debugger: true,drop_console: true,// Disabled because of an issue with Uglify breaking seemingly valid code:// https://github.com/facebook/create-react-app/issues/2376// Pending further investigation:// https://github.com/mishoo/UglifyJS2/issues/2011comparisons: false,......3. 生產環境去除sourcemap
修改webpack.config.js
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; const shouldUseSourceMap = process.env.REACT_APP_GENERATE_SOURCEMAP !== 'false'環境變量文件中使用
REACT_APP_GENERATE_SOURCEMAP=false4. 添加裝飾器插件transform-decorators-legacy
安裝 @babel/plugin-proposal-decorators
yarn add --dev @babel/plugin-proposal-decorators修改package.json中plugins
"plugins": [["@babel/plugin-proposal-decorators",{"legacy": true}],....]5. 添加插件 webpack-bundle-analyzer
安裝 webpack-bundle-analyzer
yarn add --dev webpack-bundle-analyzer修改 webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin// use BundleAnalyzerPlugin const shouldUseBundleAnalyzer = process.env.REACT_APP_USE_ANALYZER !== 'false'plugins:[....,isEnvProduction && shouldUseBundleAnalyzer && new BundleAnalyzerPlugin(), ]環境變量文件中添加
REACT_APP_USE_ANALYZER=false6. 項目中添加redux-logger
安裝redux-logger
yarn add --dev redux-logger項目中使用 configureStore.js
import { createStore, applyMiddleware } from 'redux' import logger from 'redux-logger' import rootReducer from '../reducers'const debug = process.env.NODE_ENV !== 'production'const middleware = [debug && logger, ].filter(Boolean)const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore)export default function configureStore (initialState) {const store = createStoreWithMiddleware(rootReducer, initialState,window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : undefined)return store }7. 項目中添加nprogress進度條
安裝nprogress
yarn add nprogress項目中使用 App.js
import NProgress from 'nprogress'class App extends Component {componentWillUpdate () {NProgress.start()}componentDidUpdate () {NProgress.done()}render () {return (<div className="App"><Switch>........</Switch></div>)} }8. 項目打包生成.gz文件
安裝插件compression-webpack-plugin
yarn add --dev compression-webpack-plugin修改webpack.config.js
const CompressionPlugin = require("compression-webpack-plugin");plugins: [...isEnvProduction && new CompressionPlugin({filename: '[path].gz[query]',algorithm: 'gzip',test: /\.js$|\.css$|\.html$/,threshold: 10240,minRatio: 0.8}), ]9. 按需加載ant design與ant design pro
安裝插件compression-webpack-plugin
yarn add --dev babel-plugin-import修改package.json中plugins
"plugins": [...["import",{"libraryName": "antd","libraryDirectory": "es","style": "css"},"antd"],["import",{"libraryName": "ant-design-pro","libraryDirectory": "lib","style": true,"camel2DashComponentName": false},"ant-design-pro"] ]10. 多環境支持
因為create-react-app只支持development,production,test三個環境,當需要對更多環境提供支持的時候(比如,公司有兩個測試環境,對應的接口都不一樣),就需要修改下配置了。
 其實很簡單,只需要將create-react-app查找.env文件的一個變量
 例如:
- 開發環境(development)
 - 測試環境(production)
 - 發布環境(release)
 
安裝插件cross-env
yarn add --dev cross-env項目根目錄添加文件.env.development,.env.production,.env.release
//.env.development NODE_ENV=development REACT_APP_XXX=XXX ...//.env.production NODE_ENV=production REACT_APP_XXX=XXX ...//.env.release NODE_ENV=production REACT_APP_XXX=XXX ...修改config/env.js
//有一個特殊的內置環境變量叫做NODE_ENV,你可以輸出process.env.NODE_ENV,但無法手動覆蓋NODE_ENV。這可以防止開發人員意外地將緩慢的開發構建部署到生產環境中。 // const NODE_ENV = process.env.NODE_ENV; const NODE_ENV = process.env.REACT_ENV || process.env.NODE_ENV;修改package.json
"scripts": {"start": "node scripts/start.js","build": "cross-env REACT_ENV=production node scripts/build.js","release": "cross-env REACT_ENV=release node scripts/build.js","test": "node scripts/test.js"},打包命令
- 打包測試版本:yarn build
 - 打包正式版本:yarn release
 
11. 使用DllPlugin拆分第三方資源代碼
什么是DLL
DLL(Dynamic Link Library)文件為動態鏈接庫文件,在Windows中,許多應用程序并不是一個完整的可執行文件,它們被分割成一些相對獨立的動態鏈接庫,即DLL文件,放置于系統中。當我們執行某一個程序時,相應的DLL文件就會被調用。
舉個例子:很多產品都用到螺絲,但是工廠在生產不同產品時,不需要每次連帶著把螺絲也生產出來,因為螺絲可以單獨生產,并給多種產品使用。在這里螺絲的作用就可以理解為是dll。
通常來說,我們的代碼都可以至少簡單區分成業務代碼和第三方庫。如果不做處理,每次構建時都需要把所有的代碼重新構建一次,耗費大量的時間。然后大部分情況下,很多第三方庫的代碼并不會發生變更(除非是版本升級),這時就可以用到dll:把復用性較高的第三方模塊打包到動態鏈接庫中,在不升級這些庫的情況下,動態庫不需要重新打包,每次構建只重新打包業務代碼。
還是上面的例子:把每次構建,當做是生產產品的過程,我們把生產螺絲的過程先提取出來,之后我們不管調整產品的功能或者設計(對應于業務代碼變更),都不必重復生產螺絲(第三方模塊不需要重復打包);除非是產品要使用新型號的螺絲(第三方模塊需要升級),才需要去重新生產新的螺絲,然后接下來又可以專注于調整產品本身。
新建webpack.vendor.config.js文件
const path = require('path') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const webpack = require('webpack')function resolve (dir) {return path.join(__dirname, '..', dir) }module.exports = {mode: 'production',entry: {vendor: ['react','react-container-query','react-document-title','react-dom','react-redux','react-router-dom','redux','whatwg-fetch','classnames','enquire-js','es6-promise','good-storage','nprogress','numeral','path-to-regexp',],},output: {filename: '[name].[contenthash:8].chunk.js',path: resolve('./vendor'),library: '[name]'},plugins: [new CleanWebpackPlugin(),new webpack.DllPlugin({name: '[name]',path: resolve('./vendor/[name].manifest.json')})] }修改webpack.config.js文件
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')function pathResolve (dir) {return path.resolve(__dirname, '..', dir) }//檢測文件或者文件夾存在 function fsExistsSync (path) {try {fs.accessSync(path, fs.F_OK)} catch (e) {return false}return true }const createVendorPlugins = (publicPath) => {const plugins = []const hasVendor = fsExistsSync('./vendor')if (hasVendor) {const files = fs.readdirSync(pathResolve('./vendor'))files.forEach(file => {if (/.*\.chunk.js/.test(file)) {plugins.push(new AddAssetHtmlWebpackPlugin({filepath: pathResolve(`./vendor/${file}`),publicPath: `${publicPath}static/js`,outputPath: 'static/js'}))}if (/.*\.manifest.json/.test(file)) {plugins.push(new webpack.DllReferencePlugin({manifest: pathResolve(`./vendor/${file}`)}))}})}return plugins }... plugins:[...].filter(Boolean).concat(createVendorPlugins(publicPath)) ...修改package.json文件
"scripts":{"vendor": "webpack --config ./config/webpack.vendor.config.js",... }然后控制臺使用yarn vendor yarn start||yarn build即可。
12. Webpack alias配置
修改webpack.config.js文件
alias: {// Support React Native Web// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/'react-native': 'react-native-web','@': pathResolve('src')},13. ESLint + Standard 項目配置
安裝插件
yarn add --dev eslint-config-standard eslint-config-standard-react eslint-plugin-node eslint-plugin-promise eslint-plugin-standard修改webpack.config.js文件
{test: /\.(js|mjs|jsx|ts|tsx)$/,enforce: 'pre',use: [{options: {formatter: require.resolve('react-dev-utils/eslintFormatter'),eslintPath: require.resolve('eslint'),emitWarning: true// 添加內容},loader: require.resolve('eslint-loader')}],include: paths.appSrc },項目根目錄新建.eslintrc.js文件
module.exports = {env: {browser: true,es6: true,node: true},extends: ['standard', 'standard-react'],parser: 'babel-eslint',parserOptions: {ecmaVersion: 6,ecmaFeatures: {experimentalObjectRestSpread: true,modules: true,jsx: true,},parser: 'babel-eslint',sourceType: 'module',},plugins: ['react'],root: true,globals: {Atomics: 'readonly',SharedArrayBuffer: 'readonly'},rules: {'camelcase': 0,// 強制駝峰法命名'handle-callback-err': 0,// nodejs 處理錯誤"indent": 0,// 縮進風格'no-console': 0,// 禁止使用console'no-unused-vars': [0, {// 允許聲明未使用變量'vars': 'local',// 參數不檢查'args': 'none'}],'no-return-assign': 0,// return 語句中不能有賦值表達式'no-undef': 0,// 不能有未定義的變量'node/no-deprecated-api': 0,'react/prop-types': 0,// jsx 的開始和閉合處禁止有空格'react/jsx-tag-spacing': ['error',{'closingSlash': 'never','beforeSelfClosing': 'allow','afterOpening': 'never'}],'react/jsx-indent': ['error', 2],'standard/no-callback-literal': 0} }14. 編譯進度條配置
安裝progress-bar-webpack-plugin
yarn add --dev progress-bar-webpack-plugin修改webpack.config.js文件
const ProgressBarPlugin = require('progress-bar-webpack-plugin') const chalk = require('chalk')plugins:[...new ProgressBarPlugin({format: ' build [:bar] ' + chalk.green.bold(':percent') + ' (:elapsed seconds)',clear: false}) ]運行結果如下:
15. 項目熱更新配置
create-react-app默認修改代碼后會直接刷新頁面,我們需要修改的部分自動刷新,和自動刷新網頁不同的是,hot-loader并不會刷新網頁,僅僅是替換修改的部分。
15.1 使用react-hot-loader
安裝react-hot-loader
yarn add --dev react-hot-loader修改webpack.config.js文件
entry:[// 添加內容'react-hot-loader/patch',isEnvDevelopment &&require.resolve('react-dev-utils/webpackHotDevClient'),// Finally, this is your app's code:paths.appIndexJs ] ... plugins: [[require.resolve('babel-plugin-named-asset-import'),{loaderMap: {svg: {ReactComponent: '@svgr/webpack?-svgo,+ref![path]'}}},'react-hot-loader/babel'//添加內容] ],修改App.js文件
import { hot } from 'react-hot-loader'...export default hot(module)(App)15.2 使用webpack內置HMR
修改index.js文件
const app = (<Provider store={store}><LocaleProvider locale={zhCN}><HashRouter><App/></HashRouter></LocaleProvider></Provider> )ReactDOM.render(app,document.getElementById('root'))....if (module.hot) {module.hot.accept() }重啟后可以看到修改部分已經刷新而瀏覽器網頁沒有刷新。
16. 優化create-react-app編譯打包速度
使用babel-plugin-dynamic-import-node插件,原理是轉換 import()為 require(),將所有異步組件都用同步的方式引入
安裝babel-plugin-dynamic-import-node
yarn add --dev babel-plugin-dynamic-import-node修改.env.development文件與.env.production文件
//.env.development NODE_ENV=development ...//.env.production NODE_ENV=production ...修改package.json文件
"babel": {"env": {"development": {"plugins": ["dynamic-import-node"]}},...... }重啟項目可查看運行效果。
17. 修改antd組件庫主題色
修改webpack.config.js文件
{test: antdRegex,include: /node_modules|antd\.css/,use: getStyleLoaders({importLoaders: 2,sourceMap: isEnvProduction && shouldUseSourceMap},'less-loader',{javascriptEnabled: true,// 添加如下配置 modifyVars: {'@primary-color': '#7298ff'}}),sideEffects: true },重啟項目即可修改默認主題色。
github鏈接:react-ant-design,歡迎star
總結
以上是生活随笔為你收集整理的create-react-app配置总结的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 客户说我已经有合作伙伴了 电话销售如何回
 - 下一篇: SpringMVC图片文件上传功能实现