时间:2021-05-28
需求和出发点
我们会有较多的小的单页应用,主要是一些简单的页面和活动之类。这些页面相互之间没有交集,但是会有一些可以共用的代码,资源、接口、组件啥的。
对此,我们想到了两种解决方案:
针对我们的业务需求,其实 react-router 方案会有两个小问题:
权衡之下,我们还是选择了第二个方案——改造项目成为多入口编译。
文件结构设计
改进后,整个项目的结构大体如下:
- project - build - config - public - scripts - src - api - component - site - site1 - index.html - index.js - ... - site2 - index.html - index.js - ... - package.jsonsite 文件夹下的所有文件夹都是一个独立的项目,项目通用的代码、资源被抽离到更外层的文件夹内,如 api、component 等,文件夹内都会有自己的 index.html 和 index.js,这会作为该项目的 html 模板和入口文件。下面,我们看下是如何修改编译过程的。
修改入口和出口
编译需要指定编译的入口和输出的位置,在 create-react-app 本来生成的 code 中,只有单入口和单出口,但是其实 webpack 是支持多入口、多出口的。
入口修改
create-react-app 命令生成的 config 文件夹中,有个 paths.js 文件,这里面 export 了比较常用的路径。在这里,我对 src/site 文件夹内的文件夹进行了遍历,生成为对象。具体代码如下:
// all site pathsfunction 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 属性,将其修改为:
// 动态生成 entryconst 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 以使静态资源区分不同项目:
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:
// 动态生成 pluginsconst 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启动后,发现无论输入/index.html还是/admin.html,好像都是和原来/index.html显示一样的内容。甚至输入显然不存在的/xxxx.html,也显示为/index.html的内容。
这里,我们还需要修改 /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,到这里,整个改造就完成了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
前提条件请先进行全局安装create-react-app插件哈,安装命令:npminstallcreate-react-app-g先使用create-react
使用antd按需加载使用react-app-rewired对create-react-app的默认配置进行自定义1、yarnaddreact-app-rewir
前言create-react-app是由React官方提供并推荐使用构建新的React单页面应用程序的最佳方式,其构建的项目默认是不支持less的,需要我们手动
没有去修改create-react-app默认的配置文件执行npmstart一切正常,但是npmrunbuild之后生成的打包文件只能在根目录访问这样放在服务器
React降级配置1.使用create-react-app创建一个目录2.查看当前目录下的package.json文件中的配置注意:可以看到当前的react-s