Gulp打包优化requireJS

引言

前端从用记事本写静态网页的石器时代,到现在使用Webpack等构建工具,Vue等流行框架的工业时代,的确是发展良多。
有人说requireJS已经过时,现在是Vue,ES6,Webpack的天下。
Vue的确是一个很好的工具,但也只是工具而已,选工具不一定非要选最好的,场景合适就好。
这篇文章简单的说说前代“农业时代”的技术:
requireJS(模块化工具)+koala(预编译器)+browser-sync(热更新工具)+gulp(构建工具)的使用。

前提:

随着前端文件越来越多,管理越来越困难,随之出现了requireJS等模块化工具,不过模块化拆分会带来请求次数增加的问题,大大影响了网页加载速度,于是requireJS提供了一个打包工具r.js,可以将大量零碎文件打包成一个文件,解决请求次数增多的问题。
有开发经验的同学都知道css文件写多了会有非常繁琐的问题,比如,类名冲突,起名难,各种浏览器兼容前缀后缀,使用koala等预编译器很好的解决了这一点。
开发过程中修改文件,浏览器往往有缓存,要一次次的手动清缓存,实在是一种痛苦的事情,browser-sync的出现就是为了解决这种事情。
至于gulp,自动化构建工具,打包压缩,一个命令行搞定,大大减少工作量。

正文

1.使用requireJS实现文件热更新
image.png

通过在require配置中增加

 urlArgs: new Date().getTime(),

实现在文件后增加随机数的方式,忽略浏览器缓存


image.png
2.使用koala编译css文件

可以使用sass、less看个人喜好,拿sass举例,在css文件夹中创建XX.scss,然后直接把css文件夹拖到考拉,然后点击编译即可
工具地址:http://koala-app.com/index-zh.html

image.png
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
image.png

打包前,如上图,文件请求非常多

image.png

打包后,请求少了很多,速度明显加快

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容