React 項目如何修改打包地址(編譯輸出文件地址)

好吧,筆者是一個後端開發。之前是作C/S項目出身,毫無Web前端基礎,爲了更好地理解Web開發,去年開始嘗試使用公司使用的前端框架React來搭建團隊內部使用的系統。經過這個項目的開發,也讓我更好地理解了前端同事的不容易,更加堅決了寫好接口文檔的決心。css

最近在把本身作的這個內部系統遷移到公司的統一平臺的時候,遇到了一個小問題,公司要求打包的目錄名必須爲dist,而我這個項目是使用create-react-app搭建的,因此打包的目錄是默認的build前端

遂開始了查找如何修改打包目錄的資料。隨便在網上一搜,即是以下的解決方案:react

使用eject命令暴露配置,而後修改打包地址

使用這個命令,是不可逆的,執行以前,請將代碼備份或提交版本庫git

一、使用eject命令暴露配置:github

npm run eject

二、修改暴露出的配置文件config/path.js,將appBuild修改成須要輸出的位置。npm

三、使用npm install命令安裝依賴,而後執行npm run build打包後端

這個方案固然一點毛病都沒有,經過這個能夠認識到,create-react-app在建立React項目的時候,是隱藏了許多開發者不須要過多關心的配置項的,儘可能簡化了前端的開發。而eject命令則可讓這些配置項暴露出來。前端框架

eject的弊端

要注意的是,eject命令是不可逆的(至少官方沒有提供回退的方法)。使用了這個命令,你就要接受你的開發目錄面多了不少的配置文件和腳本。antd

這還不是最關鍵的,由於個人項目使用了antd做爲UI框架,其使用了react-app-rewired這個東東,致使我在eject以後執行npm run build會報錯。app

react-app-rewired是什麼?

做爲一個後端開發,最大的感觸就是,前端的網上資料有用的太少,由於各類框架、技術更新迭代太快,不少博客上的解決方案都已通過時了。大家看到的個人這篇文章,可能很快也會過期,可是我會把思路教給你們——話說,當遇到一個技術問題,實在解決不了怎麼辦?固然是找官方文檔了

經過在react-app-rewired官方文檔,才知道這個工具的一個功能是在不eject的狀況下,修改配置文件。上文說到的antd也是爲了實現修改配置,才引入的這個工具。既然它的功能如此,那麼用來修改打包地址應該也是可行的。

使用react-app-rewired在不eject的狀況下修改打包地址

思路雖然有了,可是對於前端基礎薄弱的後臺開發來講,仍是不知道怎麼實操,在看了幾篇issue以後,Changing the default pathsChange build output path以後,終於找到了方法。

首先固然是要引入react-app-rewired了,這裏我就不寫方法了,你們參考官方文檔,不會過期。

引入以後,會有一個config-overrides.js文件,由於我引入了antd,裏面已經有了些內容:

// 此文件是爲了ant選擇性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd選擇性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);
    return config;
};

增長以下代碼(去掉我用來標記代碼的+號哈):

// 此文件是爲了ant選擇性引入
const {injectBabelPlugin} = require('react-app-rewired');

module.exports = function override(config, env) {
    // antd選擇性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   // 修改path目錄
+   const path = require('path');
+   const paths = require('react-scripts/config/paths');
+   paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
+   config.output.path = path.join(path.dirname(config.output.path), 'dist');

    return config;
};

如此,再執行npm run build就能夠了,問題解決。

若是你已經進行了eject操做,很遺憾,只能經過版本庫回退版本了。

修復npm run start失敗的問題

作了以上的修改以後,會致使npm run start失敗,錯誤提示:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined

根據提示語分析得知應該是在npm run start模式下啓動時,path獲取有問題,方法function override(config, env)裏有個env參數,最簡單粗暴的方式——根據此參數判斷用戶時是啓動的development仍是production進而進行不一樣的處理。

按下面的方式修改代碼便可。

// 此文件是爲了ant選擇性引入
const {injectBabelPlugin} = require('react-app-rewired');

// noinspection JSUnusedLocalSymbols
module.exports = function override(config, env) {
    // antd選擇性引入
    config = injectBabelPlugin(['import', {libraryName: 'antd', libraryDirectory: 'es', style: 'css'}], config);

+   if(env === 'development'){
+       console.log('evn is development, skip build path change...')
+   } else if(env === 'production') {
+       console.log('evn is production, change build path...')
        // 修改path目錄
        const path = require('path');
        const paths = require('react-scripts/config/paths');
        paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');
        config.output.path = path.join(path.dirname(config.output.path), 'dist');
+   }
    return config;
};

尾聲:配置代碼解析

到了這裏,估計有部分同窗還不滿意爲何以上代碼可以解決問題,做爲一個外行人,我按個人理解解釋下。

const path = require('path');

這行代碼是基於require.js,是一個js進行引入包的工具。經過這行代碼,拿到path,纔可以對路徑作處理。

const paths = require('react-scripts/config/paths');

react-scripts裏面有React項目用於打包的命令,以及配置文件,若是你進行了eject,會發現config和script目錄裏的內容與react-scripts裏的同名目錄驚人的類似。能夠認爲eject是把這裏的配置暴露出來了。這裏這行代碼是爲了獲取項目的路徑配置。

paths.appBuild = path.join(path.dirname(paths.appBuild), 'dist');

這行代碼是修改配置裏的appBuild目錄,React項目在進行build的時候,都是根據這裏配置的目錄作的操做(例如檢查打包後的代碼大小,計算Gzip等),必需要修改,否則打包會失敗。

config.output.path = path.join(path.dirname(config.output.path), 'dist');

這行代碼就是實現咱們目的的根源了,修改項目打包地址。

好了,到這裏本文結束。

尾聲:福利

若是本文對你有幫助,歡迎關注、點贊、收藏一波。

最近業餘時間作了個Java+React爬蟲項目,感興趣的朋友Star一波:https://github.com/hxy91819/c...,內有福利哦!

相關文章
相關標籤/搜索