create-react-app 修改為多入口編譯的方法
需求和出發(fā)點(diǎn)
我們會(huì)有較多的小的單頁應(yīng)用,主要是一些簡單的頁面和活動(dòng)之類。這些頁面相互之間沒有交集,但是會(huì)有一些可以共用的代碼,資源、接口、組件啥的。
對(duì)此,我們想到了兩種解決方案:
- react-router 路由方案;
- 同一個(gè)項(xiàng)目的多入口編譯;
針對(duì)我們的業(yè)務(wù)需求,其實(shí) react-router 方案會(huì)有兩個(gè)小問題:
- 單個(gè)活動(dòng)的修改,其實(shí)需要編譯整個(gè)項(xiàng)目;
- 若是不做編譯優(yōu)化,整個(gè)項(xiàng)目的包會(huì)比較大,但其實(shí)沒必要,當(dāng)然這個(gè)可以通過 react-router 的按需加載來解決;
權(quán)衡之下,我們還是選擇了第二個(gè)方案——改造項(xiàng)目成為多入口編譯。
文件結(jié)構(gòu)設(shè)計(jì)
改進(jìn)后,整個(gè)項(xiàng)目的結(jié)構(gòu)大體如下:
- project - build - config - public - scripts - src - api - component - site - site1 - index.html - index.js - ... - site2 - index.html - index.js - ... - package.json
site 文件夾下的所有文件夾都是一個(gè)獨(dú)立的項(xiàng)目,項(xiàng)目通用的代碼、資源被抽離到更外層的文件夾內(nèi),如 api、component 等,文件夾內(nèi)都會(huì)有自己的 index.html 和 index.js,這會(huì)作為該項(xiàng)目的 html 模板和入口文件。下面,我們看下是如何修改編譯過程的。
修改入口和出口
編譯需要指定編譯的入口和輸出的位置,在 create-react-app 本來生成的 code 中,只有單入口和單出口,但是其實(shí) webpack 是支持多入口、多出口的。
入口修改
create-react-app 命令生成的 config 文件夾中,有個(gè) paths.js 文件,這里面 export 了比較常用的路徑。在這里,我對(duì) src/site 文件夾內(nèi)的文件夾進(jìn)行了遍歷,生成為對(duì)象。具體代碼如下:
// all site paths function allSitePath(source) { const { lstatSync, readdirSync } = fs const { join } = path const result = {} const isDirectory = source => lstatSync(source).isDirectory() readdirSync(source).map(name => { let path = join(resolveApp(source), name) if (isDirectory(path)) result[name] = path }) return result } module.exports = { ... allSites: allSitePath('src/site'), }
在 webpack.config.dev.js / webpack.config.prod.js 中找到 module.exports 的 entry 屬性,將其修改為:
// 動(dòng)態(tài)生成 entry const entry = {} Object.keys(paths.allSites).forEach(item => { entry[item] = [ require.resolve('./polyfills'), require.resolve('react-dev-utils/webpackHotDevClient'), require.resolve('react-error-overlay'), paths.allSites[item] ] }) module.exports = { ... entry: entry, ... }
出口修改
出口的修改分為兩部分,一部分是 module.exports 的 output,添加 name 以使靜態(tài)資源區(qū)分不同項(xiàng)目:
module.exports = { ... output: { path: paths.appBuild, pathinfo: true, filename: 'static/js/[name].bundle.js', chunkFilename: 'static/js/[name].chunk.js', publicPath: publicPath, devtoolModuleFilenameTemplate: info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'), }, ... }
另一部分是 plugin 的修改,webpack 中,每個(gè) HTML 文件的輸出,其實(shí)是一個(gè) HtmlWebpackPlugin,我們需要添加多個(gè) HtmlWebpackPlugin,以求生成多個(gè) HTML:
// 動(dòng)態(tài)生成 plugins const plugins = [] Object.keys(paths.allSites).forEach(item => { plugins.push(new HtmlWebpackPlugin({ inject: true, chunks: [item], template: `${paths.allSites[item]}/index.html`, filename: `${item}/index.html`, })) }) module.exports = { ... plugins: [ ... ].concat(plugins), ... }
修改 webpack Dev Server 配置
上述配置做完后,理論就可以打包出多入口的版本;但使用npm start啟動(dòng)后,發(fā)現(xiàn)無論輸入/index.html還是/admin.html,好像都是和原來/index.html顯示一樣的內(nèi)容。甚至輸入顯然不存在的/xxxx.html,也顯示為/index.html的內(nèi)容。
這里,我們還需要修改 /config/webpackDevServer.config.js,做一些額外配置。
const rewrites = [] Object.keys(paths.allSites).forEach(item => { rewrites.push({ from: new RegExp(`^\\/${item}/`, 'i'), to: `/${item}/index.html`, }) }) ... module.exports = function(proxy, allowedHost) { return { ... historyApiFallback: { // Paths with dots should still use the history fallback. // See https://github.com/facebookincubator/create-react-app/issues/387. disableDotRule: true, // 指明哪些路徑映射到哪個(gè)html rewrites: rewrites, }, ... }; };
OK,到這里,整個(gè)改造就完成了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React.memo?React.useMemo對(duì)項(xiàng)目性能優(yōu)化使用詳解
這篇文章主要為大家介紹了React.memo?React.useMemo對(duì)項(xiàng)目性能優(yōu)化的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01React Native實(shí)現(xiàn)進(jìn)度條彈框的示例代碼
本篇文章主要介紹了React Native實(shí)現(xiàn)進(jìn)度條彈框的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07詳解在React.js中使用PureComponent的重要性和使用方式
這篇文章主要介紹了詳解在React.js中使用PureComponent的重要性和使用方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07react項(xiàng)目中使用react-dnd實(shí)現(xiàn)列表的拖拽排序功能
這篇文章主要介紹了react項(xiàng)目中使用react-dnd實(shí)現(xiàn)列表的拖拽排序,本文結(jié)合實(shí)例代碼講解react-dnd是如何實(shí)現(xiàn),代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02react基于react-slick實(shí)現(xiàn)多圖輪播效果
React slick是一個(gè)使用React構(gòu)建的輪播組件,下面這篇文章主要給大家介紹了關(guān)于react基于react-slick實(shí)現(xiàn)多圖輪播效果的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07react-json-editor-ajrm解析錯(cuò)誤與解決方案
由于歷史原因,項(xiàng)目中 JSON 編輯器使用的是 react-json-editor-ajrm,近期遇到一個(gè)嚴(yán)重的展示錯(cuò)誤,傳入編輯器的數(shù)據(jù)與展示的不一致,這是產(chǎn)品和用戶不可接受的,本文給大家介紹了react-json-editor-ajrm解析錯(cuò)誤與解決方案,需要的朋友可以參考下2024-06-06