use babel to compile ES6 scripts to ES5

This commit is contained in:
printempw 2017-01-19 22:54:47 +08:00
parent 5fb237f01a
commit 100314dfd7
7 changed files with 294 additions and 263 deletions

View File

@ -99,7 +99,6 @@ if (! function_exists('bs_footer')) {
$scripts = [
assets('js/app.min.js'),
assets('lang/'.config('app.locale').'/locale.js'),
assets('js/general.js')
];
if ($page_identification !== "") {

View File

@ -2,24 +2,26 @@
* @Author: printempw
* @Date: 2016-07-21 13:38:26
* @Last Modified by: printempw
* @Last Modified time: 2017-01-18 23:04:20
* @Last Modified time: 2017-01-19 23:07:05
*/
'use strict';
let gulp = require('gulp'),
var gulp = require('gulp'),
babel = require('gulp-babel'),
elixir = require('laravel-elixir'),
uglify = require('gulp-uglify'),
sass = require('gulp-sass'),
cleanCss = require('gulp-clean-css'),
del = require('del'),
zip = require('gulp-zip');
zip = require('gulp-zip'),
notify = require('gulp-notify');
require('laravel-elixir-replace');
let version = require('./package.json').version;
let vendor_js = [
let vendorJs = [
'jquery/dist/jquery.min.js',
'bootstrap/dist/js/bootstrap.min.js',
'AdminLTE/dist/js/app.min.js',
@ -28,11 +30,11 @@ let vendor_js = [
'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js',
'iCheck/icheck.min.js',
'toastr/toastr.min.js',
'es6-promise/es6-promise.auto.min.js',
'sweetalert2/dist/sweetalert2.min.js',
'es6-promise/es6-promise.min.js'
];
let vendor_css = [
let vendorCss = [
'bootstrap/dist/css/bootstrap.min.css',
'AdminLTE/dist/css/AdminLTE.min.css',
'AdminLTE/plugins/datatables/dataTables.bootstrap.css',
@ -40,72 +42,67 @@ let vendor_css = [
'font-awesome/css/font-awesome.min.css',
'iCheck/skins/square/blue.css',
'toastr/toastr.min.css',
'sweetalert2/dist/sweetalert2.min.css'
'sweetalert2/dist/sweetalert2.min.css',
];
let replacements = [
['@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);', ''],
['../fonts/glyphicons', '../fonts/glyphicons'],
['../fonts/fontawesome', '../fonts/fontawesome'],
['blue.png', '"../images/blue.png"'],
['blue@2x.png', '"../images/blue@2x.png"'],
['../fonts/glyphicons', '../fonts/glyphicons'],
['../fonts/fontawesome', '../fonts/fontawesome'],
['../img/loading.gif', '"../images/loading.gif"'],
['../img/loading-sm.gif', '"../images/loading-sm.gif"']
['../img/loading-sm.gif', '"../images/loading-sm.gif"'],
['@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);', ''],
];
let fonts = [
'font-awesome/fonts/**',
'bootstrap/dist/fonts/**',
];
let images = [
'iCheck/skins/square/blue.png',
'iCheck/skins/square/blue@2x.png',
'bootstrap-fileinput/img/loading.gif',
'bootstrap-fileinput/img/loading-sm.gif',
];
elixir.config.sourcemaps = false;
elixir((mix) => {
mix
.scripts(vendor_js.map((js) => 'resources/assets/src/bower_components/' + js).concat([
'resources/assets/src/js/utils.js'
mix // compile sass files & ES6 scripts first
.task('compile-sass')
.task('compile-es6')
.scripts(convertRelativePath(vendorJs).concat([
'resources/assets/dist/js/general.js'
]), 'resources/assets/dist/js/app.min.js', './')
.styles(vendor_css.map((css) => 'resources/assets/src/bower_components/' + css), 'resources/assets/dist/css/app.min.css', './')
.styles(convertRelativePath(vendorCss), 'resources/assets/dist/css/app.min.css', './')
.replace('resources/assets/dist/css/app.min.css', replacements)
// copy fonts & images
.copy([
'resources/assets/src/bower_components/bootstrap/dist/fonts/**',
'resources/assets/src/bower_components/font-awesome/fonts/**'
], 'resources/assets/dist/fonts/')
.copy([
'resources/assets/src/bower_components/iCheck/skins/square/blue.png',
'resources/assets/src/bower_components/iCheck/skins/square/blue@2x.png',
'resources/assets/src/bower_components/bootstrap-fileinput/img/loading.gif',
'resources/assets/src/bower_components/bootstrap-fileinput/img/loading-sm.gif'
], 'resources/assets/dist/images/')
.task('sass')
.task('uglify');
.copy(convertRelativePath(fonts), 'resources/assets/dist/fonts/')
.copy(convertRelativePath(images), 'resources/assets/dist/images/');
});
// compile sass
gulp.task('sass', () => {
gulp.task('compile-sass', () => {
gulp.src('resources/assets/src/sass/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(cleanCss())
.pipe(gulp.dest('./resources/assets/dist/css'));
});
gulp.task('uglify', () => {
gulp.task('compile-es6', () => {
gulp.src('resources/assets/src/js/*.js')
.pipe(babel({
presets: ['es2015']
}))
.pipe(uglify())
.pipe(gulp.dest('./resources/assets/dist/js'));
});
function clearCache() {
return del([
'storage/logs/*',
'storage/debugbar/*',
'storage/update_cache/*',
'storage/yaml-translation/*',
'storage/framework/cache/*',
'storage/framework/sessions/*',
'storage/framework/views/*'
]);
}
// delete cache files
gulp.task('clear', () => {
clearCache();
@ -115,6 +112,14 @@ gulp.task('clear', () => {
gulp.task('zip', () => {
clearCache();
console.info("============================================================================")
console.info("= Don't forget to compile Sass & ES2015 files before publishing a release! =");
console.info("============================================================================")
let zipPath = `blessing-skin-server-v${version}.zip`;
console.log(`Zip archive will be saved to ${zipPath}.`);
return gulp.src([
'**/*.*',
'LICENSE',
@ -144,6 +149,33 @@ gulp.task('zip', () => {
'!vendor/symfony/css-selector/**/*.*',
'!vendor/symfony/dom-crawler/**/*.*'
], { dot: true })
.pipe(zip('blessing-skin-server-v'+version+'.zip'))
.pipe(gulp.dest('../'));
.pipe(zip(zipPath))
.pipe(gulp.dest('../'))
.pipe(notify({ message: `Zip archive saved to ${zipPath}!` }));
});
gulp.task('notify')
gulp.task('watch', () => {
// Watch .scss files
gulp.watch('resources/assets/src/sass/*.scss', ['compile-sass'], () => notify({ message: 'Sass files compiled!' }));
// Watch .js files
gulp.watch('resources/assets/src/js/*.js', ['compile-es6'], () => notify({ message: 'ES6 scripts compiled!' }));
gulp.watch('resources/assets/src/js/general.js', ['scripts']);
});
function convertRelativePath(paths) {
return paths.map(relativePath => 'resources/assets/src/bower_components/' + relativePath);
}
function clearCache() {
return del([
'storage/logs/*',
'storage/debugbar/*',
'storage/update_cache/*',
'storage/yaml-translation/*',
'storage/framework/cache/*',
'storage/framework/sessions/*',
'storage/framework/views/*'
]);
}

View File

@ -14,7 +14,9 @@
"dev": "gulp watch"
},
"devDependencies": {
"babel-preset-es2015": "^6.18.0",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-clean-css": "^2.0.11",
"gulp-concat": "^2.6.0",
"gulp-jshint": "^2.0.1",

View File

@ -2,49 +2,227 @@
* @Author: printempw
* @Date: 2016-09-15 10:39:41
* @Last Modified by: printempw
* @Last Modified time: 2017-01-18 21:35:01
* @Last Modified time: 2017-01-19 22:42:44
*/
'use strict';
function logout(with_out_confirm, callback) {
if (!with_out_confirm) {
swal({
text: trans('general.confirmLogout'),
type: 'warning',
showCancelButton: true,
confirmButtonText: trans('general.confirm'),
cancelButtonText: trans('general.cancel')
}).then(function() {
do_logout(function(json) {
swal({
type: 'success',
html: json.msg
});
window.setTimeout(function() {
window.location = url();
}, 1000);
});
});
} else {
do_logout(function(json) {
if (callback) callback(json);
});
$.locales = {};
$.currentLocale = {};
/**
* Check if given value is empty.
*
* @param {any} obj
* @return {Boolean}
*/
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
/**
* Load current selected language.
*
* @return void
*/
function loadLocales() {
for (lang in $.locales) {
if (!isEmpty($.locales[lang])) {
$.currentLocale = $.locales[lang] || {};
}
}
}
function do_logout(callback) {
$.ajax({
type: "POST",
url: url('auth/logout'),
dataType: "json",
success: function(json) {
if (callback) callback(json);
},
error: showAjaxError
/**
* Translate according to given key.
*
* @param {string} key
* @param {dict} parameters
* @return {string}
*/
function trans(key, parameters = {}) {
if (isEmpty($.currentLocale)) {
loadLocales();
}
let segments = key.split('.');
let temp = $.currentLocale || {};
for (i in segments) {
if (isEmpty(temp[segments[i]])) {
return key;
} else {
temp = temp[segments[i]];
}
}
for (i in parameters) {
if (!isEmpty(parameters[i])) {
temp = temp.replace(':'+i, parameters[i]);
}
}
return temp;
}
function showModal(msg, title = 'Messgae', type = 'default', callback) {
let btnType = (type != "default") ? "btn-outline" : "btn-primary";
let dom = `
<div class="modal modal-${type} fade in">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">${title}</h4>
</div>
<div class="modal-body">
<p>${msg}</p>
</div>
<div class="modal-footer">
<button type="button" ${callback} class="btn ${btnType}">OK</button>
</div>
</div>
</div>
</div>`;
$(dom).modal();
}
/**
* Show message to div#msg with level
*
* @param {string} msg
* @param {string} type
* @return {void}
*/
function showMsg(msg, type = 'info') {
$("[id=msg]").removeClass().addClass("callout").addClass('callout-'+type).html(msg);
}
/**
* Show modal if error occured when sending an ajax request.
*
* @param {object} json
* @return {void}
*/
function showAjaxError(json) {
if (!json.responseText) {
console.warn('Empty Ajax response body.');
return;
}
showModal(json.responseText.replace(/\n/g, '<br />'), trans('general.fatalError'), 'danger');
}
/**
* Check if current environment is mobile.
*
* @return {Boolean}
*/
function isMobile() {
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
return true;
}
return false;
}
/**
* Get parameters in query string with key.
*
* @param {string} key
* @return {string}
*/
function getQueryString(key) {
result = location.search.match(new RegExp('[\?\&]'+key+'=([^\&]+)','i'));
if (result == null || result.length < 1){
return "";
} else {
return result[1];
}
}
// quick fix for compatibility of String.prototype.endsWith
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.lastIndexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
function url(relativeUri) {
relativeUri = relativeUri || "";
blessing.base_url = blessing.base_url || "";
if (relativeUri[0] != "/") {
relativeUri = "/" + relativeUri;
}
return blessing.base_url + relativeUri;
}
function confirmLogout() {
swal({
text: trans('general.confirmLogout'),
type: 'warning',
showCancelButton: true,
confirmButtonText: trans('general.confirm'),
cancelButtonText: trans('general.cancel')
}).then(() => {
logout().then((json) => {
swal({
type: 'success',
html: json.msg
});
window.setTimeout(() => window.location = url(), 1000);
});
});
}
$(document).ready(function() {
$('li.active > ul').show();
});
function logout() {
return new Promise((resolve, reject) => {
$.ajax({
type: "POST",
url: url('auth/logout'),
dataType: "json",
success: (json) => resolve(json),
error: (json) => {
showAjaxError(json);
reject(json);
}
});
});
}
$('#logout-button').click(() => confirmLogout());
$(document).ready(() => $('li.active > ul').show());

View File

@ -1,176 +0,0 @@
/*
* @Author: printempw
* @Date: 2016-07-16 09:02:32
* @Last Modified by: printempw
* @Last Modified time: 2017-01-18 21:36:24
*/
$.locales = {};
var locale = {};
/**
* Check if given value is empty.
*
* @param {any} obj
* @return {Boolean}
*/
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
/**
* Load current selected language.
*
* @return void
*/
function loadLocales() {
for (lang in $.locales) {
if (!isEmpty($.locales[lang])) {
locale = $.locales[lang] || {};
}
}
}
/**
* Translate according to given key.
*
* @param {string} key
* @param {dict} parameters
* @return {string}
*/
function trans(key, parameters) {
if (isEmpty(locale)) {
loadLocales();
}
parameters = parameters || {};
var segments = key.split('.');
var temp = locale || {};
for (i in segments) {
if (isEmpty(temp[segments[i]])) {
return key;
} else {
temp = temp[segments[i]];
}
}
for (i in parameters) {
if (!isEmpty(parameters[i])) {
temp = temp.replace(':'+i, parameters[i]);
}
}
return temp;
}
function showModal(msg, title, type, callback) {
title = title === undefined ? "Messgae" : title;
type = type === undefined ? "default" : type;
callback = callback === undefined ? 'data-dismiss="modal"' : 'onclick="'+callback+'"';
var btn_type = (type != "default") ? "btn-outline" : "btn-primary";
var dom = '<div class="modal modal-'+type+' fade in"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button><h4 class="modal-title">'+title+'</h4></div><div class="modal-body"><p>'+msg+'</p></div><div class="modal-footer"><button type="button" '+callback+' class="btn '+btn_type+'">OK</button></div></div></div></div>';
$(dom).modal();
}
/**
* Show message to div#msg with level
*
* @param {string} msg
* @param {string} type
* @return {void}
*/
function showMsg(msg, type) {
type = (type === undefined) ? "info" : type;
$("[id=msg]").removeClass().addClass("callout").addClass('callout-'+type).html(msg);
}
/**
* Show modal if error occured when sending an ajax request.
*
* @param {object} json
* @return {void}
*/
function showAjaxError(json) {
if (!json.responseText) {
console.warn('Empty Ajax response body.');
return;
}
showModal(json.responseText.replace(/\n/g, '<br />'), trans('utils.fatalError'), 'danger');
}
/**
* Check if current environment is mobile.
*
* @return {Boolean}
*/
function isMobile() {
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
return true;
}
return false;
}
/**
* Get parameters in query string with key.
*
* @param {string} key
* @return {string}
*/
function getQueryString(key) {
result = location.search.match(new RegExp('[\?\&]'+key+'=([^\&]+)','i'));
if (result == null || result.length < 1){
return "";
} else {
return result[1];
}
}
// quick fix for compatibility of String.prototype.endsWith
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.lastIndexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
function url(relativeUri) {
relativeUri = relativeUri || "";
blessing.base_url = blessing.base_url || "";
if (relativeUri[0] != "/") {
relativeUri = "/" + relativeUri;
}
return blessing.base_url + relativeUri;
}

View File

@ -138,10 +138,8 @@
downloadCompleted: 'Update package download completed.',
extracting: 'Extracting update package..'
},
utils: {
fatalError: 'Fatal Error (Please contact the author)'
},
general: {
fatalError: 'Fatal Error (Please contact the author)',
confirmLogout: 'Sure to log out?',
confirm: 'OK',
cancel: 'Cancel'

View File

@ -138,10 +138,8 @@
downloadCompleted: '更新包下载完成',
extracting: '正在解压更新包'
},
utils: {
fatalError: '严重错误(请联系作者)'
},
general: {
fatalError: '严重错误(请联系作者)',
confirmLogout: '确定要登出吗?',
confirm: '确定',
cancel: '取消'