【原創】不想eject,還咋修改create-react-app的配置?

一、先拋問題

許多剛開始接觸create-react-app框架的同學,不免都會有個疑問:如何在不執行eject操作的同時,修改create-react-app的配置。今天胡哥就來帶大家一起來看看這個問題~

二、爲啥不建議執行eject

1. 執行eject產生了什麼變化?

create-react-app框架本身將webpackbabel的相關配置封裝在了react-scripts中, 執行yarn eject後,會將webpackbabel等配置暴露在config目錄下,同時scripts目錄下會有新的命令文件更新,package.json文件中scripts命令同步更新。

2. 執行eject帶來了什麼問題?

首先,執行eject是不可逆的,複雜的webpack等配置由框架本身轉交給用戶自己進行維護了。

其次,在版本迭代時,如果更新了reactreact-scriptseslinttsconfig等依賴,有可能會引起版本依賴的問題,即使我們按錯誤信息修復了之後,項目還是無法運行

所以我們一般不太建議使用yarn eject的方式暴露create-react-app框架的配置。

三、有需求咋解決

實際開發中,我們還是需要更新webpackbabel的配置,比如:

  • antd的按需加載;

  • 配置css預處理器 - less;

  • 設置alias、externals;

  • 生產環境打包-去除console.log、debugger;

  • 打包結果優化分析;

  • 打包增加進度條提示;

前方高能預警~

藉助react-app-rewiredcustomize-cra來完成配置的擴展~

這裏劃重點,記住要考呦~

我們劃分幾個步驟,來一一實現:

  1. 下載安裝依賴

    yarn add react-app-rewired customize-cra -D

    胡哥現在使用的版本是 react-app-rewired@^2.1.8 、customize-cra@^1.0.0

  2. 配置package.json的命令

    "scripts": {
    -   "start": "react-scripts start",
    +  "start": "react-app-rewired start",
    -   "build": "react-scripts build",
    +   "build": "react-app-rewired build",
    }
  3. 在根目錄下配置config-overrides.js文件

    module.exports = {}

完成了基礎配置後,我們在config-overrides.js中進行詳細配置,解決我們上面的需求問題。

  1. antd的按需加載

    安裝依賴:

    yarn add antd -D

    配置

    cosnt { override, fixBabelImports } = require('customize-cra');

    module.exports = override(
     fixBabelImports(
       "import",
        {
       "libraryName""antd",
          "libraryDirectory""es",
          "style""css"
        }
      )
    )
  2. 配置css預處理器 - less

    爲啥在這裏只強調了less呢,因爲create-react-app中內置了sass/scss的預處理器,只需要使用時安裝相關的依賴就可以了(運行時,根據提示缺失的包進行安裝即可)。

    yarn add sass -D

    接下來我們來less的是如何支持的

    安裝依賴:

    yarn add less less-loader@7.3.0 -D

    注意這裏less-loader的版本 [email protected],如果是最新的版本和上面的react-app-rewired和customize-cra版本配合配置時有問題,所以使用了低版本的。

    less-loader的最新版本其實是爲了配合[email protected]使用的。

    配置

    const { override, addLessLoader } = require('customize-cra');

    module.exports = override(
     addLessLoader({
      // 這裏可以添加less的其他配置
      lessOptions: {
         // 根據自己需要配置即可~
        }
     })
    );
  3. 設置alias、externals;

    const { override, addWebpackAlias } = require('customize-cra');
    const path = require('path');

    module.exports = override(
      // alias
     addWebpackAlias({
        // 加載模塊的時候,可以使用“@”符號來進行簡寫啦~
        '@': path.resolve(__dirname, './src/')
      }),
      // externals
      addWebpackExternals({
        // 注意對應的在public/index.html引入jquery的遠程文件地址
        "jQuery""jQuery"
      })
    )
  4. 生產環境打包-去除console.log、debugger;

    安裝依賴

    yarn add uglifyjs-webpack-plugin -D

    配置

    const { override, addWebpackPlugin } = require('customize-cra');
    const  UglifyJsPlugin = require('uglifyjs-webpack-plugin');

    module.exports = override(
     // 注意是production環境啓動該plugin
     process.env.NODE_ENV === 'production' && addWebpackPlugin(
       new UglifyJsPlugin({
        // 開啓打包緩存
        cachetrue,
        // 開啓多線程打包
        paralleltrue,
        uglifyOptions: {
         // 刪除警告
         warningsfalse,
         // 壓縮
         compress: {
          // 移除console
          drop_consoletrue,
          // 移除debugger
          drop_debuggertrue
         }
        }
       })
      )
    )
  5. 打包結果優化分析;

    安裝依賴

    yarn add webpack-bundle-analyzer cross-env -D

    cross-env用於配置環境變量

    配置

    // package.json文件
    "scripts": {
     "build:analyzer""cross-env ANALYZER=true react-app-rewired build"
    }
    // config-overrides.js
    const { override, addWebpackPlugin } = require('customize-cra');
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

    module.exports = override(
      // 判斷環境變量ANALYZER參數的值
     process.env.ANALYZER && addWebpackPlugin(new BundleAnalyzerPlugin())
    )
  6. 打包增加進度條提示;

    安裝依賴

    yarn add progress-bar-webpack-plugin -D
    const { override, addWebpackPlugin } = require('customize-cra');
    const ProgressBarPlugin = require('progress-bar-webpack-plugin');

    module.exports = override(
     addWebpackPlugin(new ProgressBarPlugin())
    )

以上就是我們實現幾個需求的配置。我們來看看完整的config-overrides.js文件。

// config-overrides.js
cosnt { override, fixBabelImports, addWebpackPlugin, addLessLoader, addWebpackAlias, addWebpackExternals } = require('customize-cra');
const path = require('path');
const  UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');

module.exports = override(
 fixBabelImports(
   "import",
    {
   "libraryName""antd",
      "libraryDirectory""es",
      "style""css"
    }
  ),
  addLessLoader({
  // 這裏可以添加less的其他配置
  lessOptions: {
     // 根據自己需要配置即可~
    }
 }),
  // alias
 addWebpackAlias({
    // 加載模塊的時候,可以使用“@”符號來進行簡寫啦~
    '@': path.resolve(__dirname, './src/')
  }),
  // externals
  addWebpackExternals({
    // 注意對應的在public/index.html引入jquery的遠程文件地址
    "jQuery""jQuery"
  }),
  // 注意是production環境啓動該plugin
 process.env.NODE_ENV === 'production' && addWebpackPlugin(
   new UglifyJsPlugin({
    // 開啓打包緩存
    cachetrue,
    // 開啓多線程打包
    paralleltrue,
    uglifyOptions: {
     // 刪除警告
     warningsfalse,
     // 壓縮
     compress: {
      // 移除console
      drop_consoletrue,
      // 移除debugger
      drop_debuggertrue
     }
    }
   })
  ),
  // 判斷環境變量ANALYZER參數的值
 process.env.ANALYZER && addWebpackPlugin(new BundleAnalyzerPlugin()),
  addWebpackPlugin(new ProgressBarPlugin())
)

以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得收藏轉發,點擊在看推薦給更多的小夥伴。

胡哥有話說,專注於大前端技術領域,分享前端系統架構,框架實現原理,最新最高效的技術實踐!

本文分享自微信公衆號 - 胡哥有話說(hugeyouhuashuo)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章