{"id":14976452,"url":"https://github.com/cjy0208/webpack-multiple-pages","last_synced_at":"2025-10-27T20:31:58.065Z","repository":{"id":38291138,"uuid":"119158096","full_name":"CJY0208/webpack-multiple-pages","owner":"CJY0208","description":"自由代码分割、react/vue共存、支持高清方案、代码自动校验与格式化","archived":false,"fork":false,"pushed_at":"2022-12-09T04:42:36.000Z","size":5310,"stargazers_count":64,"open_issues_count":29,"forks_count":11,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-01T08:06:50.050Z","etag":null,"topics":["react","vue","webpack3"],"latest_commit_sha":null,"homepage":"https://cjy0208.github.io/webpack-multiple-pages/tweenDemo.html","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CJY0208.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-27T11:25:44.000Z","updated_at":"2024-08-26T08:03:54.000Z","dependencies_parsed_at":"2023-01-25T16:16:34.530Z","dependency_job_id":null,"html_url":"https://github.com/CJY0208/webpack-multiple-pages","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJY0208%2Fwebpack-multiple-pages","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJY0208%2Fwebpack-multiple-pages/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJY0208%2Fwebpack-multiple-pages/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CJY0208%2Fwebpack-multiple-pages/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CJY0208","download_url":"https://codeload.github.com/CJY0208/webpack-multiple-pages/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238553274,"owners_count":19491399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react","vue","webpack3"],"created_at":"2024-09-24T13:53:54.584Z","updated_at":"2025-10-27T20:31:57.447Z","avatar_url":"https://github.com/CJY0208.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Webpack Multiple Pages\n\n**注：目前侧重于移动端支持，调整webpack配置后可支持PC端**\n\n- - -\n\n### 要解决的问题\n\n#### 资源的拆分与缓存的利用\n\n常见的SPA应用做法是：webpack会把所有公共代码打成一个大包，入口html都会引用整个大包\n\n在单页应用中，上述方案通常只需做基本的优化工作（如代码分割），但在多页面情况下，对公共代码的依赖情况不尽相同、复杂多变（A页面引用react、redux，B页面引用vuex、vue，A/B页面都用了lodash、moment等）\n\n对于未完全使用大包的入口来说，如果直接引入所有公共文件，意味着有可能引入无用的资源，浪费网络性能\n\n且大包中如果存在频繁变动的业务代码，将大大降低缓存的可用性。例如：大包中1%的代码发生了变动，缓存会失效，用户需要重新下载剩余99%未变动的代码\n\n针对上述问题，解决的思路是：\n- 把大包有计划地拆成多个小包（如可配置地单独打包react相关资源、helpers资源）\n- 每个页面按自己的需求有针对性地引用\n\n#### 入口资源按需引用\n\n在解决上述问题的过程中遇到这样的问题：无法直接实现 **`每个页面按自己的需求有针对性地引用`** \n\nwebpack中无法直接得知每个资源之间的引用关系，且html-webpack-plugin为各入口生成html时，需要手动配置插件的chunks属性来声明入口的依赖资源，不够智能\n\n所以写了这个插件`build/utils/auto-inject-plugin`，来实现提取依赖关系并将相关资源自动注入html的功能（目前只针对于当前方案）\n\n#### 如何配置多入口\n\n遇到过两种声明入口的方式\n\n1. 使用配置表来指定入口\n\n\t优点：无\n\n\t缺点：每次新增入口都需要配置，十分麻烦\n\n2. 约定一个目录存放所有入口\n\n\t优点：约定大于配置，消除了配置成本\n\n\t缺点：文件夹不好整理，如果将来页面很多，约定目录展开后看着眼睛会疼\n\n目前采用的是上述第二种方法的升级版：以约定好的入口命名方式 `\u003cname\u003e @[alias]` 来实现自动采集，避免了上述存在的问题\n\n- - -\n\n### 特性介绍\n\n1. 自由的代码分割，在`build/entries.js`文件中配置代码分割\n\n\t- 多页面（*project*），每个页面一个js\n\t- 不同第三方库（*lib*）可定制化打包成某个js\n\t- 支持多个公共业务库（*vendor*），每个库一个js\n\t- 使用了[`AutoDllPlugin`](https://github.com/asfktz/autodll-webpack-plugin)功能加快编译速度，**但dll文件可能会对lib文件依赖造成影响，未了解其中原理需慎用**\n\n2. 稳定的模块版本控制，各模块改动时，尽可能不影响其他模块的hash值，保证对资源缓存的最大利用\n\n3. 支持多框架共存（目前内置了[`react`](https://reactjs.org/)、[`vue`](https://cn.vuejs.org/)），如A页面用react，B页面用vue，并引入了常用的工具，如下\n\n\t- react：\n\t\t- [`react-router`](https://github.com/ReactTraining/react-router)\n\t\t- [`antd-mobile`](https://github.com/ant-design/ant-design-mobile)\n\t\t\t- 按需打包\n\t\t\t-\t支持主题自定义，主题配置文件为`build/utils/antd-mobile/default.less`\n\t\t\t- 默认高清方案\n\t\t- [`redux`](http://www.redux.org.cn/)（集成了以下中间件）\n\t\t\t-\t[`redux-thunk`](https://github.com/gaearon/redux-thunk)\n\t\t\t- [`redux-promise`](https://github.com/redux-utilities/redux-promise)\n\t\t\t- [`redux-actions`](https://github.com/redux-utilities/redux-actions)\n\t\t\t- [`redux-persist`](https://github.com/rt2zz/redux-persist)\n\t\t- [`immutable`](http://facebook.github.io/immutable-js/docs/#/)\n\t\t- [`mobx`](http://cn.mobx.js.org/)\n\n\t- vue：\n\t\t- [`vue-router`](https://router.vuejs.org/zh-cn/)\n\t\t- [`mint-ui`](http://mint-ui.github.io/#!/zh-cn)（按需打包）\n\t\t- [`vuex`](https://vuex.vuejs.org/zh-cn/)\n\n4. [`eslint`](http://eslint.cn/)代码校验，[`prettier`](https://prettier.io/)格式化（commit时自动格式化）\n\n5. 内置了[`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/)垫片库，支持es各种新特性（装饰器、async/await等）\n\n6. 样式支持（抽取成独立的css文件）\n\t\n\t- 业务样式支持scss、sass、css\n\t- 第三方样式支持css、less\n\t- 支持[`cssModule`](http://www.ruanyifeng.com/blog/2016/06/css_modules.html)，需要使用.m.css、.m.scss、.m.sass文件后缀\n\n7. 引入[`postcss`](https://github.com/postcss/postcss/blob/master/README.cn.md)，启用以下插件\n\n\t- [`cssnext`](http://cssnext.io/)支持最新css语法，内置了[`autoprefixer`](https://github.com/postcss/autoprefixer)，兼容浏览器为 [`[iOS \u003e 7, Android \u003e= 4.0]`](https://github.com/ai/browserslist#queries)\n\n\t- [`cssnano`](http://cssnano.co/)对样式文件进行压缩\n\n\t- [`postcss-combine-duplicated-selectors`](https://github.com/ChristianMurphy/postcss-combine-duplicated-selectors)对样式或属性进行合并\n\n\t- [`postcss-viewport-units`](https://github.com/springuper/postcss-viewport-units)配合[`viewport-units-buggyfill`](https://github.com/rodneyrehm/viewport-units-buggyfill)修复浏览器对`vw`、`vh`、`vmin`、`vmax`的兼容性\n\n\t- [`postcss-px-to-viewport`](https://github.com/evrone/postcss-px-to-viewport)自动将px转换为vw以支持高清方案（未全局开启）\n\n\t- [`postcss-write-svg`](https://github.com/jonathantneal/postcss-write-svg)支持css内编写svg，用以实现[1px-border](https://www.w3cplus.com/css/fix-1px-for-retina.html)\n\n8. 集成了部分常用工具：[`lodash`](https://lodash.com/)、[`lodash/fp`](https://github.com/lodash/lodash/wiki/FP-Guide)、[`axios`](https://github.com/axios/axios)、[`date-fns`](https://date-fns.org/)、[`md5`](https://github.com/pvorb/node-md5)、[`fastclick`](https://github.com/ftlabs/fastclick)\n\n9. 高清方案方面，[`flexible.js`](https://github.com/amfe/lib-flexible)官方推荐使用viewport方案代替rem，参考[《如何在Vue项目中使用vw实现移动端适配》](https://www.w3cplus.com/mobile/vw-layout-in-vue.html)，目前脚手架中已经**默认启用了此方案，如使用px单位会自动转为vw，设计稿尺寸为720px**\n\n10. 默认采用根目录下的`template.html`作为各入口html模板，可在入口目录下使用`index.html`文件自定义html，需要注意保留资源的动态注入模板\n- - -\n\n### 业务入口约定\n\n- 业务代码存放在`src`目录中，每个入口文件夹名称必须符合 `\u003cname\u003e @[alias]` 格式，入口文件必须为`index.js`\n\n- `src/project`中为多页面入口代码\n\n- `src/vendor`中为业务公共部分代码\n\n- - -\n\n### 开发构建启动方式\n\n1. 使用以下命令进行开发构建\n\n```bash\nnpm start\n```\n\n2. 启动服务器后，浏览器打开`localhost:10001/wmp/任意页面名` 来进行浏览\n\n\t例如 [`localhost:10001/wmp/reduxCouterDemo`](http://localhost:10001/wmp/reduxCouterDemo)\n\n- - -\n\n### 编译方式\n\n1. 使用以下命令进行开发构建\n\n```bash\nnpm run build\n```\n\n2. 若要启动dist服务器，使用以下命令，服务器默认运行在10000端口\n\n```bash\nnpm run server:dist\n```\n- - -\n\n### 开发时构建的提速说明\n\n1. `start`命令中包含了`dll`命令，作用是尽可能将使用到的第三方资源打包成静态包，加快开发构建的速度\n\n\t所以在第三方资源不变动的情况下，`start`命令只需执行一次，后续开发构建的启动直接使用以下命令\n\n\t```bash\n\tnpm run dev\n\t```\n\n\t如果明确得知第三方资源发生了变动，需再执行一次`start`命令（不执行也可，不过`dev`速度会受到影响）\n\n2. 我们在开发多页应用时，一般来说不会同时关注所有页面的开发工作，一次只会负责一个或数个页面的开发\n\n\t针对这个特性，我们在开发构建时可以指定（或忽略）部分入口以加快构建速度，具体操作如下\n\n\t在根目录下创建名为`__entry.config.js`的文件（此文件被git忽略），文件内容示例为：\n\n\t```javascript\n\tmodule.exports = {\n\t  include: [\n\t    /demo/\n\t  ],\n\t  exclude: [\n\t    /vue/\n\t  ]\n\t}\n\t```\n\n\t`include`为指定包含的入口，`exclude`为需要排除的入口，每个项的内容为`匹配入口路径的正则表达式`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjy0208%2Fwebpack-multiple-pages","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjy0208%2Fwebpack-multiple-pages","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjy0208%2Fwebpack-multiple-pages/lists"}