首頁 > 軟體

create-react-app常用自定義設定教學範例

2022-06-24 18:00:04

引言

Create React App 是一個官方支援的建立 React 單頁應用程式的方法。它提供了一個零設定的現代構建設定。
雖然開箱即用,但是開發中我們還是少不了做一些修改,下面總結了一些常用的設定。

yarn安裝依賴包報錯

在專案目錄下執行yarn,報錯如下

yarn install v1.7.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info There appears to be trouble with your network connection. Retrying...
error An unexpected error occurred: "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz: connect ETIMEDOUT 104.16.21.35:443".
info If you think this is a bug, please open a bug report with the information provided in "F:\await\react-rabc\yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

提示很明顯,網路連線超時,我們更換一下源地址就行了

npm 設定為 淘寶源

npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist

yarn 設定為 淘寶源

yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global

專案中如果用的是 sass,需要下載 node-sass,這個依賴包下載是相當的慢,可以單獨設定源地址

yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass
npm config set sass-binary-site http://npm.taobao.org/mirrors/node-sass

最後刪除 node_modules,重新下載就行了

IE10下報錯, Map 未定義

yarn add react-app-polyfill

入口檔案第一行引入

// This must be the first line in src/index.js
import 'react-app-polyfill/ie9'

react-app-polyfill

webpack新增 alias

config/modules.js檔案中的webpackAliases的alias是解析專案根目錄下的tsconfig.json或者jsconfig.json來返回的,有點複雜

可以直接在webpack.config.js的resolve.alias欄位中的末尾新增欄位

resolve: {
  // ...
  alias: {
    // ...
    '@': path.resolve(__dirname, '../src')
  }
}

解決跨域,反向代理設定

1、安裝依賴

yarn add http-proxy-middleware

2、在src目錄下新建setupProxy.js檔案

const { createProxyMiddleware } = require('http-proxy-middleware')
module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:6000', // 請求介面地址
      changeOrigin: true,
      pathRewrite: {
        '^/api': '/'
      }
    })
  )
}

專案主要檔案路徑設定

包括專案入口檔案、靜態目錄、專案構建輸出目錄、設定proxy檔案...

在config/paths.js檔案設定,挑出幾個最常用的

module.exports = {
  dotenv: resolveApp('.env'), // 專案環境變數檔案
  appBuild: resolveApp('dist'), // 專案構建輸出目錄,預設 build
  appPublic: resolveApp('public'), // 靜態目錄
  appHtml: resolveApp('public/index.html'), // index.html
  appIndexJs: resolveModule(resolveApp, 'src/index'), // 專案入口檔案
  proxySetup: resolveApp('src/setupProxy.js') // 設定 proxy 檔案
}

關閉自動開啟瀏覽器設定

在scripts/start.js檔案,註釋掉openBrowser(urls.localUrlForBrowser)即可,
或者使用環境變數BROWSER

{
  "script": {
    "start": "cross-env BROWSER=none node scripts/start.js"
  }
}

修改 webpack output.publicPath

如果專案不是部署在靜態伺服器根目錄下會用到,直接在package.json中設定homepage欄位

{
  "homepage": "/e-admin/"
}

或者使用環境變數PUBLIC_URL

{
  "script": {
    "build": "cross-env PUBLIC_URL=/e-admin/ node scripts/build.js"
  }
}

生產環境關閉 sourcemap

一般在部署到生產環境會關閉 sourcemap,避免打包檔案過大
檢視 webpack.config.js 看到如下程式碼:

const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

可以在命令列中使用GENERATE_SOURCEMAP這個環境變數

{
  "script": {
    "build": "cross-env GENERATE_SOURCEMAP=false node scripts/build.js"
  }
}

eslint 設定

可以直接在package.json中的eslintConfig欄位設定。

在根目錄下新建.eslint.js(或者.eslintrc)組態檔,然後在命令列中設定EXTEND_ESLINT

{
  "script": {
    "start": "cross-env EXTEND_ESLINT=true node scripts/start.js"
  }
}

因為各平臺設定環境變數的方式不同,這裡使用cross-env來抹平差異

裝飾器 Decorators 設定

開發中會有很多高階元件以及 redux 的 connect 來包裹元件,使用 Decorators 寫法會直觀許多

  • 先安裝 babel 外掛
