引言
前端从用记事本写静态网页的石器时代,到现在使用Webpack等构建工具,Vue等流行框架的工业时代,的确是发展良多。
有人说requireJS已经过时,现在是Vue,ES6,Webpack的天下。
Vue的确是一个很好的工具,但也只是工具而已,选工具不一定非要选最好的,场景合适就好。
这篇文章简单的说说前代“农业时代”的技术:
requireJS(模块化工具)+koala(预编译器)+browser-sync(热更新工具)+gulp(构建工具)的使用。
前提:
随着前端文件越来越多,管理越来越困难,随之出现了requireJS等模块化工具,不过模块化拆分会带来请求次数增加的问题,大大影响了网页加载速度,于是requireJS提供了一个打包工具r.js,可以将大量零碎文件打包成一个文件,解决请求次数增多的问题。
有开发经验的同学都知道css文件写多了会有非常繁琐的问题,比如,类名冲突,起名难,各种浏览器兼容前缀后缀,使用koala等预编译器很好的解决了这一点。
开发过程中修改文件,浏览器往往有缓存,要一次次的手动清缓存,实在是一种痛苦的事情,browser-sync的出现就是为了解决这种事情。
至于gulp,自动化构建工具,打包压缩,一个命令行搞定,大大减少工作量。
正文
1.使用requireJS实现文件热更新
通过在require配置中增加
urlArgs: new Date().getTime(),
实现在文件后增加随机数的方式,忽略浏览器缓存
2.使用koala编译css文件
可以使用sass、less看个人喜好,拿sass举例,在css文件夹中创建XX.scss,然后直接把css文件夹拖到考拉,然后点击编译即可
工具地址:http://koala-app.com/index-zh.html
3.使用browser-sync实现css样式热更新
地址:http://www.browsersync.cn/
使用非常简单,看教程一分钟学会,可以单独使用,也可以配合gulp使用
4.gulp打包优化
在项目根目录新建gulpfile.js配置如下
var gulp = require('gulp'),
gutil = require('gulp-util'),
concat = require('gulp-concat'),
minifyCss = require('gulp-minify-css'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'),
jshint = require('gulp-jshint'),
requireOptimize = require('gulp-requirejs-optimize'),
browserSync = require('browser-sync'),
rjs = require('requirejs'),
gulp_remove_logging = require("gulp-remove-logging"),
htmlmin = require('gulp-htmlmin'),
assetRev = require('gulp-asset-rev'),
runSequence = require('run-sequence'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
del = require('del'),
imageMin = require('gulp-imagemin'),
pngquant = require('imagemin-pngquant');
var paths = {
scripts: [
['./js/**/*.js', './tpls/*.html', './assets/**/*.js',
'./assets/**/**/*.js', './lib/*.js', 'main.js']
]
};
//脚本检查
gulp.task('lint', function () {
gulp.src('./js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
// 上线压缩css
gulp.task('cssmin', function () {
gulp.src(['./css/*.css'])
.pipe(minifyCss())
.pipe(gulp.dest('dist/css/'))
})
// 压缩图片
gulp.task('images', function () {
gulp.src('./imgs/*.*')
.pipe(imageMin({
progressive: true, // 无损压缩JPG图片
svgoPlugins: [{
removeViewBox: false
}], // 不移除svg的viewbox属性
use: [pngquant()] // 使用pngquant插件进行深度压缩
}))
.pipe(gulp.dest('dist/imgs/'))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task('images-login', function () {
gulp.src('./imgs/login/*.*')
.pipe(imageMin({
progressive: true,
// 无损压缩JPG图片
svgoPlugins: [{
removeViewBox: false
}],
// 不移除svg的viewbox属性
use: [pngquant()]
// 使用pngquant插件进行深度压缩
}))
.pipe(gulp.dest('dist/imgs/login'))
.pipe(browserSync.reload({
stream: true
}));
});
// 压缩html
gulp.task('htmlmin', function () {
var options = {
removeComments: true,
//清除HTML注释
collapseWhitespace: true,
//压缩HTML
collapseBooleanAttributes: true,
//省略布尔属性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true,
//删除所有空格作属性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true,
//删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,
//删除<style>和<link>的type="text/css"
minifyJS: true, //压缩页面JS
minifyCSS: true //压缩页面CSS
};
gulp.src(['./main.html','./index.html'])
.pipe(htmlmin(options))
.pipe(gulp.dest('dist/'));
})
// 压缩lib/js
gulp.task('jsmin', function () {
gulp.src('./lib/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/lib/'));
})
//文件copy到dist上线
gulp.task('ico', function (cb) {
gulp.src(['favicon.ico'])
.pipe(gulp.dest('dist/'))
});
// 将静态文件copy到dist
gulp.task('copy', function () {
gulp.src(['./assets/**'])
.pipe(gulp.dest('dist/assets'))
});
gulp.task('copyimgs', function () {
gulp.src(['./imgs/**'])
.pipe(gulp.dest('dist/imgs'))
})
// js主文件去除console.log
gulp.task('removelog',function(){
gulp.src('./js/**/*.js')
.pipe(gulp_remove_logging({
namespace: ['console']
}))
.pipe(gulp.dest('./js'))
})
//require合并
gulp.task('rjs', function (cb) {
rjs.optimize({
baseUrl: "./js",
mainConfigFile: "main.js",
preserveLicenseComments: false,
//去掉头部版权声明
removeCombined: false,
//自动删除被合并过的文件
}, function (buildResponse) {
// console.log('build response', buildResponse);
cb();
}, cb)
});
// js主文件合并
gulp.task('build', function (done) {
condition = false;
runSequence(
['removelog'] ,['rjs'],
done);
});
// Rerun the task when a file changes
gulp.task('watch', function () {
var watcher = gulp.watch(paths.scripts, ['rjs']);
watcher.on('change', function (event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
});
});
gulp.task('browser', function () {
browserSync.init({
files: ['./css/*.css', './*.js', './js/**/*.js', './tpls/*.html'],
// server:{
// baseDir:'./',
// index:'index.html'
// },
proxy: '127.0.0.1',
port: 80
})
})
gulp.task('dev', [ 'browser');
gulp.task('dist', ['build','cssmin', 'htmlmin', 'jsmin', 'copy', 'ico', 'copyimgs'])
在require的main.js的require.config中配置如下
require.config({
baseUrl: "./js",
urlArgs: new Date().getTime(),
paths: {
jquery: "../lib/jquery-2.1.4",
cookie: "../lib/jquery.cookie",
text: "../lib/text",
artTemplate: "../lib/template-web",
bootstrap: "../assets/bootstrap/js/bootstrap",
pager: "../assets/jQueryPage/pager",
//配置模板文件夹的路径
tpls: "../tpls",
// 日期控件
datetimepicker: "../assets/datetimepicker/js/bootstrap-datetimepicker.min",
clockpicker: "../assets/clockpicker/bootstrap-clockpicker.min",
daterangepicker: "../assets/daterangepicker/js/daterangepicker",
moment: "../assets/daterangepicker/js/moment.min",
datetimepickerLang: "../assets/datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN",
clipboard: "../lib/clipboard",
//打包入口文件
entry: "../main"
},
// 设置依赖
shim: {
bootstrap: {
deps: ["jquery"]
},
datetimepicker: {
deps: ["moment"]
},
clockpicker: {
deps: ["bootstrap"]
},
datetimepickerLang: {
deps: ["datetimepicker"]
},
daterangepicker: {
deps: ["moment"]
},
clipboard: {
deps: ["jquery"]
}
},
//不打包的静态文件
excludeShallow: [
'jquery','bootstrap','clockpicker', 'datetimepickerLang', 'clipboard', 'moment', 'datetimepicker', 'daterangepicker'
],
waitSeconds: 0,
name: "entry",
out: "./dist/main.js"
});
开发使用命令行
gulp dev
上线使用命令行
gulp dist
打包前,如上图,文件请求非常多
打包后,请求少了很多,速度明显加快