一个 “普通” 项目的 “另类” 复盘
2015. 5. 22
@CSS魔法
如何在一个无聊的项目中找乐子……
2015. 5. 22
@CSS魔法
一个 “普通” 项目的 “另类” 复盘
一个 “无聊” 的项目
-
传统项目
-
无法拒绝
-
无追求
-
幸好:不着急
(45 分钟)
-
Part 1
-
Part 2
-
Part 3
Part 1
给自己打 Log
-
精确统计
-
分析
-
评估成本

简单的统计
-
实际工期:2014.11.14 ~ 2015.01.24
-
总耗时: 112.8 小时
-
折算工作日: 18 ~ 28 天
-
成本估算:……
各环节耗时占比

兼容 IE 8 的代价

Part 2
各种实践
-
前端架构
-
前后端配合
-
开发环境
/
├── html/
│
├── static/
│ ├── _building/
│ ├── img/
│ ├── pic/
│ ├── css/
│ │ ├── dist/
│ │ └── src/
│ ├── js/
│ │ ├── dist/
│ │ └── src/
│ └── json/
│
└── index.html
目录结构概览
-
纵深 vs 扁平
-
只占用两个一级目录
-
易整合
前后端配合
-
远程协作:版本控制 + 在线演示
-
后端架构:LAMP
-
整合方式:静态页面 + “套程序”(后端整合)
“静态页面”
/
├── html/
│ ├── _component/
│ │ ├── header.php
│ │ ├── footer.php
│ │ ├── news-detail.php
│ │ └── ...
│ ├── _env.php
│ ├── home.php
│ ├── news.php
│ ├── member.php
│ └── ...
│
├── static/
│ └── ...
└── index.html
首页(未登录):/html/home.php
首页(已登录):/html/home.php?login=1
<?php require_once('_env.php'); ?>
<?php $login = isset($_GET['login']) ? $_GET['login'] : '0'; ?>
<!DOCTYPE html>
<html lang="zh-cmn-Hans-CN">
<head>
<meta charset="UTF-8">
<title>首页 - <?= $login === '0' ? '未登录' : '已登录' ?></title>
<?php require_once('component/head.php'); ?>
<link rel="stylesheet" href="<?= $pathCSS ?>/home.css">
</head>
<body>
<?php
$navItem = 'home';
require_once('component/header.php');
require_once('component/header-nav.php');
?>
<?php if ($login == '0') {
require_once('component/dialog-login.php');
} ?>
<div id="main-body">
...
</div>
<?php require_once('component/footer.php'); ?>
<?php require_once('component/side-toolbar.php'); ?>
<script src="<?= $pathJS ?>/global.js"></script>
<script src="<?= $pathJS ?>/home.js"></script>
</body>
</html>
版本控制
-
Git / GitHub
版本控制
-
Git / GitHub -
SVN
在线演示
-
SVN + PHP => SAE
-
PHP 5.3
$gradeTypes = [
'1' => '初级',
'2' => '中级',
'3' => '高级',
];
$gradeTypes = array(
'1' => '初级',
'2' => '中级',
'3' => '高级',
);
前端源码组织
-
CSS:Stylus
-
JS:JS 模块化(CommonJS / Sea.js / ...)
前端源码组织
-
CSS:Stylus
-
JS:JS 模块化(CommonJS / Sea.js / ...) -
JS:JS Combo
前端目录组织
└── static/
│
├── css/
│ ├── dist/
│ └── src/
│ ├── basic/
│ ├── module/
│ │ ├── _component/
│ │ │ ├── header.styl
│ │ │ ├── footer.styl
│ │ │ ├── news-detail.styl
│ │ │ └── ...
│ │ ├── home/
│ │ ├── news/
│ │ ├── member/
│ │ ├── .../
│ │ ├── _index.styl
│ │ └── ...
│ ├── home.styl
│ ├── news.styl
│ ├── member.styl
│ └── ...
│
└── js/
├── dist/
└── src/
├── _common/
├── home/
├── news/
├── member/
└── .../
└── html/
│
├── _component/
│ ├── header.php
│ ├── footer.php
│ ├── news-detail.php
│ └── ...
│
├── _env.php
├── home.php
├── news.php
├── member.php
└── ...
开发环境
(略)
开发环境
Booster 在这一刻灵魂附体!
/
├── html/
├── static/
│ ├── _building/
│ │ ├── bower_components/
│ │ ├── node_modules/
│ │ ├── util/
│ │ │ ├── config-js-combo.js
│ │ │ ├── config-nproxy.js
│ │ │ ├── config-stylus.js
│ │ │ └── stylus.js
│ │ ├── bower.json
│ │ ├── package.json
│ │ └── gulpfile.js
│ └── ...
└── index.html
开发阶段
源
文
件
本地 Stylus
编译服务
本地
代理
Stylus
CSS
JS
开发者
(资源替换)
(文件合并)
开发阶段
部署阶段
源
文
件
本地 Stylus
编译服务
本地
代理
Stylus
CSS
JS
源
文
件
Stylus
JS
Gulp
构建任务
SAE/服务器
开发者
协作者/用户
CSS
JS
(资源替换)
(文件合并)
优点
-
完全按需
-
“快”
缺点
-
功能有限:脚本的编译环节待开发
-
逻辑重复:无法复用构建任务
Part 3
Stylus 练级
-
编码规范
-
寻找最佳实践
-
验证各种理论
编码规范
全局变量与局部变量
// 定义全局变量
$line-height = 1.5
btn()
// 定义局部变量
$-color = #a1c444
$-color-shadow = #6ea928
// 使用全局变量
line-height $line-height
// 使用局部变量
background-color $-color
box-shadow 0 1px 0 0 $-color-shadow
...
公开 Mixin 与非公开 Mixin
// 定义非公开 mixin
-icon-size($size)
width $size
height $size
// 定义公开 mixin
icon-20()
// 使用非公开 mixin
-icon-size(20)
icon-30()
// 使用非公开 mixin
-icon-size(30)
样式模块的内容
“样式模块” 是什么?
页面
“样式入口”
<!DOCTYPE html>
<html lang="zh-cmn-Hans-CN">
<head>
...
<link rel="stylesheet" href="home.css">
...
</head>
<body>
...
</body>
</html>
// home.styl
@import './module/_component/header'
@import './module/_component/breadcrumb'
@import './module/_component/footer'
@import './module/btn'
...
“样式模块”
// btn.styl
.btn
...
&.success
...
// footer.styl
#footer
...
// breadcrumb.styl
#breadcrumb
...
// header.styl
#header
...
// header.styl
#header
.logo-box
float left
width 250px
a.logo
float left
size 110px 80px
p.slogan
float left
size 130px 80px
.hotline-box
float right
i.hotline
margin-right 10px
size 20px
// news-box.styl
news-box()
> .header
headline()
a
font-size 12px
ul
li
margin-bottom 10px
margin-left 15px
a
display block
i.icon
display inline-block
span.time
color #979797
A: 代码块
B: Mixin
两种形式如何选择?
// header.styl
#header
.logo-box
float left
width 250px
a.logo
float left
size 110px 80px
p.slogan
float left
size 130px 80px
.hotline-box
float right
i.hotline
margin-right 10px
size 20px
// header.styl
header()
.logo-box
float left
width 250px
a.logo
float left
size 110px 80px
p.slogan
float left
size 130px 80px
.hotline-box
float right
i.hotline
margin-right 10px
size 20px
最终决定:统一为 Mixin 的方式
@import './module/_component/header'
@import './module/_component/breadcrumb'
@import './module/_component/footer'
@import './module/btn'
#login-form
.btn
btn()
#feedback-form
.submit > button
btn()
@import './module/_component/header'
@import './module/_component/breadcrumb'
@import './module/_component/footer'
@import './module/btn'
#header
header()
#breadcrumb
breadcrumb()
#footer
footer()
#login-form
.btn
btn()
#feedback-form
.submit > button
btn()
在页面样式入口文件中调用
@import './module/_component/header'
@import './module/_component/breadcrumb'
@import './module/_component/footer'
#header
header()
#breadcrumb
breadcrumb()
#footer
footer()
#login-form
.btn
@import './module/btn'
btn()
#feedback-form
.submit > button
@import './module/btn'
btn()
样式库暴露的接口
-
类
-
Mixin
(“样式库” 即类似 Bootstrap 这样的 UI 元素样式集合。)
类
Mixin
// icon.styl
-icon-basic()
display block
margin-left auto
margin-right auto
-icon-type($type)
...
.icon
-icon-basic()
&.icon-error
-icon-type('error')
// icon.styl
-icon-basic()
display block
margin-left auto
margin-right auto
-icon-type($type)
...
icon-error()
-icon-basic()
-icon-type('error')
// home.styl
.msg
> i
icon-error()
<!-- home.php -->
<div class="msg">
<i></i>
<p>出错了……</p>
</div>
<!-- home.php -->
<div class="msg">
<i class="icon icon-error"></i>
<p>出错了……</p>
</div>
MIXIN 接口的缺点
-
HTML 干净
-
生成的 CSS 代码更少
-
不需要多个接口的组合
“文艺项目” 必选!
MIXIN 接口的优点
-
多一步:胶合代码
但是,在 “普通项目” 中:
-
多一步:胶合代码
-
HTML 干净
-
生成的 CSS 代码更少
-
不需要多个接口的组合
完全无所谓
不明显
文档+习惯
“普通项目” 还是……
麻烦
Q & A
THANK YOU!
一个 “普通” 项目的 “另类” 复盘
By CSS魔法
一个 “普通” 项目的 “另类” 复盘
如何在一个无聊的项目中找乐子……
- 967