注:目前侧重于移动端支持,调整webpack配置后可支持PC端
常见的SPA应用做法是:webpack会把所有公共代码打成一个大包,入口html都会引用整个大包
在单页应用中,上述方案通常只需做基本的优化工作(如代码分割),但在多页面情况下,对公共代码的依赖情况不尽相同、复杂多变(A页面引用react、redux,B页面引用vuex、vue,A/B页面都用了lodash、moment等)
对于未完全使用大包的入口来说,如果直接引入所有公共文件,意味着有可能引入无用的资源,浪费网络性能
且大包中如果存在频繁变动的业务代码,将大大降低缓存的可用性。例如:大包中1%的代码发生了变动,缓存会失效,用户需要重新下载剩余99%未变动的代码
针对上述问题,解决的思路是:
- 把大包有计划地拆成多个小包(如可配置地单独打包react相关资源、helpers资源)
- 每个页面按自己的需求有针对性地引用
在解决上述问题的过程中遇到这样的问题:无法直接实现“每个页面按自己的需求有针对性地引用”
webpack中无法直接得知每个资源之间的引用关系,且html-webpack-plugin为各入口生成html时,需要手动配置插件的chunks属性来声明入口的依赖资源,不够智能
所以写了这个插件build/utils/auto-inject-plugin
,来实现提取依赖关系并将相关资源自动注入html的功能(目前只针对于当前方案)
遇到过两种声明入口的方式
-
使用配置表来指定入口
优点:无
缺点:每次新增入口都需要配置,十分麻烦
-
约定一个目录存放所有入口
优点:约定大于配置,消除了配置成本
缺点:文件夹不好整理,如果将来页面很多,约定目录展开后看着眼睛会疼
目前采用的是上述第二种方法的升级版:以约定好的入口命名方式 <name> @[alias]
来实现自动采集,避免了上述存在的问题
-
自由的代码分割,在
build/entries.js
文件中配置代码分割- 多页面(project),每个页面一个js
- 不同第三方库(lib)可定制化打包成某个js
- 支持多个公共业务库(vendor),每个库一个js
- 使用了
AutoDllPlugin
功能加快编译速度,但dll文件可能会对lib文件依赖造成影响,未了解其中原理需慎用
-
稳定的模块版本控制,各模块改动时,尽可能不影响其他模块的hash值,保证对资源缓存的最大利用
-
支持多框架共存(目前内置了
react
、vue
),如A页面用react,B页面用vue,并引入了常用的工具,如下-
react:
react-router
antd-mobile
- 按需打包
- 支持主题自定义,主题配置文件为
build/utils/antd-mobile/default.less
- 默认高清方案
redux
(集成了以下中间件)immutable
mobx
-
vue:
vue-router
mint-ui
(按需打包)vuex
-
-
内置了
babel-polyfill
垫片库,支持es各种新特性(装饰器、async/await等) -
样式支持(抽取成独立的css文件)
- 业务样式支持scss、sass、css
- 第三方样式支持css、less
- 支持
cssModule
,需要使用.m.css、.m.scss、.m.sass文件后缀
-
引入
postcss
,启用以下插件-
cssnext
支持最新css语法,内置了autoprefixer
,兼容浏览器为[iOS > 7, Android >= 4.0]
-
cssnano
对样式文件进行压缩 -
postcss-combine-duplicated-selectors
对样式或属性进行合并 -
postcss-viewport-units
配合viewport-units-buggyfill
修复浏览器对vw
、vh
、vmin
、vmax
的兼容性 -
postcss-px-to-viewport
自动将px转换为vw以支持高清方案(未全局开启) -
postcss-write-svg
支持css内编写svg,用以实现1px-border
-
-
高清方案方面,
flexible.js
官方推荐使用viewport方案代替rem,参考《如何在Vue项目中使用vw实现移动端适配》,目前脚手架中已经默认启用了此方案,如使用px单位会自动转为vw,设计稿尺寸为750px,原flexible.js
方案可使用但未开启 -
默认采用根目录下的
template.html
作为各入口html模板,可在入口目录下使用index.html
文件自定义html,需要注意保留资源的动态注入模板
-
业务代码存放在
src
目录中,每个入口文件夹名称必须符合<name> @[alias]
格式,入口文件必须为index.js
-
src/project
中为多页面入口代码 -
src/vendor
中为业务公共部分代码
- 使用以下命令进行开发构建
npm start
-
启动服务器后,浏览器打开
localhost:10001/wmp/任意页面名
来进行浏览
- 使用以下命令进行开发构建
npm run build
- 若要启动dist服务器,使用以下命令,服务器默认运行在10000端口
npm run server:dist
-
start
命令中包含了dll
命令,作用是尽可能将使用到的第三方资源打包成静态包,加快开发构建的速度所以在第三方资源不变动的情况下,
start
命令只需执行一次,后续开发构建的启动直接使用以下命令npm run dev
如果明确得知第三方资源发生了变动,需再执行一次
start
命令(不执行也可,不过dev
速度会受到影响) -
我们在开发多页应用时,一般来说不会同时关注所有页面的开发工作,一次只会负责一个或数个页面的开发
针对这个特性,我们在开发构建时可以指定(或忽略)部分入口以加快构建速度,具体操作如下
在根目录下创建名为
__entry.config.js
的文件(此文件被git忽略),文件内容示例为:module.exports = { include: [ /demo/ ], exclude: [ /vue/ ] }
include
为指定包含的入口,exclude
为需要排除的入口,每个项的内容为匹配入口路径的正则表达式