yarn add @babel/plugin-proposal-decorators
  • babel 設定,在 plugins 中新增
{
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ]
  ]
}

完成上面設定後,編譯就不會報錯了,程式碼能正常執行,但是編輯器(這是使用VSCode)卻報錯了,我們需要做額外的設定

在根目錄下新建 jsconfig.json 檔案

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

開啟 VSCode 的 setting.json 檔案,新增以下屬性

"javascript.implicitProjectConfig.experimentalDecorators": true

create-react-app 的 babel 設定預設是在 package.json 中的,可以單獨放到根目錄下(.babelrc或者babel.config.js)

區分環境

開發環境,測試環境,預生產環境,生產環境,很多設定項(比如介面地址)都是不同的,這時候我們需要根據環境來決定設定項。
create-react-app 預設支援development,test,production,這裡的 test 是用來做程式碼測試的,並不是構建測試環境的,我們需要多種打包環境。
這裡我們先區分三個環境:

  • 開發環境 dev
  • 測試環境 alpha
  • 生產環境 prod

1、然後在根目錄新建三個檔案 .env,.env.alpha,.env.prod,檔案內容如下:

// .env
NODE_ENV=development
REACT_APP_MODE=dev
// .env.alpha
NODE_ENV=production
REACT_APP_MODE=alpha
// .env.prod
NODE_ENV=production
REACT_APP_MODE=prod

2、修改package.json的命令指令碼

{
  "script": {
    "build:alpha": "cross-env MODE_ENV=alpha node scripts/build.js",
    "build:prod": "cross-env MODE_ENV=prod node scripts/build.js"
  }
}

3、修改config/env.js檔案

// const NODE_ENV = process.env.NODE_ENV;
const NODE_ENV = process.env.MODE_ENV || process.env.NODE_ENV;

4、然後在業務程式碼裡面就可以使用process.env.REACT_APP_MODE來區分環境了

// axios.baseURL
const baseURL = {
  dev: 'http://localhost:3000',
  alpha: 'http://alpha.xxx.com',
  prod: 'http://xxx.com'
}[process.env.REACT_APP_MODE]

根據不同命令區分不同環境,這是通用的手段。
這裡根據npm命令中的REACT_APP_MODE來決定使用哪個.env.[xxx]的環境變數,注入到編譯程式碼中。

注意:

  • 需要注意的是在 env.js 檔案中將 NODE_ENV 替換為了 MODE_ENV,導致本來的 NODE_ENV 缺失,在 .env.[xxx] 檔案中要補上
  • .env.[xxx] 的環境變數 以 REACT_APP_xxx 開頭

編譯進度條設定

安裝依賴

yarn add webpackbar

修改webpack.config.js檔案

const WebpackBar = require('webpackbar')
plugins: [
  // ...
  new webpack.ProgressPlugin(),
  new WebpackBar()
]

webpack.ProgressPlugin() 是webpack內建外掛,webpack.ProgressPlugin,WebpackBar用來顯示編譯時長

打包開啟 gzip 壓縮

安裝依賴

yarn add compression-webpack-plugin

修改webpack.config.js檔案

const CompressionPlugin = require('compression-webpack-plugin')
const isGzip = process.env.GENERATE_GZIP_FILE === 'true'
plugins: [
  // ...
  isEnvProduction && isGzip && new CompressionPlugin({
    filename: '[path].gz[query]', // 新版本 asset 屬性已更換為 filename
    algorithm: 'gzip',
    test: /.js$|.css$/,
    threshold: 10240,
    minRatio: 0.8
  })
]

通過設定環境變數GENERATE_GZIP_FILE=true來啟用gzip壓縮

請確保靜態伺服器開啟了 gzip 設定項,nginx 設定 gzip_static on; 選項即可

下面是未開啟gzip和開啟gzip的效果:

未開啟 gzip

開啟 gzip

生成 report.html 視覺化打包分析

安裝依賴

yarn add webpack-bundle-analyzer

修改webpack.config.js檔案

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const isBundleAnalyzer = process.env.GENERATE_BUNDLE_ANALYZER_REPORT === 'true'
plugins: [
  // ...
  isEnvProduction && isBundleAnalyzer && new BundleAnalyzerPlugin()
]

