Vue或React的多页应用脚手架

  1. 云栖社区>
  2. 博客>
  3. 正文

Vue或React的多页应用脚手架

行者武松 2017-08-01 14:58:00 浏览1948
展开阅读全文

前言

一直以来都在研究多页应用如何能有一套像SPA一样优雅的开发模式

本套架构在项目上使用感觉还不错(已跑在上百个页面的项目上),所以决定开源出来给大家

阅读完本文能实现在项目中使用ES6(7)+组件化(.vue | .jsx)开发多页应用

(其实我是想把它做为大家多页应用的脚手架)

目录结构介绍

TIPS:任何的项目的架构都和目录结构有关,所以这部分非常重要,请仔细耐心阅读

我们先宏观的看下结构


  1. |--- public // 生产环境下所需的文件 
  2.     |--- static 
  3.         |--- css 
  4.         |--- es6 
  5.         |--- fonts 
  6.         |--- images 
  7.     |--- views 
  8. |--- src 
  9.     |--- assets 
  10.         |--- fonts 
  11.         |--- images 
  12.     |--- components 
  13.     |--- js 
  14.     |--- sass 
  15.     |--- static 
  16.         |--- css 
  17.         |--- es6 
  18.         |--- fonts 
  19.         |--- images 
  20.     |--- views  

src里的assets,components,js,sass里的文件最后都会生成到src/static下,这个作为我们dev中引用的资源文件。而public不用说,是线上访问的文件。

我们展开介绍下具体的页面应该如何对应它的资源。拿js和views为例


  1. |--- views 
  2.     |--- home // 官网介绍 业务模块 
  3.         |--- index.html 
  4.         ... 
  5.     |--- shopping // 购物业务模块 
  6.         |--- buy.html 
  7.         ... 
  8. |--- js 
  9.     |--- lib 
  10.         |--- vue.js 
  11.         |--- react.js 
  12.         |--- react.dom.js 
  13.         ... 
  14.     |--- home // 官网介绍业务模块的js 
  15.         |--- index.js 
  16.         ... 
  17.     |--- shopping // 购物业务模块的js 
  18.         |--- buy.js 
  19.         ... 
  20.     tools.js 
  21.     common.js  

在多页应用中,往往我们的页面以业务模块划分,业务模块由许多的页面组成。

如home,shopping,可能就分别为官网介绍和购物的业务模块。在这业务模块下,分别有许多个页面,那我们的js文件也需要命名一一对应。

当然,我们还有第三方的js库是不需要编译的,所以我们专门用一个lib文件夹来存放他们。(包括你自己编写的指令或者filter等,不需要编译的,也直接放在lib下引入即可)

另外,你还有许多自己写的需要编译的工具库直接放在js目录下即可(如,tools.js,common.js)

我们的sass也是同理


  1. |--- sass 
  2.     |--- home 
  3.         |--- index.scss 
  4.         ... 
  5.     |--- shopping 
  6.         |--- buy.scss 
  7.         ...  

他们编译在static下的文件将为


  1. |--- static 
  2.     |--- css // scss 编译后的 
  3.         |--- home 
  4.             |--- index.css 
  5.         |--- shopping 
  6.             |--- buy.css 
  7.     |--- js // babel处理后的js 
  8.         |--- home 
  9.             |--- index.js 
  10.         |--- shopping 
  11.             |--- buy.js  

页面引用的路径就为(home/index.html为例)


  1. ... 
  2. <link rel="stylesheet" href="../../static/css/home/index.css"
  3.  
  4. ... 
  5.  
  6. <script src="../../static/es6/lib/vue(react).js"></script> 
  7. <script src="../../static/es6/lib/react.dom.js"></script> 
  8. <script src="../../static/es6/home/index.js"></script> 
  9. ...  

js和sass搞定了后,我们的难点是编写组件的过程中,如何知道应该编译哪个入口js文件呢?

所以我们需要对我们的组件名进行一些约定,这也就是约定大于配置的前提。


  1. |--- components 
  2.     |--- home // home 业务模块 
  3.         |--- home-header.vue(jsx) 
  4.         |--- index-info.vue(jsx) 
  5.         ... 
  6.     |--- shopping  // shopping 业务模块 
  7.         |--- buy-list.vue(jsx) 
  8.         ...  

我们components下的业务模块名和之前的sass,js一样。具体组件那就有所不同。

我们分为几种类型的组件

一、当前页面使用的组件

二、当前业务模块下的公用组件

三、所有业务模块的通用组件

当前页面组件的命名,我们约定为 [页面]-[组件].vue(jsx)

如下


  1. |--- components 
  2.     |--- home 
  3.         |--- index-info.vue(jsx)  

这个 index-info 的组件就仅仅只有在home/index.html页面下使用,当你修改了这个组件后,会自动编译home/index.js路口js文件并刷新页面。

当前业务模块下的公用组件,我们约定为 [业务模块]-[组件].vue(jsx)

