create-react-app 修改為多入口編譯的方法
需求和出發(fā)點
我們會有較多的小的單頁應(yīng)用,主要是一些簡單的頁面和活動之類。這些頁面相互之間沒有交集,但是會有一些可以共用的代碼,資源、接口、組件啥的。
對此,我們想到了兩種解決方案:
- react-router 路由方案;
- 同一個項目的多入口編譯;
針對我們的業(yè)務(wù)需求,其實 react-router 方案會有兩個小問題:
- 單個活動的修改,其實需要編譯整個項目;
- 若是不做編譯優(yōu)化,整個項目的包會比較大,但其實沒必要,當(dāng)然這個可以通過 react-router 的按需加載來解決;
權(quán)衡之下,我們還是選擇了第二個方案——改造項目成為多入口編譯。
文件結(jié)構(gòu)設(shè)計
改進(jìn)后,整個項目的結(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 文件夾下的所有文件夾都是一個獨立的項目,項目通用的代碼、資源被抽離到更外層的文件夾內(nèi),如 api、component 等,文件夾內(nèi)都會有自己的 index.html 和 index.js,這會作為該項目的 html 模板和入口文件。下面,我們看下是如何修改編譯過程的。
修改入口和出口
編譯需要指定編譯的入口和輸出的位置,在 create-react-app 本來生成的 code 中,只有單入口和單出口,但是其實 webpack 是支持多入口、多出口的。
入口修改
create-react-app 命令生成的 config 文件夾中,有個 paths.js 文件,這里面 export 了比較常用的路徑。在這里,我對 src/site 文件夾內(nèi)的文件夾進(jìn)行了遍歷,生成為對象。具體代碼如下:
// 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 屬性,將其修改為:
// 動態(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ū)分不同項目:
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 中,每個 HTML 文件的輸出,其實是一個 HtmlWebpackPlugin,我們需要添加多個 HtmlWebpackPlugin,以求生成多個 HTML:
// 動態(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啟動后,發(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,
// 指明哪些路徑映射到哪個html
rewrites: rewrites,
},
...
};
};
OK,到這里,整個改造就完成了。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React.memo?React.useMemo對項目性能優(yōu)化使用詳解
這篇文章主要為大家介紹了React.memo?React.useMemo對項目性能優(yōu)化的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
React Native實現(xiàn)進(jìn)度條彈框的示例代碼
本篇文章主要介紹了React Native實現(xiàn)進(jìn)度條彈框的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
詳解在React.js中使用PureComponent的重要性和使用方式
這篇文章主要介紹了詳解在React.js中使用PureComponent的重要性和使用方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
react項目中使用react-dnd實現(xiàn)列表的拖拽排序功能
這篇文章主要介紹了react項目中使用react-dnd實現(xiàn)列表的拖拽排序,本文結(jié)合實例代碼講解react-dnd是如何實現(xiàn),代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
react基于react-slick實現(xiàn)多圖輪播效果
React slick是一個使用React構(gòu)建的輪播組件,下面這篇文章主要給大家介紹了關(guān)于react基于react-slick實現(xiàn)多圖輪播效果的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
react-json-editor-ajrm解析錯誤與解決方案
由于歷史原因,項目中 JSON 編輯器使用的是 react-json-editor-ajrm,近期遇到一個嚴(yán)重的展示錯誤,傳入編輯器的數(shù)據(jù)與展示的不一致,這是產(chǎn)品和用戶不可接受的,本文給大家介紹了react-json-editor-ajrm解析錯誤與解決方案,需要的朋友可以參考下2024-06-06

