feat:初始化项目

This commit is contained in:
dengtongyu committed 2021-08-23 22:05:46 +08:00
commit ca52cf1bc0
486 files changed
+56656

No files matched your search

+457
View File
@@ -0,0 +1,457 @@
var fs = require('fs');
var path = require('path');
var del = require('del');
var ejs = require('gulp-ejs');
var less = require('gulp-less');
var util = require('./lib/util');
var gulpif = require('gulp-if');
var ejshelper = require('tmt-ejs-helper');
var bs = require('browser-sync').create(); // 自动刷新浏览器
var lazyImageCSS = require('gulp-lazyimagecss'); // 自动为图片样式添加 宽/高/background-size 属性
var postcss = require('gulp-postcss'); // CSS 预处理
var posthtml = require('gulp-posthtml'); // HTML 预处理
var sass = require('gulp-sass');
var webpack = require('webpack-stream');
var babel = require('gulp-babel');
var eslint = require('gulp-eslint');
var parseSVG = require('./common/parseSVG');
var svgSymbol = require('gulp-svg-sprite');
var rename = require('gulp-rename');
var proxy = require('http-proxy-middleware'); // 转发请求
var webpackConfigPath = path.join(process.cwd(), 'webpack.config.js');
var webpackConfig; // webpack 配置
var jsPath = path.join(process.cwd(), 'src', 'js');
if (util.dirExist(jsPath) && util.fileExist(webpackConfigPath)) {
webpackConfig = require(webpackConfigPath);
webpackConfig.output.publicPath = path.join('..', 'js/');
}
// 周玉杰加的,如果代码怕不起来可以删除 开始
var postcssPxtorem = require('postcss-pxtorem'); // 转换 px 为 rem
var postcssAutoprefixer = require('autoprefixer');
var svgInline = require('gulp-svg-inline');
// 周玉杰加的,如果代码怕不起来可以删除 结束
module.exports = function(gulp, config) {
// var targetDir = '../../activity/' + config.projectName + '/';
var paths = {
src: {
dir: './',
img: './img/**/*.{JPG,jpg,png,gif,svg}',
slice: './slice/**/*.png',
js: './js/**/*.js',
media: './media/**/*',
less: './css/*.less',
lessAll: './css/**/*.less',
sass: './css/*.scss',
sassAll: './css/**/*.scss',
html: ['./**/*.html', '!./_*/**.html', '!./_*/**/**.html', '!./html_tpl/**/*.html'],
svg: './svg/**/*.svg',
htmlAll: './**/*.html',
exclude: '!./dev/**/*'
},
dev: {
dir: './dev',
css: './dev/css',
html: './dev',
js: './dev/js',
symboltemp: './dev/symboltemp/',
symbol: './dev/symbolsvg'
}
// dev: {
// dir: targetDir,
// css: targetDir + 'css',
// html: targetDir,
// js: targetDir + 'js',
// symboltemp: targetDir + 'symboltemp/',
// symbol: targetDir + 'symbolsvg'
// }
};
// 周玉杰加的,如果代码怕不起来可以删除 开始
var postcssOption = [];
if (config.supportREM) { // 这个要在 .tmtworkflowrc 里面设置为true 如果要用px 要改为 Px 或者 PX 大写
postcssOption = [
postcssAutoprefixer(),
postcssPxtorem({
root_value: '75', // 基准值 html{ font-zise: 20px; }
prop_white_list: [], // 对所有 px 值生效
minPixelValue: 0 // 忽略 1px 值
}),
]
} else {
postcssOption = [
postcssAutoprefixer()
]
}
// 周玉杰加的,如果代码怕不起来可以删除 结束
var lazyDir = config.lazyDir || ['../slice', '../svg'];
// 复制操作
var copyHandler = function(type, file) {
file = file || paths['src'][type];
return gulp.src(file, { base: paths.src.dir })
.pipe(gulp.dest(paths.dev.dir))
.on('end', reloadHandler);
};
// 自动刷新
var reloadHandler = function() {
config.livereload && bs.reload();
};
// 清除目标目录
function delDev() {
return del([paths.dev.dir], {
force: true
});
}
// 复制操作 start
function copyImg() {
return copyHandler('img');
}
function copySlice() {
return copyHandler('slice');
}
function copySvg() {
return copyHandler('svg');
}
function copyMedia() {
return copyHandler('media');
}
// 复制操作 end
// 编译 less
function compileLess() {
return gulp.src(paths.src.less)
.pipe(less({ relativeUrls: true }))
.on('error', function(error) {
console.log(error.message);
})
.pipe(lazyImageCSS({ SVGGracefulDegradation: false, imagePath: lazyDir }))
.pipe(gulp.dest(paths.dev.css))
.on('data', function() {
})
.on('end', reloadHandler)
}
// 编译 sass
function compileSass() {
return gulp.src(paths.src.sass)
.pipe(sass())
.on('error', sass.logError)
.pipe(lazyImageCSS({ SVGGracefulDegradation: false, imagePath: lazyDir }))
.pipe(gulp.dest(paths.dev.css))
.on('data', function() {
})
.on('end', reloadHandler)
}
// 周玉杰加的,如果代码怕不起来可以删除 开始
// 自动补全
function compileAutoprefixer() {
return gulp.src(paths.dev.css + '/**/*.css')
.pipe(svgInline({
maxImageSize: 10 * 1024 * 1024,
extensions: [/.svg/ig]
}))
.pipe(postcss(postcssOption))
.pipe(gulp.dest(paths.dev.css));
}
// 周玉杰加的,如果代码怕不起来可以删除 结束
// 编译 html
function compileHtml() {
return gulp.src(paths.src.html)
.pipe(ejs(ejshelper()).on('error', function(error) {
console.log(error.message);
}))
.pipe(parseSVG({ devPath: paths.dev.dir }))
.pipe(gulp.dest(paths.dev.html))
.on('data', function() {
})
.on('end', reloadHandler)
}
// 编译 JS
function compileJs() {
var condition = !!webpackConfig;
return gulp.src(paths.src.js)
.pipe(eslint())
.pipe(eslint.format('../node_modules/eslint-friendly-formatter'))
.pipe(gulpif(
condition,
webpack(webpackConfig),
babel({
presets: ['es2015', 'stage-2']
})
))
.pipe(gulp.dest(paths.dev.js))
.on('end', reloadHandler)
}
// 启动 livereload
function startServer() {
var apiProxy = proxy('/api', {
target: config.livereload.proxyTarget,
changeOrigin: true,
// pathRewrite: {
// '^/api': ''
// }
});
bs.init({
server: {
baseDir: paths.dev.dir,
middleware: [apiProxy],
routes: {
'/common': '../../common'
}
},
port: config['livereload']['port'] || 8080,
startPath: config['livereload']['startPath'] || '/index.html',
reloadDelay: 0,
notify: { // 自定制livereload 提醒条
styles: [
'margin: 0',
'padding: 5px',
'position: fixed',
'font-size: 10px',
'z-index: 9999',
'bottom: 0px',
'right: 0px',
'border-radius: 0',
'border-top-left-radius: 5px',
'background-color: rgba(60,197,31,0.5)',
'color: white',
'text-align: center'
]
}
});
}
var watchHandler = function(type, file) {
var target = file.match(/(.*?)[\/|\\]/);
target = target ? target[1] : 'html';
switch (target) {
case 'img':
if (type === 'removed') {
// var tmp = file.replace(/src/, 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
});
} else {
copyHandler('img', file);
compileHtml();
}
break;
case 'svg':
if (type === 'removed') {
// var tmp = file.replace(/src/, 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
});
} else {
copyHandler('svg', file);
compileLess();
compileHtml();
setTimeout(function() {
svgSymbols();
setTimeout(function() {
reloadHandler();
}, 300)
}, 300)
}
break;
case 'slice':
if (type === 'removed') {
// var tmp = file.replace('src', 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
});
} else {
copyHandler('slice', file);
}
break;
case 'js':
if (type === 'removed') {
// var tmp = file.replace('src', 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
});
} else {
compileJs();
}
break;
case 'media':
if (type === 'removed') {
// var tmp = file.replace('src', 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
});
} else {
copyHandler('media', file);
}
break;
case 'css':
var ext = path.extname(file);
if (type === 'removed') {
// var tmp = file.replace('src', 'dev').replace(ext, '.css');
var tmp = paths.dev.dir + file;
tmp = tmp.replace(ext, '.css');
del([tmp], {
force: true
});
} else {
if (ext === '.less') {
compileLess();
} else {
compileSass();
}
// 周玉杰加的,如果代码怕不起来可以删除 开始
if (config.supportREM) {
setTimeout(function () {
compileAutoprefixer()
}, 650)
}
// 周玉杰加的,如果代码怕不起来可以删除 结束
}
break;
case 'html_tpl':
case 'html':
if (type === 'removed') {
// var tmp = file.replace('src', 'dev');
var tmp = paths.dev.dir + file;
del([tmp], {
force: true
}).then(function() {
util.loadPlugin('build_dev');
});
} else {
compileHtml();
}
if (type === 'add') {
setTimeout(function() {
util.loadPlugin('build_dev');
}, 500);
}
break;
}
};
function svgSymbols() {
return gulp.src(paths.dev.symboltemp + '**/*.svg')
.pipe(svgSymbol({
mode: {
inline: true,
symbol: true
},
shape: {
id: {
generator: function(id) {
var ids = id.replace(/.svg/ig, '');
return ids;
}
}
}
}))
.pipe(rename(function(path) {
path.dirname = './';
path.basename = 'symbol';
}))
.pipe(gulp.dest(paths.dev.symbol))
}
// 监听文件
function watch(cb) {
var watcher = gulp.watch([
paths.src.img,
paths.src.svg,
paths.src.slice,
paths.src.js,
paths.src.media,
paths.src.lessAll,
paths.src.sassAll,
paths.src.htmlAll,
paths.src.exclude
],
{ ignored: /[\/\\]\./ }
);
watcher
.on('change', function(file) {
util.log(file + ' has been changed');
watchHandler('changed', file);
})
.on('add', function(file) {
util.log(file + ' has been added');
watchHandler('add', file);
})
.on('unlink', function(file) {
util.log(file + ' is deleted');
watchHandler('removed', file);
});
cb();
}
// 加载插件
function loadPlugin(cb) {
util.loadPlugin('build_dev');
cb();
}
// 注册 build_dev 任务
gulp.task('build_dev', gulp.series(
delDev,
gulp.parallel(
copyImg,
copySlice,
compileJs,
copySvg,
// copyJs,
copyMedia,
compileLess,
compileSass
),
// 周玉杰加的,如果代码怕不起来可以删除 开始
...(config.supportREM ? [compileAutoprefixer] : []),
// 周玉杰加的,如果代码怕不起来可以删除 结束
compileHtml,
svgSymbols,
gulp.parallel(
watch,
loadPlugin
),
startServer
));
gulp.task('test', gulp.series(delDev));
};
+469
View File
@@ -0,0 +1,469 @@
var _ = require('lodash');
var fs = require('fs');
var del = require('del');
var path = require('path');
var ejs = require('gulp-ejs');
var gulpif = require('gulp-if');
var less = require('gulp-less');
var util = require('./lib/util');
var uglify = require('gulp-uglify');
var usemin = require('gulp-usemin');
var lazyImageCSS = require('gulp-lazyimagecss'); // 自动为图片样式添加 宽/高/background-size 属性
var minifyCSS = require('gulp-cssnano');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');
var tmtsprite = require('gulp-tmtsprite'); // 雪碧图合并
var ejshelper = require('tmt-ejs-helper');
var postcss = require('gulp-postcss'); // CSS 预处理
var postcssPxtorem = require('postcss-pxtorem'); // 转换 px 为 rem
var postcssAutoprefixer = require('autoprefixer');
var posthtml = require('gulp-posthtml');
var posthtmlPx2rem = require('posthtml-px2rem');;
var RevAll = require('gulp-rev-all'); // reversion
var revDel = require('gulp-rev-delete-original');
var sass = require('gulp-sass');
var changed = require('./common/changed')();
var webpack = require('webpack-stream');
var babel = require('gulp-babel');
var eslint = require('gulp-eslint');
//svg转换用到的组件
var fs = require('fs');
var rename = require('gulp-rename');
var svgmin = require('gulp-svgmin');
var svgInline = require('gulp-svg-inline');
var replace = require('gulp-replace');
var parseSVG = require('./common/parseSVG');
var svgToPng = require('./common/svgToPng');
var svgSymbol = require('gulp-svg-sprite');
var webpackConfigPath = path.join(process.cwd(), 'webpack.config.js');
var webpackConfig; // webpack 配置
var jsPath = path.join(process.cwd(), 'src', 'js');
if (util.dirExist(jsPath) && util.fileExist(webpackConfigPath)) {
webpackConfig = require(webpackConfigPath);
}
module.exports = function (gulp, config) {
process.env.NODE_ENV = 'production';
var targetDir = '../../activity/' + config.projectName + '/';
var paths = {
src: {
dir: './',
img: './img/**/*.{JPG,jpg,png,gif,svg}',
slice: './slice/**/*.png',
js: './js/**/*.js',
media: './media/**/*',
less: './css/**/*.less',
sass: './css/**/*.scss',
html: ['./**/*.html', '!./_*/**.html', '!./html_tpl/**/*.html'],
htmlAll: './**/*.html',
php: './**/*.php',
svg: './svg/**/*.svg'
},
tmp: {
dir: './tmp',
css: './tmp/css',
img: './tmp/img',
html: './tmp',
sprite: './tmp/sprite',
js: './tmp/js',
svg: './tmp/svg',
symboltemp: './tmp/symboltemp/',
symbol: './tmp/symbolsvg'
},
dist: {
dir: targetDir,
css: targetDir + 'css',
img: targetDir + 'img',
svg: targetDir + 'svg',
html: targetDir,
sprite: targetDir + 'sprite'
}
};
var webp = require('./common/webp')(config);
var lazyDir = config.lazyDir || ['../slice', '../svg'];
var postcssOption = [];
if (config.supportREM) {
postcssOption = [
postcssAutoprefixer(),
// 周玉杰加的如果不行可删除 开始
postcssPxtorem({
root_value: '75', // 基准值 html{ font-zise: 20px; }
prop_white_list: [], // 对所有 px 值生效
minPixelValue: 0 // 忽略 1px 值
})
// 周玉杰加的如果不行可删除 结束
// 如果删除了上面的 就要解开注释
// postcssPxtorem({
// root_value: '20', // 基准值 html{ font-zise: 20px; }
// prop_white_list: [], // 对所有 px 值生效
// minPixelValue: 2 // 忽略 1px 值
// })
]
} else {
postcssOption = [
postcssAutoprefixer()
]
}
// 清除 dev 目录
function delDev() {
return del('./dev', {
force: true
});
}
// 清除 dist 目录
function delDist() {
return del([paths.dist.dir], {
force: true
});
}
// 清除 tmp 目录
function delTmp() {
return del([paths.tmp.dir]);
}
function delSVG() {
return del([paths.tmp.symboltemp]);
}
//编译 less
function compileLess() {
return gulp.src(paths.src.less)
.pipe(less({relativeUrls: true}))
.pipe(lazyImageCSS({SVGGracefulDegradation: config.SVGGracefulDegradation, imagePath: lazyDir}))
.pipe(tmtsprite({margin: 4}))
.pipe(gulpif('*.png', gulp.dest(paths.tmp.sprite), gulp.dest(paths.tmp.css)));
}
//编译 less
function compileSass() {
return gulp.src(paths.src.sass)
.pipe(sass())
.on('error', sass.logError)
.pipe(lazyImageCSS({SVGGracefulDegradation: config.SVGGracefulDegradation, imagePath: lazyDir}))
.pipe(tmtsprite({margin: 4}))
.pipe(gulpif('*.png', gulp.dest(paths.tmp.sprite), gulp.dest(paths.tmp.css)));
}
//自动补全
function compileAutoprefixer() {
// return gulp.src('./tmp/css/style-*.css')
return gulp.src(paths.tmp.css + '/**/*.css')
.pipe(svgInline({
maxImageSize: 10 * 1024 * 1024,
extensions: [/.svg/ig],
}))
.pipe(postcss(postcssOption))
.pipe(gulp.dest(paths.tmp.css));
}
//CSS 压缩
function miniCSS() {
// return gulp.src('./tmp/css/style-*.css')
return gulp.src(paths.tmp.css + '/**/*.css')
.pipe(minifyCSS({
safe: true,
reduceTransforms: false,
advanced: false,
compatibility: 'ie7',
keepSpecialComments: 0
}))
.pipe(gulp.dest(paths.tmp.css));
}
//图片压缩
function imageminImg() {
return gulp.src(paths.src.img)
.pipe(imagemin({
use: [pngquant()]
}))
.pipe(gulp.dest(paths.tmp.img));
}
//复制媒体文件
function copyMedia() {
return gulp.src(paths.src.media, {base: paths.src.dir}).pipe(gulp.dest(paths.tmp.dir));
}
//编译 JS
function compileJs() {
var condition = webpackConfig ? true : false;
return gulp.src(paths.src.js)
.pipe(eslint())
.pipe(eslint.format('../node_modules/eslint-friendly-formatter'))
.pipe(eslint.failAfterError())
.pipe(gulpif(
condition,
webpack(webpackConfig),
babel({
presets: ['es2015', 'stage-2']
})
))
.pipe(uglify())
.pipe(gulp.dest(paths.tmp.js));
}
//雪碧图压缩
function imageminSprite() {
// return gulp.src('./tmp/sprite/**/*')
return gulp.src(paths.tmp.sprite + '/**/*')
.pipe(imagemin({
use: [pngquant()]
}))
.pipe(gulp.dest(paths.tmp.sprite));
}
//html 编译
function compileHtml() {
return gulp.src(paths.src.html)
.pipe(ejs(ejshelper()))
.pipe(gulpif(
config.supportREM,
posthtml(
posthtmlPx2rem({
rootValue: 20,
minPixelValue: 2
})
))
)
.pipe(parseSVG({devPath: 'tmp', SVGGracefulDegradation: config.SVGGracefulDegradation}))
.pipe(gulp.dest(paths.tmp.html))
.pipe(usemin())
.pipe(gulp.dest(paths.tmp.html));
}
//webp 编译
function supportWebp() {
if (config['supportWebp']) {
return webp();
} else {
return function noWebp(cb) {
cb();
}
}
}
//新文件名(md5)
function reversion(cb) {
var RevOptions = {
fileNameManifest: 'manifest.json',
dontRenameFile: ['.html', '.php'],
dontUpdateReference: ['.html'],
includeFilesInManifest: ['.css', '.js', '.html', 'htm'],
transformFilename: function (file, hash) {
var ext = path.extname(file.path);
// if(ext === '.html'){
// return path.basename(file.path, ext) + ext;
// }
return path.basename(file.path, ext) + '.' + hash.substr(0, 8) + ext;
}
};
if (config['reversion']) {
// return gulp.src(['./tmp/**/*'])
return gulp.src([paths.tmp.dir + '/**/*'])
.pipe(RevAll.revision(RevOptions))
.pipe(gulp.dest(paths.tmp.dir))
.pipe(revDel({
exclude: /(.html|.htm)$/
}))
// .pipe(RevAll.manifestFile())
.pipe(gulp.dest(paths.tmp.dir));
} else {
cb();
}
}
function miniSVG() {
if (config.SVGGracefulDegradation) {
return gulp.src(paths.src.svg)
.pipe(svgmin({
plugins: [{
convertPathData: true
}, {
removeTitle: true
}, {
mergePaths: false
}, {
removeUnknownsAndDefaults: false
}, {
removeDoctype: true
}, {
removeComments: true
}, {
cleanupNumericValues: {
floatPrecision: 2
}
}, {
convertColors: {
names2hex: true,
rgb2hex: true
}
}]
}))
.pipe(svgToPng())
.pipe(gulp.dest(paths.tmp.svg));
} else {
return gulp.src(paths.src.svg)
.pipe(svgmin({
plugins: [{
convertPathData: true
}, {
removeTitle: true
}, {
mergePaths: false
}, {
removeUnknownsAndDefaults: false
}, {
removeDoctype: true
}, {
removeComments: true
}, {
cleanupNumericValues: {
floatPrecision: 2
}
}, {
convertColors: {
names2hex: true,
rgb2hex: true
}
}]
}))
.pipe(gulp.dest(paths.tmp.svg));
}
}
function svgSymbols() {
return gulp.src(paths.tmp.symboltemp + '**/*.svg')
.pipe(svgSymbol({
mode: {
inline: true,
symbol: true
},
shape: {
id: {
generator: function (id) {
var ids = id.replace(/.svg/ig, '');
return ids;
}
}
}
}))
.pipe(rename(function (path) {
path.dirname = './';
path.basename = 'symbol';
}))
.pipe(gulp.dest(paths.tmp.symbol));
}
function findChanged(cb) {
if (!config['supportChanged']) {
return gulp.src('./tmp/**/*', {base: paths.tmp.dir})
.pipe(gulp.dest(paths.dist.dir))
.on('end', function () {
delTmp();
})
} else {
var diff = changed('./tmp');
var tmpSrc = [];
if (!_.isEmpty(diff)) {
//如果有reversion
if (config['reversion'] && config['reversion']['available']) {
var keys = _.keys(diff);
//先取得 reversion 生成的manifest.json
var reversionManifest = require(path.resolve('./tmp/manifest.json'));
if (reversionManifest) {
reversionManifest = _.invert(reversionManifest);
reversionManifest = _.pick(reversionManifest, keys);
reversionManifest = _.invert(reversionManifest);
_.forEach(reversionManifest, function (item, index) {
tmpSrc.push('./tmp/' + item);
console.log('[changed:] ' + util.colors.blue(index));
});
//将新的 manifest.json 保存
fs.writeFileSync('./tmp/manifest.json', JSON.stringify(reversionManifest));
tmpSrc.push('./tmp/manifest.json');
}
} else {
_.forEach(diff, function (item, index) {
tmpSrc.push('./tmp/' + index);
console.log('[changed:] ' + util.colors.blue(index));
});
}
return gulp.src(tmpSrc, {base: paths.tmp.dir})
.pipe(gulp.dest(paths.dist.dir))
.on('end', function () {
delTmp();
})
} else {
console.log('Nothing changed!');
delTmp();
cb();
}
}
}
//加载插件
function loadPlugin(cb) {
util.loadPlugin('build_dist');
cb();
}
//注册 build_dist 任务
gulp.task('build_dist', gulp.series(
gulp.parallel(
delDist,
delDev
),
gulp.parallel(
compileLess,
compileSass,
imageminImg,
copyMedia,
compileJs,
miniSVG
),
compileAutoprefixer,
imageminSprite,
miniCSS,
compileHtml,
svgSymbols,
reversion,
supportWebp(),
delSVG,
findChanged,
loadPlugin
));
};
+38
View File
@@ -0,0 +1,38 @@
var _ = require('lodash');
var del = require('del');
var path = require('path');
var ftp = require('gulp-ftp');
var util = require('./lib/util');
module.exports = function (gulp, config) {
//清除目标目录
function delDist() {
return del(['./dist']);
}
function remoteFtp() {
var remotePath = config['ftp']['remotePath'] || "",
ftpConfig = _.extend(config['ftp'], {
remotePath: path.join(remotePath, config['projectName'])
}),
distPath = config['ftp']['includeHtml'] ? './dist/**/*' : ['./dist/**/*', '!./dist/html/**/*.html'];
return gulp.src(distPath, {base: '.'})
.pipe(ftp(ftpConfig));
}
//加载插件
function loadPlugin(cb) {
util.loadPlugin('ftp');
cb();
}
//注册 ftp 任务
gulp.task('ftp', gulp.series(
'build_dist',
remoteFtp,
delDist,
loadPlugin
));
};
+38
View File
@@ -0,0 +1,38 @@
var _ = require('lodash');
var path = require('path');
var del = require('del');
var util = require('./lib/util');
var sftp = require('gulp-sftp');
module.exports = function (gulp, config) {
//清除目标目录
function delDist() {
return del(['./dist']);
}
function remoteSftp() {
var remotePath = config['sftp']['remotePath'] || '',
sftpConfig = _.extend(config['sftp'], {
remotePath: path.join(remotePath, config['projectName'])
}),
distPath = config['ftp']['includeHtml'] ? './dist/**/*' : ['./dist/**/*', '!./dist/html/**/*.html'];
return gulp.src(distPath, {base: '.'})
.pipe(sftp(sftpConfig))
}
//加载插件
function loadPlugin(cb) {
util.loadPlugin('Res');
cb();
}
//注册 Res 任务
gulp.task('sftp', gulp.series(
'build_dist',
remoteSftp,
delDist,
loadPlugin
));
};
+24
View File
@@ -0,0 +1,24 @@
var util = require('./lib/util');
var del = require('del');
var zip = require('gulp-zip');
module.exports = function (gulp, config) {
//清除目标目录
function delDist() {
return del(['./dist']);
}
function zipTask(){
return gulp.src('./dist/**/*')
.pipe(zip('dist.zip'))
.pipe(gulp.dest('./'));
}
//注册 zip 任务
gulp.task('zip', gulp.series(
'build_dist',
zipTask,
delDist
));
};
+57
View File
@@ -0,0 +1,57 @@
var md5 = require('crypto-md5');
var path = require('path');
var rd = require('rd');
var fs = require('fs');
var _ = require('lodash');
function changed(dir) {
var manifestPath = path.resolve('./src/manifest.json');
var manifest = {};
var originManifest = {};
//如果存在 manifest.json, 则加载保存
if (fs.existsSync(manifestPath)) {
originManifest = require(manifestPath);
}
//遍历目录, 根据内容 md5 加密
rd.eachFileFilterSync(dir, function (file) {
var index = path.relative(dir, file);
//过滤掉 隐藏文件 和 manifest.json
if (path.extname(file) && index !== 'manifest.json' && fs.existsSync(file)) {
var data = fs.readFileSync(file);
if (data) {
manifest[index] = md5(data, 'hex');
}
}
});
//将新的 manifest.json 保存
fs.writeFile(manifestPath, JSON.stringify(manifest), function (err) {
if (err) throw err;
});
//找出有变动的文件
if(originManifest){
var diff = {};
_.forEach(manifest, function (item, index) {
if (originManifest[index] !== item) {
diff[index] = item;
}
});
}
return diff;
}
module.exports = function(){
return changed;
};
+161
View File
@@ -0,0 +1,161 @@
/**
* Created by doubleluo
*/
var gulp = require('gulp');
var replace = require('gulp-replace');
var through = require('through2');
var fs = require('fs');
var path = require('path');
var File = require('vinyl');
var util = require('../lib/util');
var cheerio = require('cheerio');
module.exports = function (options) {
var mkdirs = function(dirpath, callback) {
fs.exists(dirpath, function(exists) {
if(exists) {
callback(dirpath);
} else {
mkdirs(path.dirname(dirpath), function(){
fs.mkdir(dirpath, callback);
});
}
});
}
var mkdirone = false;
var marchRegInline = /<img.*?src=['"].*?(\w+)\.svg\?i['"].*?>/gi;
var marchRegSybmol = /<img.*?src=['"].*?(\w+)\.svg\?s['"].*?>/gi;
var marchRegBase = /<img.*?src=['"].*?(\w+)\.svg['"].*?>/gi;
var src = [],id,style,className,data,width,height,newcontent,$;
function getBase(){
id = $.attr('id');
style = $.attr('style');
className = $.attr('class');
data = fs.readFileSync(path.join(process.cwd(), options.devPath+'/img', src[0])).toString();
width = data.match(/<svg(.*?)width=["|'](.*?)(px)?["|']/)[2];
height = data.match(/<svg(.*?)height=["|'](.*?)(px)?["|']/)[2];
fileName = src[0].substr(src[0].lastIndexOf('/')+1,src[0].indexOf('.svg')-7);
newcontent = [];
}
function getAttr(){
if(id){
newcontent.push(' id="'+ id +'"');
}
if(style){
newcontent.push(' style="'+ style +'"');
}
if(className){
newcontent.push(' class="'+ className +'"');
}
}
function inline(contents){
getAttr();
data = data.replace('<svg','<svg width="'+ width +'" height="'+ height +'"'+newcontent.join(''));
if(options.SVGGracefulDegradation){
data = data.replace('>','><image width="'+ width +'" height="'+ height +'" src="'+src[0].replace('.svg','.png')+'" />');
}
return data;
}
function sybmol(contents){
var newFile = path.join(process.cwd(), options.devPath + '/symboltemp/', fileName);
fs.writeFile(newFile, data, {encoding: 'utf8'}, err => {
if (err) throw err;
});
newcontent.push('<svg width="'+ width +'" height="'+ height +'" xmlns="http://www.w3.org/2000/svg"');
getAttr();
newcontent.push('>');
if(options.SVGGracefulDegradation){
newcontent.push('<image src="'+src[0].replace('.svg','.png')+'"',' />');
}
newcontent.push('<use xlink:href="'+ ((options && options.symbolBaseUrl)||'../symbolsvg/symbol.svg')+ '#' + fileName.replace('.svg','') +'"/>');
newcontent.push('</svg>');
return newcontent.join('');
}
function base(contents){
newcontent.push('<svg width="'+ width +'" height="'+ height +'" xmlns="http://www.w3.org/2000/svg"');
getAttr();
newcontent.push('>');
if(options.SVGGracefulDegradation){
newcontent.push('<image width="'+ width +'" height="'+ height +'" src="'+src[0].replace('.svg','.png')+'" xlink:href="'+src[0]+'">');
}else{
newcontent.push('<image width="'+ width +'" height="'+ height +'" xlink:href="'+src[0]+'">');
}
newcontent.push('</svg>');
return newcontent.join('');
}
function run(regData,contents,marchReg){
if(regData){
for(var i = 0;i<regData.length;i++){
var replaceData = '';
$ = cheerio(regData[i]);
src = $.attr('src').split('?');
if(src[0].indexOf('.svg')>-1){
getBase();
if(src[1] == 'i'){
replaceData = inline(contents);
}else if(src[1] == 's'){
replaceData = sybmol(contents);
}else{
replaceData = base(contents);
}
}
contents = contents.replace(regData[i], replaceData);
}
}
return contents;
}
return through.obj(function (file, enc, cb) {
var _this = this;
if (file.isNull()) {
cb(null, file);
} else {
if (util.fileExist(file.path)) {
var contents = file.contents.toString();
var regData;
if(options.onlyInline){
regData = contents.match(marchRegInline);
contents = run(regData,contents,marchRegInline);
}else{
if(!mkdirone){
mkdirone = true;
fs.exists(process.cwd() + '/'+ options.devPath +'/symboltemp',function(exists){
if(!exists){
fs.mkdir(process.cwd() + '/'+ options.devPath +'/symboltemp', err => {
if (err) throw err;
});
}
});
}
regData = contents.match(marchRegInline);
contents = run(regData,contents,marchRegInline);
regData = contents.match(marchRegSybmol);
contents = run(regData,contents,marchRegSybmol);
regData = contents.match(marchRegBase);
contents = run(regData,contents,marchRegBase);
}
_this.push(new File({
base: file.base,
path: file.path,
contents: new Buffer(contents)
}));
cb(null);
} else {
cb(null, file);
}
}
});
}
+36
View File
@@ -0,0 +1,36 @@
/**
* Created by doubleluo on 15/5/3.
*/
var gulp = require('gulp');
var replace = require('gulp-replace');
var through = require('through2');
var fs = require('fs');
var path = require('path');
var util = require('../lib/util');
var File = require('vinyl');
var svg_to_png = require('svg-to-png');
module.exports = function (options) {
return through.obj(function (file, enc, cb) {
var _this = this;
if (file.isNull()) {
cb(null, file);
} else {
if (util.fileExist(file.path)) {
svg_to_png.convert(file.path, file.path.substr(0,file.path.lastIndexOf('/')).replace('/src/','/dist/'));
_this.push(new File({
base: file.base,
path: file.path,
contents: file.contents
}));
cb(null);
} else {
cb(null, file);
}
}
});
}
+86
View File
@@ -0,0 +1,86 @@
/**
* Created by littledu on 15/5/2.
*/
var rd = require('rd');
var gulp = require('gulp');
var path = require('path');
var gulpWebp = require('gulp-webp');
var rename = require('gulp-rename');
var replace = require('gulp-replace');
var util = require('./../lib/util');
var fs = require('fs');
module.exports = function (config, done) {
var webpScript = '<script>function webpsupport(a){var c=window.localStorage;if(typeof a!="function"){a=function(){}}if(c!=undefined&&c._tmtwebp!=undefined&&c._tmtwebp==0){a();return false}else{if(c!=undefined&&c._tmtwebp!=undefined&&c._tmtwebp==1){a(1);return true}else{var f=new Image();f.onload=f.onerror=function(){if(f.height!=2){if(c!=undefined){c._tmtwebp=0}a();return false}else{if(c!=undefined){c._tmtwebp=1}a(1);return true}};f.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"}}};;(function(){function b(t){var f=document.getElementsByTagName("link");for(var e=0,d=f.length;e<d;e++){if(t){f[e].href=f[e].getAttribute("data-href").replace(".css",".webp.css");}else{f[e].href=f[e].getAttribute("data-href")}}}webpsupport(b);})();</script></head>';
var webpMap = {}; //为了筛选webp而构建的对象
var imgArr = []; //筛选出来需要转换成 webp 的图片
var imgMap = {}; //返回给全局作 preload 判断使用{"img_name": 1, "img_name": 0} 1 为可优化成 webp
var reg = null;
function render_webp(src) {
if (!fs.existsSync(src)) return;
rd.eachFileSync(src, function (file, stats) {
var extname = path.extname(file);
var basename = path.basename(file, extname);
if (!(basename in webpMap)) {
webpMap[basename] = {};
webpMap[basename]['size'] = stats.size;
webpMap[basename]['extname'] = extname;
} else {
if ((webpMap[basename]['size'] > stats.size) && (extname === '.webp')) {
imgArr.push(basename + webpMap[basename]['extname']);
imgMap[basename + webpMap[basename]['extname']] = 1;
} else {
imgMap[basename + webpMap[basename]['extname']] = 0;
}
}
});
}
return function () {
return gulp.series(
function compileSprite() {
return gulp.src('./tmp/sprite/**/*')
.pipe(gulpWebp())
.pipe(gulp.dest('./tmp/sprite'));
},
function compileImg () {
return gulp.src('./tmp/img/**/*')
.pipe(gulpWebp())
.pipe(gulp.dest('./tmp/img'));
},
//智能寻找 webp
function find2Webp (cb) {
render_webp('./tmp/sprite');
render_webp('./tmp/img');
if(imgArr.length){
reg = eval('/(' + imgArr.join('|') + ')/ig');
}
cb();
},
function compileCss () {
return gulp.src(['./tmp/css/**/*.css', '!./tmp/css/**/*.webp.css'])
.pipe(rename({suffix: '.webp'}))
.pipe(replace(reg, function (match) {
if(match){
return match.substring(0, match.lastIndexOf('.')) + '.webp';
}
}))
.pipe(gulp.dest('./tmp/css'));
},
function insertWebpJs () {
var preload_script = '<script>window.imgMap = ' + JSON.stringify(imgMap) + '</script>';
return gulp.src('./tmp/html/**/*.html')
.pipe(replace('data-href', 'href'))
.pipe(replace(/(link.*?)href/ig, '$1data-href'))
.pipe(replace('</head>', webpScript))
.pipe(replace('</head>', preload_script))
.pipe(gulp.dest('./tmp/html'));
}
);
}
}
+17
View File
@@ -0,0 +1,17 @@
var fs = require('fs');
var path = require('path');
var config = require('rc')('tmtworkflow', {
projectName: process.cwd().split(path.sep).pop(),
livereload: {
'proxyTarget': 'http://apibeta.kawayisound.xyz'
}
});
module.exports = function(gulp) {
fs.readdirSync(__dirname).filter(function(file) {
return (file.indexOf('.') !== 0) && (file.indexOf('Task') === 0);
}).forEach(function(file) {
var registerTask = require(path.join(__dirname, file));
registerTask(gulp, config);
});
};
+73
View File
@@ -0,0 +1,73 @@
var fs = require('fs');
var path = require('path');
var util = require('gulp-util');
var config = require('rc')('tmtworkflow', {
projectName: process.cwd().split(path.sep).pop()
});
var tmt_util = {
log: function (task_name) {
util.log.apply(util, arguments);
},
task_log: function (task_name) {
this.log(util.colors.magenta(task_name), util.colors.green.bold('√'));
},
loadPlugin: function (name, cb) {
name = name + 'After';
if (config['plugins'] && config['plugins'][name] && config['plugins'][name].length) {
var plugins = config['plugins'][name];
plugins.every(function (plugin) {
if (plugin.indexOf('.js') === -1) {
plugin += '.js';
}
var filepath = path.resolve(__dirname, '../plugins', plugin);
if (fs.existsSync(filepath)) {
require(filepath)(config);
(typeof cb === 'function') && cb();
} else {
console.log('The ' + filepath + ' is not found!');
(typeof cb === 'function') && cb();
}
});
}
},
colors: util.colors,
dirExist: function (dirPath) {
try {
var stat = fs.statSync(dirPath);
if (stat.isDirectory()) {
return true;
} else {
return false;
}
} catch (err) {
if (err.code === 'ENOENT') {
return false;
} else {
throw new Error(err);
}
}
},
fileExist: function (filePath) {
try {
var stat = fs.statSync(filePath);
if (stat.isFile()) {
return true;
} else {
return false;
}
} catch (err) {
if (err.code === 'ENOENT') {
return false;
} else {
throw new Error(err);
}
}
}
};
module.exports = tmt_util;
+109
View File
@@ -0,0 +1,109 @@
/**
* Created by littledu on 15/5/16.
*/
var fs = require('fs'),
path = require('path'),
localIp = require('quick-local-ip');
module.exports = function (config) {
var html = [
'<!DOCTYPE html>',
'<head>',
'<meta charset="utf-8">',
'<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">',
'<title></title>',
'<link rel="stylesheet" href="http://wximg.gtimg.com/tmt/tools/file-list/css/style.css">',
'<style type="text/css">',
'.icon-qrcode{cursor: pointer;}@media only screen and (min-device-width : 310px) and (max-device-width : 800px){#myTable{margin: 0;max-width: 100%;}.td-header-qrcode,.td-header-time,.td-qrcode,.td-time{display:none;}.table-body,.td-header-title{font-size: 14px }}',
'</style>',
'</head>',
'<body>',
' <table id="myTable" class="table">',
' <thead class="table-head">',
' <tr>',
' <th class="td-header-title">文件名</th>',
' <th class="td-header-qrcode" style="width:40px;text-align: center;">二维码</th>',
' </tr>',
' </thead>',
' <tbody class="table-body">'
].join(''),
tmpHtml = '',
length = '/dev/html/'.length,
collector = listdir('./dev/html'),
ip = localIp.getLocalIP4();
showdir(collector, 0);
function listdir(dir) {
var collector = {
'name': dir,
'type': 'dir',
'url': '',
'child': []
};
files = fs.readdirSync(dir);
files.forEach(function (file) {
var absolutePath = dir + '/' + file,
stats = fs.statSync(absolutePath);
var url = absolutePath.substring(absolutePath.indexOf('./dev/html/') + length + 1);
if (stats.isDirectory() && (stats.isDirectory() !== '.' || stats.isDirectory() !== '..')) {
collector['child'].push(listdir(absolutePath));
} else {
collector['child'].push({
'name': path.basename(absolutePath),
'type': 'file',
'url': url
});
}
});
return collector;
}
function showdir(collector, level) {
var file = collector['name'],
basename = path.basename(file);
var indent = 25 * (level - 1);
if (indent <= 0) {
indent = 10;
}
if (collector['type'] == 'dir') {
if (level != 0) {
html += '<tr><td class="td-dir" style="text-align:left; padding-left: ' + indent + 'px">[目录]: ' + basename + '</td><td></td></tr>';
}
collector['child'].forEach(function (item) {
showdir(item, level + 1);
});
}
if (collector['type'] == 'file') {
if (path.extname(file) === '.html' && basename !== 'TmTIndex.html') {
if (level === 1) {
tmpHtml += '<tr class="level1"><td class="td-file sort-file" style="padding-left: ' + indent + 'px"><a href="' + collector['url'] + '" target="_blank">' + basename + '</a></td><td class="td-qrcode"><i class="icon-qrcode"></i></td></tr>';
} else {
html += '<tr><td class="td-file" style="padding-left: ' + indent + 'px"><a href="' + collector['url'] + '" target="_blank">' + basename + '</a></td><td class="td-qrcode"><i class="icon-qrcode"></i></td></tr>';
}
}
}
}
html = html + tmpHtml;
html += '</tbody></table><div id="qrcode"></div><script src="http://wximg.gtimg.com/tmt/tools/file-list/js/jquery-2.1.3.min.js"></script><script src="http://wximg.gtimg.com/tmt/tools/file-list/js/qrcode.min.js"></script><script type="text/javascript">$(document).ready(function(){ var url = location.href.replace("localhost", "' + ip + '");document.title= "' + config.projectName + ' 资源列表"; $(".level1").prependTo(".table-body"); $(".td-qrcode i").bind("mouseenter ",function(){$("#qrcode").show().empty();new QRCode(document.getElementById("qrcode"), encodeURI(url.split("TmTIndex.html")[0]+$(this).parent().parent().find("a").attr("href")));});$("body").bind("click",function(){$("#qrcode").hide();});});</script></body></html>';
var out = fs.createWriteStream('./dev/html/TmTIndex.html', {encoding: "utf8"});
out.write(html, function (err) {
if (err) console.log(err);
});
out.end();
}
+12
View File
@@ -0,0 +1,12 @@
/**
* Created by littledu on 15/4/28.
*/
var util = require('./../lib/util');
var path = require('path');
module.exports = function(config){
var remotePath = config['ftp']['remotePath'] || "";
var url = 'http://' + path.join(remotePath, config['projectName'], 'dist/html/').replace(/\\/g, '/');
util.log(util.colors.magenta('copy to browser:') + url);
}