注:目前侧重于移动端支持,调整webpack配置后可支持PC端
常见的SPA应用做法是:webpack会把所有公共代码打成一个大包,入口html都会引用整个大包
在单页应用中,上述方案通常只需做基本的优化工作(如代码分割),但在多页面情况下,对公共代码的依赖情况不尽相同、复杂多变(A页面引用react、redux,B页面引用vuex、vue,A/B页面都用了lodash、moment等)
对于未完全使用大包的入口来说,如果直接引入所有公共文件,意味着有可能引入无用的资源,浪费网络性能
且大包中如果存在频繁变动的业务代码,将大大降低缓存的可用性。例如:大包中1%的代码发生了变动,缓存会失效,用户需要重新下载剩余99%未变动的代码
针对上述问题,解决的思路是:
在解决上述问题的过程中遇到这样的问题:无法直接实现 每个页面按自己的需求有针对性地引用
webpack中无法直接得知每个资源之间的引用关系,且html-webpack-plugin为各入口生成html时,需要手动配置插件的chunks属性来声明入口的依赖资源,不够智能
所以写了这个插件build/utils/auto-inject-plugin
,来实现提取依赖关系并将相关资源自动注入html的功能(目前只针对于当前方案)
遇到过两种声明入口的方式
使用配置表来指定入口
优点:无
缺点:每次新增入口都需要配置,十分麻烦
约定一个目录存放所有入口
优点:约定大于配置,消除了配置成本
缺点:文件夹不好整理,如果将来页面很多,约定目录展开后看着眼睛会疼
目前采用的是上述第二种方法的升级版:以约定好的入口命名方式 <name> @[alias]
来实现自动采集,避免了上述存在的问题
自由的代码分割,在build/entries.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文件)
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,设计稿尺寸为720px
默认采用根目录下的template.html
作为各入口html模板,可在入口目录下使用index.html
文件自定义html,需要注意保留资源的动态注入模板
业务代码存放在src
目录中,每个入口文件夹名称必须符合 <name> @[alias]
格式,入口文件必须为index.js
src/project
中为多页面入口代码
src/vendor
中为业务公共部分代码
npm start
启动服务器后,浏览器打开localhost:10001/wmp/任意页面名
来进行浏览
npm run build
npm run server:dist
start
命令中包含了dll
命令,作用是尽可能将使用到的第三方资源打包成静态包,加快开发构建的速度
所以在第三方资源不变动的情况下,start
命令只需执行一次,后续开发构建的启动直接使用以下命令
npm run dev
如果明确得知第三方资源发生了变动,需再执行一次start
命令(不执行也可,不过dev
速度会受到影响)
我们在开发多页应用时,一般来说不会同时关注所有页面的开发工作,一次只会负责一个或数个页面的开发
针对这个特性,我们在开发构建时可以指定(或忽略)部分入口以加快构建速度,具体操作如下
在根目录下创建名为__entry.config.js
的文件(此文件被git忽略),文件内容示例为:
module.exports = {
include: [
/demo/
],
exclude: [
/vue/
]
}
include
为指定包含的入口,exclude
为需要排除的入口,每个项的内容为匹配入口路径的正则表达式