前言

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

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

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

如果你不需要SEO,需要前后端分离,项目是多页应用,选择我就对了

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

目录结构介绍

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

我们先宏观的看下结构

|--- public // 生产环境下所需的文件|--- components|--- css|--- fonts|--- images|--- js|--- sass|--- views
|--- src|--- components|--- css|--- fonts|--- images|--- js|--- sass|--- views复制代码

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

|--- views|--- home // 官网介绍 业务模块|--- index.html...|--- shopping // 购物业务模块|--- buy.html...
|--- js|--- lib|--- vue.js|--- react.js|--- react.dom.js...|--- home // 官网介绍业务模块的js|--- index.js...|--- shopping // 购物业务模块的js|--- buy.js...tools.jscommon.js复制代码

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

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

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


我们的sass也是同理

|--- sass|--- home|--- index.scss...|--- shopping|--- buy.scss...复制代码

他们会分别编译在cssjs下的文件将为

|--- css // scss 编译后的|--- home|--- index.css|--- shopping|--- buy.css
|--- js // babel处理后的js|--- home|--- index.js|--- shopping|--- buy.js复制代码

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

...
<link rel="stylesheet" href="../../js/css/home/index.css">...<script src="../../js/lib/vue(react).js"></script>
<script src="../../js/lib/react.dom.js"></script>
<script src="../../js/home/index.js"></script>
...复制代码

js和sass搞定了后,我们的难点是编写组件的过程中,如何知道应该编译哪个入口js文件呢?
所以我们需要对我们的组件名进行一些约定,这也就是约定大于配置的前提。

|--- components|--- home // home 业务模块|--- home-header.vue(jsx)|--- index-info.vue(jsx)...|--- shopping  // shopping 业务模块|--- buy-list.vue(jsx)...复制代码

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

我们分为几种类型的组件

  • 一、当前页面使用的组件
  • 二、当前业务模块下的公用组件
  • 三、所有业务模块的通用组件

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

如下

|--- components|--- home|--- index-info.vue(jsx)复制代码

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

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

如下

|--- components|--- home|--- home-header.vue(jsx)复制代码

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

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

|--- components|--- common|--- loading.vue(jsx)复制代码

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

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

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

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

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

图片&&字体文件

这其实是一个大坑

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

// 如 在html标签里这样
<template><figure><img src="../../images/home/logo.jpg" alt="头像"></figure>
</template>// 在style里这样
<style rel="stylesheet/scss" lang="sass">@import "../../sass/home/index-info";// 甚至可能在这@import面引入相对路径,这都会算是在组件里引入相对路径#bg h3 {background: url("../../images/holmes.jpg");color: #fff;}
</style>复制代码

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

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

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

build 后的路径是这样

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

环境变量的配置

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

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

// package.json
"scripts": {"build": "NODE_ENV=production gulp build","dev": "NODE_ENV=dev gulp reload"
},复制代码

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

//  src/js/ajaxurl.jsconst server1 = 'https://production.server.com';
const server2 = 'https://dev.server.com';let useServer = null;
if(NODE_ENV === 'production') {useServer = server1;
} else if(NODE_ENV === 'dev') {useServer = server2;
}export default useServer;复制代码
// src/js/home/index.jsimport url from '../ajaxurl';
console.log(url);复制代码

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

假设你需要在 开发中 配置测试,你可以写一条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直接放在后台目录下也没有问题。

TODO

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

后话

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

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

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


总览

总览

js部分

js部分

images

images

组件

组件和页面

你们可能在总览的图会发现多了apismock文件夹,这个是我们promise封装接口层和前端本地mock层,由于每个团队的做法都不同,我就没有放在这次的脚手架里

vue-multpage 通用版: github.com/MeCKodo/vue…

这个是我们内部的版本


Have a nice day