通過設定環境變數GENERATE_BUNDLE_ANALYZER_REPORT=true來生成report

引入 antd

antd 的 JS 程式碼預設支援基於 ES modules 的 tree shaking,即按需引入,只是樣式的引入有些區別

1、直接引入,樣式直接用編譯後的antd.css

import { Button } from 'antd'
import 'antd/dist/antd.css'
function App() {
  return (
    <Button type="primary">按鈕</Button>
  )
}

簡單粗暴,但是沒法統一修改一些全域性的顏色

2、引入 less

安裝依賴

yarn add less less-loader

wepack.config.js設定,預設的rules已經包含css和sass,先找到下面的正則

// style files regexes
const cssRegex = /.css$/;
const cssModuleRegex = /.module.css$/;
const sassRegex = /.(scss|sass)$/;
const sassModuleRegex = /.module.(scss|sass)$/;
// 加上匹配 less 檔案的正則
const lessRegex = /.less$/;
const lessModuleRegex = /.module.less$/;

然後加上 loader 設定,在sass-loader設定下面加上less-loader的設定

// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
  test: sassModuleRegex,
  use: getStyleLoaders(
    {
      importLoaders: 3,
      sourceMap: isEnvProduction && shouldUseSourceMap,
      modules: {
        getLocalIdent: getCSSModuleLocalIdent,
      },
    },
    'sass-loader'
  ),
},
// 在下面加上 less-loader 設定
{
  test: lessRegex,
  exclude: lessModuleRegex,
  use: getStyleLoaders(
    {
      importLoaders: 2,
      sourceMap: isEnvProduction && shouldUseSourceMap,
    },
    'less-loader'
  ),
  sideEffects: true,
},
// Adds support for CSS Modules, but using less
// using the extension .module.less
{
  test: lessModuleRegex,
  use: getStyleLoaders(
    {
      importLoaders: 2,
      sourceMap: isEnvProduction && shouldUseSourceMap,
      modules: {
          getLocalIdent: getCSSModuleLocalIdent
      }
    },
    'less-loader'
  ),
},

找到getStyleLoaders方法,做如下修改:

// 將 if (preProcessor) {} 中的程式碼替換,實際上就是判斷是`less-loader`就生成針對less的options
if (preProcessor) {
  let preProcessorRule = {
    loader: require.resolve(preProcessor),
    options: {
      sourceMap: true
    }
  }
  if (preProcessor === 'less-loader') {
    preProcessorRule = {
      loader: require.resolve(preProcessor),
      options: {
        sourceMap: true,
        lessOptions: { // 如果使用less-loader@5,需要移除 lessOptions 這一級
          javascriptEnabled: true,
          modifyVars: {
            'primary-color': '#346fff', // 全域性主色
            'link-color': '#346fff' // 連結色
          }
        }
      }
    }
  }
  loaders.push(
    {
      loader: require.resolve('resolve-url-loader'),
      options: {
        sourceMap: isEnvProduction &amp;&amp; shouldUseSourceMap,
      },
    },
    preProcessorRule
  );
}

將import 'antd/dist/antd.css'換成import 'antd/dist/antd.less'

經過上面的設定後,可以直接修改less變數來修改全域性顏色、間距等,所有變數

當然如果在組態檔中覆蓋less變數有些麻煩,可以直接直接新建單獨的less檔案來覆蓋預設變數

@import '~antd/lib/style/themes/default.less';
@import '~antd/dist/antd.less';
@import 'customer-theme-file.less'; // 用於覆蓋預設變數

但是這種方式會載入所有元件的樣式,沒法做到按需載入

3、按需載入

安裝依賴

yarn add babel-plugin-import

babel 設定

"plugins": [
  [
    "babel-plugin-import",
    {
      "libraryName": "antd",
      "libraryDirectory": "es",
      "style": true
    }
  ]
]

去掉import 'antd/dist/antd.less'的引入,現在引入元件就會附帶引入對應元件的樣式了

參考連結:

Create React App 官方檔案

Create React App 中文檔案

Ant Design

以上就是create-react-app常用自定義設定的詳細內容,更多關於create-react-app自定義設定的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com