如下


  1. |--- components 
  2.     |--- common 
  3.         |--- loading.vue(jsx)  

这个home-header组件就属于home业务模块下的公用组件,当你修改了这个组件后,会自动编译home业务模块下所有的js文件并刷新页面。

剩下的就是所有业务模块下的通用组件,我们约定全放在components/common目录下,不需要具体命名约定


  1. |--- components 
  2.     |--- common 
  3.         |--- loading.vue(jsx)  

这个loading组件就属于所有业务模块下的公用组件,当你修改了这个组件后,会自动编译所有业务模块下的js文件并刷新页面。

编译组件的原理以及为什么约定命名的原因是:

我会根据组件更改变动,去读取文件夹名,组件名,并编译对应名的路口js

至此,我们就把组件的问题也解决了

由于我采用的是主gulp辅webpack,webpack仅仅只编译用,所以编译基本达到秒编译。比单纯利用webpack做构建快得多。如果单纯采用webpack做构建,需要去配置entry,配置HTMLPlugin。所以会慢得多,然而我这一套并不需要如此繁琐。

图片&&字体文件

这其实是一个大坑

我们的实现目标是组件能相对路径引入图片或字体文件


  1. // 如 在html标签里这样 
  2. <template> 
  3.     <figure> 
  4.         <img src="../../assets/images/home/logo.jpg" alt="头像"
  5.     </figure> 
  6. </template> 
  7.  
  8. // 在style里这样 
  9. <style rel="stylesheet/scss" lang="sass"
  10.     @import "../../sass/home/index-info"
  11.     // 甚至可能在这@import面引入相对路径,这都会算是在组件里引入相对路径 
  12.     #bg h3 { 
  13.         background: url("../../assets/images/holmes.jpg"); 
  14.         color: #fff; 
  15.     } 
  16. </style>  

这个坑,真是不可描述,我个人尝试了各种体位,才把这个坑配置好。

直接给大家看最后实现是怎样的。

dev 的路径是这样,页面可以显示图片或字体。

build 后的路径是这样

这样就达到了开发和发布后的资源统一,摸索这一步真是挺累的 T.T,有兴趣的自己看源码吧。

环境变量的配置

我们在webpack中经常会遇见不同环境下不同配置的问题

首先可在package.json里配置一条script


  1. // package.json 
  2. "scripts": { 
  3.     "build""NODE_ENV=production gulp build"
  4.     "dev""NODE_ENV=dev gulp reload" 
  5. },  

假设我们需要为不同环境配置不同的api请求地址,就可以利用我们在package.json设置的NODE_ENV来识别当前环境(这部分我在gulpfile中处理了,所以在文件里可直接识别NODE_ENV,如下)


  1. //  src/js/ajaxurl.js 
  2.   
  3. const server1 = 'https://production.server.com'
  4. const server2 = 'https://dev.server.com'
  5.  
  6. let useServer = null
  7. if(NODE_ENV === 'production') { 
  8.     useServer = server1; 
  9. else if(NODE_ENV === 'dev') { 
  10.     useServer = server2; 
  11.  
  12. export default useServer; 
  13. // src/js/home/index.js 
  14.  
  15. import url from '../ajaxurl'
  16. console.log(url);  

这样就解决了我们不同环境下不同配置的问题,我默认配置了dev和production,大家可以自行拓展。比如

假设你需要在 开发中 配置测试,你可以写一条NODE_ENV=test gulp reload。

如果需要 预发布打包 测试,就可以另一条NODE_ENV=preproduction gulp build。

总之就是打包使用gulp build,开发使用gulp reload。

注意事项

开发:执行命令 npm run dev

发布:执行命令 npm run build (BTW,别忘了去gulpfile.js里替换你的CDN链接,进入gulp文件修改 const CDN = 'yourCDNLink'这里的变量即可)

命名一定要按约定来!

命名一定要按约定来!

命名一定要按约定来!

否则不知道要编译谁!!!

gulp配置很简单,大家可以看一下针对各自项目进行修改,不懂得可以直接问我。

如果你们不完全的前后端分离,把这个src直接放在后台目录下也没有问题。

写vue和react都没问题,我把示例demo都写好了,下面是分别两个的repo地址。

vue-multpage : https://github.com/MeCKodo/vue-multipage

react-multpage : https://github.com/MeCKodo/react-multipage

TODO

  • [ ] 项目的Unit test
  • [ ] 项目Cli脚手架

后话

本来是想写成vue-cli或者是create-react-app这种cli脚手架的,但是!本人真是太懒又没有时间了! 各位看官可以先尝试clone把玩把玩,如果有足够多人喜欢,我就把他写成cli,发布npm :)

我是用mac下开发完成的,用了半天多时间专门去给window写了兼容,window还可能会有bug,不是我说!window就是辣鸡!

最后给大家看下我们的某项目结构。

总览

js部分

sass部分

组件和页面



作者:二哲

来源:51CTO

网友评论

登录后评论
0/500
评论
行者武松
+ 关注