首页 > 语言 > JavaScript > 正文

create-react-app 修改为多入口编译的方法

2024-05-06 15:32:16
字体:
来源:转载
供稿:网友

需求和出发点

我们会有较多的小的单页应用,主要是一些简单的页面和活动之类。这些页面相互之间没有交集,但是会有一些可以共用的代码,资源、接口、组件啥的。

对此,我们想到了两种解决方案:

react-router 路由方案; 同一个项目的多入口编译;

针对我们的业务需求,其实 react-router 方案会有两个小问题:

单个活动的修改,其实需要编译整个项目; 若是不做编译优化,整个项目的包会比较大,但其实没必要,当然这个可以通过 react-router 的按需加载来解决;

权衡之下,我们还是选择了第二个方案——改造项目成为多入口编译。

文件结构设计

改进后,整个项目的结构大体如下:

- project  - build  - config  - public  - scripts  - src    - api    - component    - site      - site1        - index.html        - index.js        - ...      - site2        - index.html        - index.js        - ...  - package.json

site 文件夹下的所有文件夹都是一个独立的项目,项目通用的代码、资源被抽离到更外层的文件夹内,如 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, '/'), }, ...}             
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选