一直以来都在研究多页应用如何能有一套像SPA同样优雅的开发模式css
本套架构在项目上使用感受还不错(已跑在上百个页面的项目上),因此决定开源出来给你们html
阅读完本文能实如今项目中使用ES6(7)+组件化(.vue | .jsx)开发多页应用前端
若是你不须要SEO,须要先后端分离,项目是多页应用,选择我就对了vue
(其实我是想把它作为你们多页应用的脚手架)react
TIPS:任何的项目的架构都和目录结构有关,因此这部分很是重要,请仔细耐心阅读webpack
咱们先宏观的看下结构git
|--- public // 生产环境下所需的文件
|--- components
|--- css
|--- fonts
|--- images
|--- js
|--- sass
|--- views
|--- src
|--- components
|--- css
|--- fonts
|--- images
|--- js
|--- sass
|--- views复制代码
咱们展开介绍下具体的页面应该如何对应它的资源。拿js
和views
为例github
|--- 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.js
common.js复制代码
在多页应用中,每每咱们的页面以业务模块划分,业务模块由许多的页面组成。
如home,shopping
,可能就分别为官网介绍和购物的业务模块。在这业务模块下,分别有许多个页面,那咱们的js文件也须要命名一一对应。web
固然,咱们还有第三方的js库是不须要编译的,因此咱们专门用一个lib
文件夹来存放他们。(包括你本身编写的指令或者filter等,不须要编译的,也直接放在lib下引入便可)ajax
另外,你还有许多本身写的须要编译的工具库直接放在js
目录下便可(如,tools.js,common.js)
咱们的sass也是同理
|--- sass
|--- home
|--- index.scss
...
|--- shopping
|--- buy.scss
...复制代码
他们会分别编译在css
和js
下的文件将为
|--- 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同样。具体组件那就有所不一样。
咱们分为几种类型的组件
- 1、当前页面使用的组件
- 2、当前业务模块下的公用组件
- 3、全部业务模块的通用组件
当前页面组件的命名,咱们约定为 [页面]-[组件].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.js
const 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.js
import url from '../ajaxurl';
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-cli
或者是create-react-app
这种cli脚手架的,可是!本人真是太懒又没有时间了! 各位看官能够先尝试clone把玩把玩,若是有足够多人喜欢,我就把他写成cli,发布npm :)
我是用mac下开发完成的,用了半天多时间专门去给window写了兼容,window还可能会有bug,不是我说!window就是辣鸡!
最后给你们看下咱们的某项目结构。
总览
js部分
images
组件
大家可能在总览的图会发现多了apis
和mock
文件夹,这个是咱们promise封装接口层和前端本地mock层,因为每一个团队的作法都不一样,我就没有放在此次的脚手架里
vue-multpage 通用版: github.com/MeCKodo/vue…
Have a nice day