Authored by 毕凯

增加 H5 postcss框架

/**
* GULP-FILE
* author: xuqi(qi.xu@yoho.cn)
* date: 2015/9/30
*/
var gulp = require('gulp'),
compass = require('gulp-compass'),
cp = require('child_process');
var fs = require('fs'),
ftp = require('gulp-ftp'),
gutil = require('gulp-util'),
uglify = require('gulp-uglify'),
Package = require('father').SpmPackage,
transport = require('gulp-spm'),
concat = require('gulp-concat');
var config = JSON.parse(fs.readFileSync('./package.json').toString());
var rootDist = 'dist/myohobuy/',
ftpConfig = {
host: '218.94.75.58',
user: 'php',
pass: 'yoho9646'
};
var distDir = {
js: rootDist + config.version,
css: rootDist + config.version,
img: rootDist + 'assets/img',
font: rootDist + 'assets/font'
};
gulp.task('default', ['compass', 'compass-watch', 'spm-doc']);
// compass
gulp.task('compass', function() {
gulp.src('sass/**/*.scss')
.pipe(
compass({
config_file: 'config.rb',
css: 'css',
sass: 'sass'
})
).on('error', function(error) {
console.log(error);
this.emit('end');
});
});
// compass watch
gulp.task('compass-watch', function() {
gulp.watch('sass/**/*.scss', ['compass']);
});
// start spm server
gulp.task('spm-doc', function() {
var sd = cp.exec('spm doc');
// sd.stdout.on('data', function(data) {
// console.log(data);
// });
sd.stderr.on('data', function(data) {
console.log(data);
});
sd.on('exit', function(code) {
console.log('process spm doc exit with code ' + code);
});
});
//生成发布目录,可用于上传测试机
gulp.task('ge', ['assets', 'compass-production', 'build']);
//发布
gulp.task('dist', ['assets', 'compass-production', 'build'], function() {
var ftpstream = ftp(ftpConfig);
return gulp.src('dist/**/')
.pipe(ftpstream)
.pipe(gutil.noop());
});
//font+img->dist/assets
gulp.task('assets', function() {
gulp.src('img/**')
.pipe(gulp.dest(distDir.img));
gulp.src('font/*')
.pipe(gulp.dest(distDir.font));
});
//compass
gulp.task('compass-production', ['assets'], function() {
gulp.src('sass/index.scss')
.pipe(
compass({
css: distDir.css,
sass: 'sass',
image: distDir.img,
font: distDir.font,
http_path: '/',
style: 'compressed'
})
)
.on('error', function(error) {
console.log(error);
this.emit('end');
});
});
//spm build
gulp.task('build', ['libs', 'business']);
//libs
gulp.task('libs', ['pre-libs', 'concat-min-libs', 'clear-libs']);
gulp.task('pre-libs', function() {
var obj = {
name: '',
version: config.version,
spm: config.spm
};
var packages = [],
libsjs = '';
var libCon, key, i;
var pkg;
obj.spm.main = 'libs.js';
obj.spm.buildArgs = '--idleading {{}} --include all';
libCon = JSON.stringify(obj);
fs.renameSync('package.json', 'package.bak.json');
fs.writeFileSync('package.json', libCon);
for (key in obj.spm.dependencies) {
if (obj.spm.inside && obj.spm.inside[key]) {
packages.push(obj.spm.inside[key]);
} else {
packages.push(key);
}
}
for (i = 0; i < packages.length; i++) {
libsjs += 'require("' + packages[i] + '");';
}
fs.writeFileSync('libs.js', libsjs); //重写入口文件
pkg = new Package(__dirname);
return gulp.src(pkg.main)
.pipe(transport({
pkg: pkg
}))
.pipe(gulp.dest(distDir.js));
});
gulp.task('concat-min-libs', ['pre-libs'], function() {
var path = distDir.js + '/libs.js';
var jsStr = fs.readFileSync(path).toString();
fs.writeFileSync(path, jsStr.substr(jsStr.indexOf('});') + 4));
return gulp.src(['js/sea.js', distDir.js + '/libs.js'])
.pipe(concat('lib.js'))
.pipe(uglify())
.pipe(gulp.dest(distDir.js));
});
gulp.task('clear-libs', ['concat-min-libs'], function() {
fs.renameSync('package.bak.json', 'package.json');
fs.unlinkSync('./libs.js');
fs.unlinkSync(distDir.js + '/libs.js');
});
gulp.task('business', ['libs'], function() {
var pkg = new Package(__dirname);
return gulp.src(pkg.main)
.pipe(transport({
pkg: pkg
}))
.pipe(concat('index-debug.js'))
.pipe(gulp.dest(distDir.js))
.pipe(uglify())
.pipe(concat('index.js'))
.pipe(gulp.dest(distDir.js));
});
\ No newline at end of file
... ...
... ... @@ -5,7 +5,6 @@
*/
var gulp = require('gulp'),
compass = require('gulp-compass'),
cp = require('child_process');
var fs = require('fs'),
... ... @@ -16,7 +15,11 @@ var fs = require('fs'),
transport = require('gulp-spm'),
concat = require('gulp-concat');
var config = JSON.parse(fs.readFileSync('./package.json').toString());
var postcss = require('gulp-postcss');
var sourcemaps = require('gulp-sourcemaps');
var cssnano = require('gulp-cssnano');
var config = require('./package');
var rootDist = 'dist/myohobuy/',
ftpConfig = {
... ... @@ -32,31 +35,112 @@ var distDir = {
font: rootDist + 'assets/font'
};
gulp.task('default', ['compass', 'compass-watch', 'spm-doc']);
// compass
gulp.task('compass', function() {
gulp.src('sass/**/*.scss')
.pipe(
compass({
config_file: 'config.rb',
css: 'css',
sass: 'sass'
})
).on('error', function(error) {
console.log(error);
this.emit('end');
gulp.task('default', ['postcss-dev', 'postcss-watch', 'spm-doc']);
//根据环境变量生成postcss插件配置
function postcssEnvPlugin(env) {
var sprites = {
spritesmith: {
padding: 2
},
groupBy: function(file) {
// 根据目录分组,防止合并后的图片太大
var group = file.url.split('/')[1];
return group ? Promise.resolve(group) : Promise.reject();
},
filterBy: function(file) {
//使用resolve转化后静态资源生成../img或者../assets/img/的路径
if (/\/img/.test(file.url) || /data:image/.test(file.url)) {
return Promise.reject();
}
return Promise.resolve();
}
},
assets;
if (env === 'DEV') {
assets = {
loadPaths: ['font/', 'img/'],
relativeTo: 'css/'
};
Object.assign(sprites, {
basePath: './img',
stylesheetPath: './css',
spritePath: './img'
});
} else if (env === 'PRO') {
assets = {
loadPaths: [distDir.img, distDir.font],
relativeTo: distDir.css,
cachebuster: function(filePath, urlPathname) {
//只给字体加no-cache
if (/font\//.test(urlPathname)) {
return fs.statSync(filePath).mtime.getTime().toString(16);
}
}
};
Object.assign(sprites, {
basePath: distDir.img,
stylesheetPath: distDir.css,
spritePath: distDir.img
});
}
return [
require('precss'),
require('postcss-assets')(assets),
require('postcss-sprites').default(sprites),
require('postcss-calc'),
require('postcss-pxtorem')({
rootValue: 40,
unitPrecision: 5, // 保留5位小数字
minPixelValue: 2, // 小于 2px 时,不转换, 单位为 PX 大写的时候不转换
selectorBlackList: [], // 选择器黑名单,可以使用正则
propWhiteList: [] // 属性名称为空,表示替换所有属性的值
}),
require('autoprefixer')({
add: true,
browsers: ['> 1%']
}),
//可选
require('postcss-use')({
modules: ['postcss-clearfix', 'postcss-crip', 'postcss-short', 'postcss-center', 'postcss-position']
})
];
}
//Postcss开发环境
gulp.task('postcss-dev', function() {
return gulp.src('sass/index.css')
.pipe(sourcemaps.init())
.pipe(postcss(postcssEnvPlugin('DEV')))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('css/'))
});
gulp.task('postcss-watch', function() {
gulp.watch('sass/**/*.css', ['postcss-dev']);
});
// compass watch
gulp.task('compass-watch', function() {
gulp.watch('sass/**/*.scss', ['compass']);
//Postcss正式环境生成
gulp.task('postcss-pro', ['assets'], function() {
return gulp.src('sass/index.css')
.pipe(postcss(postcssEnvPlugin('PRO')))
.pipe(cssnano())
.pipe(gulp.dest(distDir.css))
});
// start spm server
gulp.task('spm-doc', function() {
var sd = cp.exec('spm doc');
var sd = cp.exec('spm doc watch --port 8000'); // PC 用8001,H5 用8000, 跑两个服务器,不冲突
// sd.stdout.on('data', function(data) {
// console.log(data);
... ... @@ -72,10 +156,10 @@ gulp.task('spm-doc', function() {
});
//生成发布目录,可用于上传测试机
gulp.task('ge', ['assets', 'compass-production', 'build']);
gulp.task('ge', ['assets', 'postcss-pro', 'build']);
//发布
gulp.task('dist', ['assets', 'compass-production', 'build'], function() {
gulp.task('dist', ['assets', 'postcss-pro', 'build'], function() {
var ftpstream = ftp(ftpConfig);
return gulp.src('dist/**/')
... ... @@ -84,30 +168,16 @@ gulp.task('dist', ['assets', 'compass-production', 'build'], function() {
});
//font+img->dist/assets
gulp.task('assets', function() {
gulp.src('img/**')
gulp.task('assets', ['img', 'font']);
gulp.task('img', function() {
return gulp.src('img/**/*')
.pipe(gulp.dest(distDir.img));
gulp.src('font/*')
.pipe(gulp.dest(distDir.font));
});
//compass
gulp.task('compass-production', ['assets'], function() {
gulp.src('sass/index.scss')
.pipe(
compass({
css: distDir.css,
sass: 'sass',
image: distDir.img,
font: distDir.font,
http_path: '/',
style: 'compressed'
})
)
.on('error', function(error) {
console.log(error);
this.emit('end');
});
gulp.task('font', function() {
return gulp.src('font/*')
.pipe(gulp.dest(distDir.font))
});
//spm build
... ... @@ -166,7 +236,7 @@ gulp.task('concat-min-libs', ['pre-libs'], function() {
fs.writeFileSync(path, jsStr.substr(jsStr.indexOf('});') + 4));
return gulp.src(['js/sea.js', distDir.js + '/libs.js'])
return gulp.src(['plugin/sea.js', distDir.js + '/libs.js'])
.pipe(concat('lib.js'))
.pipe(uglify())
.pipe(gulp.dest(distDir.js));
... ... @@ -190,4 +260,4 @@ gulp.task('business', ['libs'], function() {
.pipe(uglify())
.pipe(concat('index.js'))
.pipe(gulp.dest(distDir.js));
});
\ No newline at end of file
});
... ...
... ... @@ -34,18 +34,33 @@
}
},
"devDependencies": {
"autoprefixer": "^6.3.3",
"father": "^1.0.0",
"gulp": "^3.9.0",
"gulp-compass": "^2.1.0",
"gulp-concat": "^2.6.0",
"gulp-cssnano": "^2.1.1",
"gulp-ftp": "^1.0.4",
"gulp-postcss": "^6.1.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-spm": "^0.11.3",
"gulp-uglify": "^1.4.2",
"gulp-util": "^3.0.6",
"spm": "3"
"postcss-assets": "^4.0.1",
"postcss-calc": "^5.2.0",
"postcss-center": "^1.0.0",
"postcss-clearfix": "^0.2.1",
"postcss-crip": "^2.0.0",
"postcss-position": "^0.4.0",
"postcss-pxtorem": "^3.3.1",
"postcss-short": "^1.4.0",
"postcss-sprites": "^3.1.0",
"postcss-use": "^2.0.2",
"precss": "^1.4.0",
"spm": "3.4"
},
"scripts": {
"test": "spm test",
"build": "spm build"
}
}
\ No newline at end of file
}
... ...
.filter-mask, .filter-body {
position: absolute;
left: 0;
right: 0;
top: 0;
}
.filter-mask {
height: 100%;
background: rgba(0,0,0,0.1);
}
.filter-body {
background: #fff;
color: #000;
cursor: pointer;
font-size: 14px;
height: 440px;
.classify {
width: 50%;
height: 100%;
background: #f8f8f8;
> li {
height: 60px;
line-height: 60px;
> * {
box-sizing: border-box;
}
&.active {
background: #fff;
}
.shower {
padding-left: 20px;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: #333;
&.highlight {
background: #eee;
}
}
.default {
color: #999;
}
.title {
float: left;
color: #000;
}
}
}
.sub-classify {
position: absolute;
display: none;
width: 50%;
height: 440px;
left: 50%;
top: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
> li {
height: 60px;
line-height: 60px;
padding-left: 15px;
border-bottom: 1px solid #e6e6e6;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&.highlight {
background: #eee;
}
}
.chosed-icon {
display: none;
}
.chosed .chosed-icon {
display: inline;
}
}
.active > .sub-classify {
display: block;
}
}
... ...
.good-info {
float: left;
width: 276px;
height: 486px;
margin: 0 (15px) (15px);
.tag-container {
height: 28px;
width: 100%;
overflow: hidden;
.good-tag {
display: block;
float: left;
height: 28px;
font-size: 18px;
text-align: center;
line-height: 28px;
box-sizing: border-box;
margin-right: 4px;
&:last-child {
margin-right: 0;
}
}
.new-tag {
width: 60px;
background-color: #78dc7e;
color: #fff;
}
.renew-tag {
width: 90px;
background-color: #78dc7e;
color: #fff;
}
.sale-tag {
width: 60px;
background-color: #ff575c;
color: #fff;
}
.new-festival-tag {
width: 90px;
background-color: #000;
color: #fff;
}
.limit-tag {
width: 100px;
border: 1px solid #000;
color: #000;
}
}
}
.good-detail-img {
position: relative;
height: 368px;
.good-islike {
position: absolute;
width: 60px;
height: 60px;
top: 0px;
right: 0px;
line-height: 60px;
font-size: 30px;
text-align: center;
color: #b0b0b0;
text-decoration: none;
}
.good-like {
color: #d72928;
}
img {
display: block;
width: 100%;
height: 368px;
}
.few-tag {
position: absolute;
bottom: 0;
width: 100%;
height: 28px;
background: #ffac5b;
font-size: 18px;
color: #fff;
line-height: 28px;
text-align: center;
}
}
.good-detail-text {
.name a {
display: block;
line-height: 56px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-decoration: none;
font-size: 22px;
color: #444;
}
.price {
line-height: 22px;
font-size: 22px;
.sale-price {
color: #d62927;
}
.sale-price.no-price {
color: #000;
}
.market-price {
margin: 0 0 0 (5px);
color: #b0b0b0;
text-decoration: line-through;
}
}
}
... ...
.order-failure {
background-image: resolve('lazy-failure/order-good.jpg');
background-size: 100%;
}
.good-failure {
background-image: resolve('lazy-failure/order-good.jpg');
background-size: 132px !important;
background-position-x: 40%;
}
... ...
.loading-mask {
position: fixed;
background: rgba(0,0,0,.1);
top: 0;
bottom: 0;
right: 0;
left: 0;
@keyframes scale {
0% {
transform: scale(1);
opacity: 1;
}
45% {
transform: scale(0.1);
opacity: 0.7;
}
80% {
transform: scale(1);
opacity: 1;
}
}
.loading {
position: absolute;
width: 60px;
height: 20px;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -30px;
> div {
display: inline-block;
background: #fff;
width: 15px;
height: 15px;
border-radius: 100%;
margin: 2px;
$init: 0.12;
@for $i from 1 to 3 {
&:nth-child($i) {
animation: scale .75s $(init)s infinite cubic-bezier(.2,.68,.18,1.08);
}
$init: ($i + 1) * 0.12;
}
}
}
}
... ...
@charset "utf-8";
@use postcss-clearfix;
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
}
html {
line-height: 1;
}
ol, ul {
list-style: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
q, blockquote {
quotes: none;
}
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
a img {
border: none;
}
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}
/*Reset End*/
.clearfix {
clear: fix;
}
* {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-moz-tap-highlight-color: rgba(0,0,0,0);
tap-highlight-color: rgba(0,0,0,0);
}
html, body {
font-family: helvetica,Arial,"黑体";
width: 100%;
font-size: 12PX;
line-height: 1.4;
}
button, input, select, textarea {
font-size: 100%;
margin: 0;
}
img {
max-width: 100%;
display: block;
border: 0;
margin: 0 auto;
}
a {
text-decoration: none;
outline: none;
color: #000;
&:link,
&:visited,
&:hover,
&:actived {
color: #000;
}
}
*:focus {
outline: none;
}
.hide {
display: none;
}
.overflow-hidden {
overflow: hidden;
}
@font-face {
font-family: "iconfont";
src: resolve('iconfont.eot'); /* IE9*/
src: resolve('iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
resolve('iconfont.woff') format('woff'), /* chrome、firefox */
resolve('iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
resolve('iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16PX;
font-style: normal;
text-decoration: none;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.yoho-tip {
position: fixed;
display: none;
text-align: center;
width: 70%;
padding: 34px 0;
top: 50%;
left: 50%;
margin-left: -35%;
margin-top: -45px;
background-color: rgba(0,0,0,.7);
color: #fff;
font-size: 18px;
border: none;
z-index:4;
border-radius: 10px;
}
.tap-hightlight {
&.highlight {
background: #eee!important;
}
}
.load-more-info {
width: 100%;
height: 70px;
line-height: 70px;
text-align: center;
font-size: 14px;
overflow: hidden;
.status {
&.hide {
display: none;
}
}
}
@import "layout/header";
@import "layout/footer";
@import "layout/footer_tab";
@import "good";
@import "lazy-failure";
@import "filter";
@import "loading";
/*@import "passport/index";
@import "guang/index";
@import "home/index";
@import "category/index";
@import "product/index";
@import "index/index";
@import "cart/index";
@import "me/index";*/
... ...
.yoho-footer {
font-size: 12px;
background-color: #fff;
position: relative;
.op-row {
padding: 0 15px;
height: 60px;
line-height: 60px;
span{
display: inline-block;
overflow:hidden;
}
a{
display: inline-block;
overflow:hidden;
}
.user-name {
text-decoration: underline;
margin-left: .3em;
margin-right: 1em;
max-width: 200px;
text-overflow:ellipsis;
white-space:nowrap;
}
.back-to-top {
position: absolute;
right: 20px;
}
.sep-line {
margin: 0 0.3em;
}
}
.copyright {
height: 60px;
line-height: 60px;
border-top: 1px solid #ccc;
text-align: center;
color: #666;
background-color: #eee;
}
&.bottom {
position: fixed;
width: 100%;
bottom: 0;
}
}
... ...
.footer-tab {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 100px;
padding-top: 20px;
box-sizing: border-box;
background: #fff;
border-top: 1px solid #b0b0b0;
z-index: 3;
.tab-item {
float: left;
width: 20%;
text-align: center;
color: #b0b0b0;
&.current {
color: #414141;
}
}
.tab-icon {
font-size: 40px;
line-height: 1;
}
.tab-name {
margin-top: 10px;
font-size: 20px;
line-height: 1;
}
}
.boys-wrap {
.footer-tab {
.tab-item.current {
color: #414141;
}
}
}
.girls-wrap {
.footer-tab {
.tab-item.current {
color: #FF88AE;
}
}
}
.kids-wrap {
.footer-tab {
.tab-item.current {
color: #7ad9f9;
}
}
}
.lifestyle-wrap {
.footer-tab {
.tab-item.current {
color: #4f4138;
}
}
}
... ...
@define-extend nav {
display: block;
position: absolute;
top: 0;
width: 90px;
height: 90px;
font-size: 20px;
line-height: 90px;
color: #fff;
text-align: center;
outline: none;
}
.yoho-header {
position: relative;
background-color: #000;
color: #fff;
width: 100%;
overflow: hidden;
height: 90px;
line-height: 90px;
z-index: 1;
&.boys {
background-image: linear-gradient(#323232, #414141);
}
&.girls {
background: #ff88ae;
}
&.kids {
background: #7ad9f9;
}
&.life-style {
background: #4f4138;
}
a.highlight {
background: rgba(200,200,200,.1);
}
.nav-back {
@extend nav;
left: 10px;
}
.nav-home {
@extend nav;
right: 10px;
}
.nav-btn {
@extend nav;
right: 10px;
font-size: 14PX;
}
.nav-title {
position: absolute;
margin-left: 100px;
margin-right: 100px;
height: 100%;
font-size: 36px;
color: #fff;
font-weight: bold;
top: 0;
right: 0;
left: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
}
}
.systemUpdate{
width: 100%;
height: 90px;
overflow: hidden;
line-height: 90px;
display: none;
background-image: linear-gradient(#323232, #414141);
.systemHeader{
width: 85%;
height: 100%;
overflow: hidden;
font-size: 60px;
color:#fff;
float: left;
text-align: center;
}
span{
width: 14%;
height: 100%;
overflow: hidden;
float: left;
text-align: center;
font-size: 80px;
font-weight: bold;
color: #fff;
}
}
.systemMain{
width: 92%;
height: 100%;
overflow: hidden;
background-color:#444;
color: #fff;
padding:0 4%;
position: absolute;
top: 0;
left: 0;
p {
font-size: 52px;
line-height: 60px;
&:first-of-type{
padding-top: 90px;
}
}
}
.homebuttom{
width: 100%;
height: 90px;
overflow: hidden;
border-top: 1px solid rgba(255,255,255,0.5);
color: #fff;
z-index: 2;
position: relative;
&.boys {
background-image: linear-gradient(#323232, #414141);
}
&.girls {
background: #ff88ae;
}
&.kids {
background: #7ad9f9;
}
&.life-style {
background: #4f4138;
}
ul {
width: 100%;
height: 90%;
overflow: hidden;
padding-top: 12px;
li {
width: 25%;
height: 100%;
overflow: hidden;
float: left;
text-align: center;
i{
width: 100%;
height: 40%;
display: block;
color: #fff;
margin-bottom: 8px;
}
span{
width: 100%;
height: auto;
overflow: hidden;
display: block;
line-height: 40px;
color: #fff;
}
}
}
}
... ...