Vue多页应用脚手架相关推荐

  1. day 83 Vue学习之五DIY脚手架、webpack使用、vue-cli的使用、element-ui

    Vue学习之五DIY脚手架.webpack使用.vue-cli的使用.element-ui 本节目录 一 vue获取原生DOM的方式 二 DIY脚手架 三 vue-cli脚手架的使用 四 webpac ...

  2. prerender html5,HTML5 VUE单页应用 SEO 优化之 预渲染(prerender-spa-plugin)

    前言:当前 SPA 架构流行的趋势如日中天,前后端分离的业务模式已经成为互联网开发的主流方式,但是 单页面 应用始终存在一个痛点,那就是 SEO, 对于那些需要推广,希望能在百度搜索时排名靠前的网站而 ...

  3. 解决vue单页路由跳转后scrollTop的问题

    作为vue的初级使用者,在开发过程中遇到的坑太多了.在看页面的时候发现了页面滚动的问题,当一个页面滚动了,点击页面上的路由调到下一个页面时,跳转后的页面也是滚动的,滚动条并不是在页面的顶部 在我们写路 ...

  4. 基于vue单页应用的例子

    代码地址如下: http://www.demodashi.com/demo/13374.html 目录结构 - src目录 主要的代码目录 - components 存放项目组件 - router 路 ...

  5. Vue.js 介绍及其脚手架工具搭建

    vue.js介绍 (MVVM.核心思想) vue.js 是一套轻量级的 MVVM 的渐进式框架.Vue 的核心库只关注视图层. vue.js 的官方网址是:点我,我是网址 MVVM 介绍 MVVM 全 ...

  6. vue 翻页时钟制作

    前言 vue 翻页时钟制作基于 kuan-vue-flip-clock 插件,由于插件的样式比较固定,所以想要改变其样式需要自定义 效果 实现 1.安装依赖 npm i kuan-vue-flip-c ...

  7. Vue 单页应用与多页应用的区别

    Vue 单页应用与多页应用的区别 概念: ● SPA单页面应用(SinglePage Web Application),指只有一个主页面的应用,一开始只需要加载一次js.css等相关资源.所有内容都包 ...

  8. vue 登录页vue模板_Vue材质设计管理员模板

    vue 登录页vue模板 Vue材料管理员 (Vue Material Admin) Vue Material Admin Template is a Vue Based Material Desig ...

  9. 【VUE3】保姆级基础讲解(二)计算属性,vue组件,vue-cli脚手架,组件通讯,插槽slot

    目录 计算属性computed 侦听器watch 对象监听 组件 注册全局组件 注册局部组件 Vue-CLI脚手架 安装和使用 .browserslistrc main.js jsconfig.jso ...

最新文章

  1. Pytorch源码与运行原理浅析--网络篇(一)
  2. 三维重建【一】——————(深度学习方式)
  3. 命令行接口(CLI)将被取而代之,它不再是网络运维的主要工具
  4. FAIR 训练 AI 玩拳击,效果堪比真人比赛,试探+周旋+爆头
  5. -Linux基础知识2 -文件系统的操作 压缩,解压缩
  6. Material DesignDrawerLayout的旋转箭头的实现方式。
  7. [剑指offer][JAVA]面试题第[07]题[重建二叉树][递归]
  8. python函数type的用意_python中type()是什么意思
  9. Python面向对象编程扑克牌发牌程序,另含大量Python代码!
  10. 20135337——Linux内核分析:第十七章 模块与设备
  11. cocos2d-x之Box2d初试
  12. AI图片翻译助手软件FAQ
  13. matlab解方java_在matlab中求解欠定方程组
  14. TSE无线通信(铺垫)
  15. Error: Cannot find module 'util-deprecate'
  16. 现在java开发用什么工具
  17. 宸展光电拟与宸鸿科技集团合资;Tableau承诺未来五年培养1000万名数据学员 | 全球TMT...
  18. python做淘宝_我用 python 做了款可开淘宝店赚钱的工具!
  19. 使用 Morphia 和 MongoDB 实现持久化
  20. 华为鸿蒙将删除谷歌代码,证明它真是自主研发,反攻安卓系统

热门文章

  1. wordpress WBOLT 百度推送管理 3.4.6 Pro
  2. linux sed写文件内容,Linux学习——文本处理:sed
  3. 禾匠榜店小程序商城V4独立版V4.0.25 前端+后端
  4. sql ntext 替换存储过程
  5. 20组免费的用户界面图标,开发者必备
  6. Moodle: 获取老师的课程 Get Faculty Course Profiles
  7. Google 地图 google map api / 地图有关
  8. lua5.3 获取table的元素数量
  9. linux chcon命令详解
  10. Linux rm命令:删除文件或目录