spencer-kit-project-templates
Version:
spencer kit project templates
358 lines (323 loc) • 10.6 kB
JavaScript
var minimist = require('minimist');
var fs = require('fs');
var sh = require('shelljs');
var rename = require('gulp-rename');
var url = require('url')
var path = require('path');
var gulp = require('gulp');
var replace = require('gulp-replace');
var hash = require('gulp-hash');
var inject = require('gulp-inject');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var minifyCss = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var connect = require('gulp-connect');
var proxy = require('http-proxy-middleware');
var webpack = require('webpack');
var webpackConfig = require('./webpack.config');
var options = minimist(process.argv.slice(2));
var DIST = options.dist || 'dist';// dist dir
var ENV = options.env || 'dev';//environment,dafault is dev
var ENTRY = path.resolve(options.entry||'./project.js');//build entry file
var projectConfig = require(ENTRY);
if (typeof projectConfig == 'function') {
projectConfig = projectConfig(ENV);
}
var serverConfig = {
root: DIST,// server root
port: 8080,//server port
livereload: false,
/**
* @ description
* proxy config,you can uncomment the code below for cross
* origin ajax;
*/
middleware: function (connect, opt) {
return [
proxy( function (pathname, req) {
return pathname.match('^/PC');
}, {
target: '',
changeOrigin: true,
})
]
}
}
function meger(source,dest){
for(var o in source){
if(source.hasOwnProperty(o)){
if(!dest[o] || typeof dest[o]!=='object'){
dest[o] = source[o];
}else{
dest[o] = meger(source[o],dest[o]);
}
}
}
return dest;
}
function TaskDelayer() {
this.timeoutTokens = {};
TaskDelayer.prototype.delay = function (fn, token) {
clearTimeout(this.timeoutTokens[token]);
this.timeoutTokens[token] = setTimeout(fn, 1000);
}
}
function mkdir() {
if (fs.existsSync(DIST)) {
sh.rm('-rf', DIST);
}
fs.mkdir(DIST);
}
function getTemplate(path) {
if (fs.existsSync(path)) {
return gulp.src(path);
} else {
console.log(path + ' not exist');
}
}
function html() {
HTMLgenerate(projectConfig.pages);
}
function HTMLgenerate(pages) {
pages.forEach(function (config) {
var template = getTemplate(config.template);
var injectFiles = [
]
config.js = config.js || [];
config.js.unshift('buildconfig.js');
if (config.js) {
injectFiles.push({
name: 'js',
files: config.js.map(function (name) {
return DIST + '/js/' + name.replace('\.', '*\.');
})
})
}
if (config.css) {
injectFiles.push({
name: 'css',
files: config.css.map(function (name) {
return DIST + '/css/pc/' + name.replace('\.', '*\.');
})
})
}
if (template) {
template = HTMLComplie(config, template, DIST);
injectFiles.forEach(function (config) {
template = injectFile(template, config);
});
if(config.prerender&&ENV!=='dev'){
require('./AppRegister.prerender');
global.BuildConfig = getBuildConfig();
var files = [];
injectFiles[0].files.forEach(function(v){
if(v.indexOf('react') <0){
console.log(v)
files.push(v);
}
})
gulp.src(files).pipe(
concat(config.output+'.js')
).pipe(gulp.dest(DIST)).addListener('end',function(){
AppRegister.setTag(config.output);
require('./'+DIST+'/'+config.output);
sh.rm(DIST+'/'+config.output+'.js');
var html = AppRegister.getTag(config.output);
template.pipe(
replace('html_placeholder\'>','html_placeholder\'>'+html)
).pipe(gulp.dest(DIST));
});
}else{
template.pipe(gulp.dest(DIST));
}
}
});
}
function asset() {
gulp.src([projectConfig.assetDIR+'/**'])
.pipe(gulp.dest(DIST));
}
function HTMLComplie(config, template) {
return template.pipe(replace(
/<%=[\s\S]*?(?:%>)/g,
function (matcher) {
matcher = matcher.replace(/(<%=\s*|\s*%>)/g, '');
if (matcher != '') {
return new Function('config',
'return '+ String(matcher))(config);
} else {
return matcher;
}
}
)).pipe(rename(config.output));
}
function runWebpack(env, entry, output) {
// entry = encodeURI(JSON.stringify(entry));
return new Promise(function (resolve, reject) {
if (!entry) {
resolve();
} else {
entry = encodeURI(JSON.stringify(entry));
let config = webpackConfig;
let argv = env + '--' + entry + '--' + output;
if (typeof config === 'function') {
config = config(argv);
}
var compiler = webpack(config);
compiler.run(function (err, stats) {
resolve();
webpackCompiler = compiler;
console.log(stats.toString({
colors: true
}));
});
}
})
// webpacks.Compiler
// sh.exec('webpack --colors --env=' + env + '--' + entry + '--' + output +
// ' --progress --profile');
}
function hashmifify() {
var readyList = [];
if (ENV == 'dev') {
return Promise.resolve();
}
return new Promise(function (resolve) {
function checkReady() {
readyList.push(true);
if (readyList.length == 2) {
sh.rm('-fr',[DIST + '/js1',DIST + '/css1']);
resolve();
}
}
sh.mv('-f',DIST + '/js',DIST + '/js1');
sh.mv('-f',DIST + '/css',DIST + '/css1');
process.nextTick(function () {
gulp.src([DIST + '/css1/**']).
pipe(minifyCss()).
pipe(hash()).
pipe(gulp.dest(DIST + '/css'))
.addListener('end', checkReady);
gulp.src([DIST + '/js1/**.js']).
pipe(uglify()).
pipe(hash()).
pipe(gulp.dest(DIST + '/js')).
addListener('end', checkReady);
})
})
}
function concatJS(list, DIST) {
list = list || {};
return new Promise(function (resolve, reject) {
var readyList = [];
var taskList = [];
function checkReady() {
readyList.push(true);
if (readyList.length == taskList.length) {
resolve();
}
}
for (var js in list) {
gulp.src(list[js]).
pipe(sourcemaps.init()).
pipe(concat(js + '.js')).
pipe(sourcemaps.write()).
pipe(gulp.dest(DIST))
.addListener('end', checkReady);
taskList.push(true)
}
});
}
function getBuildConfig(){
var buildConfig = projectConfig.buildConfig&&projectConfig.buildConfig.defaultConfigs||{};
var envBuildConfig = projectConfig.buildConfig&&projectConfig.buildConfig[ENV];
buildConfig = meger(envBuildConfig,buildConfig);
return buildConfig;
}
//buile config
function generateBuildConfigJS(dir){
var buildConfig = projectConfig.buildConfig&&projectConfig.buildConfig.defaultConfigs||{};
var envBuildConfig = projectConfig.buildConfig&&projectConfig.buildConfig[ENV];
buildConfig = meger(envBuildConfig,buildConfig);
var js = '(function(){window.BuildConfig='+JSON.stringify(buildConfig)+'}());';
var appregister = fs.readFileSync('AppRegister.js');
js = js+'\r\n'+appregister;
fs.writeFileSync(path.join(dir,'buildconfig.js'),js);
}
function injectFile(template, config) {
return template.pipe(
inject(
gulp.src(config.files),
{ relative: false, name: config.name, ignorePath:DIST }
));
}
function css() {
if(!projectConfig.compass){
return Promise.resolve();
}
sh.exec('compass compile --sass-dir ' + path.resolve(projectConfig.scssDIR) + ' --force');
return new Promise(function (resolve) {
process.nextTick(function(){
sh.rm('-fr', DIST + '/css');
sh.mv('-f','css', DIST + '/css');
process.nextTick(resolve);
});
})
}
function js() {
var jsDIR = path.join(DIST,'js');
if(!fs.existsSync(jsDIR)){
fs.mkdirSync(jsDIR)
}
generateBuildConfigJS(jsDIR);
if (projectConfig.webpackEntry) {
return runWebpack(ENV, projectConfig.webpackEntry,jsDIR).then(function(){
return concatJS(projectConfig.commonJS, jsDIR);
});
}
}
function clear() {
// sh.rm('-rf', 'css');
}
function start() {
mkdir();
asset();
css().then(js).then(hashmifify).then(html).then(server);
}
start();
function server() {
if (ENV == 'dev') {
connect.server(serverConfig);
var delayer = new TaskDelayer();
var webpackWatching = webpackCompiler.watch({
aggregateTimeout: 1000,
ignored:[
/node_modules/,
/dist/
]
}, function (err, stats) {
console.log(stats.toString({
chunks: false,
colors: true
}))
console.log(new Date()+'reload')
//arguments.callee.apply(null, arguments);
})
gulp.watch(['asset/**'], function () {
delayer.delay(function () {
asset();
process.nextTick(function () {
connect.reload();
})
}, 'asset')
})
gulp.watch([projectConfig.scssDIR + '/**'], function () {
delayer.delay(function () {
css().then(function () {
connect.reload();
});
}, 'scss')
})
}
}