天天看点

使用gulp快速开发静态页

前言

如今我们开发web网页的方式主要有几种,使用

vue-cli、create-react-app、webpack、不借助构建工具

等实现单页或多页网站。“工欲善其事,必先利其器”,前三种方式无疑能满足我们开发网页的绝大部分需求,但在某些情况下,比如前后端不分离(jsp、php、tpl等嵌套后端语言的方式),以及单纯地开发一些静态页(活动页、帮助手册等),使用gulp搭建一个轻量级的前端开发环境是一个选择。

gulp相对上手简单,有经验的前端也都比较熟悉,这里不打算一步步地介绍gulp开发环境的搭建,而是分享一下实际使用gulp的代码及思路。

实现哪些功能

使用gulp的目的是实现自动化构建,提升开发效率、代码质量,所以有以下一些目标。

  1. 压缩html、css、js、图片
  2. 编译ES6、less/scss
  3. 补全css前缀
  4. px转rem
  5. 静态资源缓存控制
  6. 静态服务器
  7. 代码检查

实际上gulp能做到的还有更多,不过出于开发静态页的目的,这里只罗列了一些常用功能。

代码

基本目录如下

使用gulp快速开发静态页

gulpfile.js主要代码

静态服务器
gulp.task('server', done => {
    connect.server({
        root: 'dist',//根目录
        livereload: true,//自动更新
        port: 9090//端口
    })
    done();
});
           
压缩html
gulp.task('html', function () {
    return gulp.src('src/*.html')
        .pipe(htmlmin({ collapseWhitespace: true }))
        .pipe(gulp.dest('dist'))
        .pipe(connect.reload())
})
           
编译并压缩css
gulp.task('css', done => {
    var processors = [px2rem({ remUnit: 100 })];

    gulp.src('src/less/**/*.less')   //获取所有less文件路径
        .pipe(less())           //执行less
        .pipe(autoprefixer({//补全前缀
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ]
        }))
        .pipe(postcss(processors))//px转rem tips: 如果某个px不转换,可使用大写代替,类似1PX
        .pipe(minifyCss())
        .pipe(gulp.dest('dist/css'))
        .pipe(connect.reload())

    done();
});
           
编译并压缩js
gulp.task('js', function () {
    return gulp.src('src/js/**/*.js')
        //.pipe(jshint())//检查代码
        .pipe(babel({//编译ES6
            presets: ['@babel/env']
        }))
        .pipe(uglify())//压缩js
        .pipe(gulp.dest('dist/js'))
        .pipe(connect.reload())
})
           
压缩图片
gulp.task('images', function () {
    return gulp.src('src/images/**/*.+(png|jpg|jpeg|gif|svg)')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/images'))
});
           
监控文件变化
gulp.task('watcher', done => { //监听变化
    gulp.watch('src/*.html', gulp.series('html'));
    gulp.watch('src/less/**/*.less', gulp.series('css'));
    gulp.watch('src/js/**/*.js', gulp.series('js'));
    gulp.watch('src/images/**/*', gulp.series('images'));

    done();
})
           
生成带hash值的文件名及路径

这里还使用了

gulp-rev-delete-original

删除旧文件。

gulp.task("hash", done => {
    gulp
        .src("dist/**")
        .pipe(
            RevAll.revision({
                dontRenameFile: [/\.html$/]
            })
        )
        .pipe(revdel({
            exclude: function (file) {
                if (/\.html$/.test(file.name)) {
                    return true; //if you want to exclude the file from being deleted
                }
            }
        }))
        .pipe(gulp.dest("dist"))

    done();
});
           
gulp命令

打开本地服务器,以及打包文件。

// 初始化
gulp.task('init', gulp.series('clean', gulp.parallel('html', 'css', 'js', 'images')));
// 开发
gulp.task('default', gulp.series('init', 'server', 'watcher'));
// 打包
gulp.task('build', gulp.series('hash'));
           

可以看出上面的代码比较简单,因为初衷是做一些简单的静态页,所以并没有做得比较复杂,监控文件变化编译至dist目录,再由gulp-rev-all生成hash文件名。

前后端不分离的情况

这里需要区分前后端不分离的情况,由于公司的技术不升级,或者需要维护老项目,就要应付前后端不分离的场景。比如页面是jsp、php文件,这时静态页跟实际页面并没有直接对应关系,每次gulp打包后,gulp-rev-all会重新生成带hash的文件和路径,并且不支持

test.css?v=123

这种方式,这样全部手动复制到项目目录并不实际,只能放弃gulp-rev-all(

build

),并且移除代码压缩。

值得一提的是,前后端不分离可以用后端语言进行资源的缓存控制,例如使用php读取文件的修改日期来做版本号。

function autoVersion($file) {  
    if( file_exists($_SERVER['DOCUMENT_ROOT'].$file) ) {  
        $ver = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);  
    } else {  
        $ver = 1;  
    }  
    return $file .'?v=' .$ver;  
}  
           

此外,应对前后端不分离应该还有一种解决方案,借助构建工具直接生成后端所需的模板文件(如index.tpl),这里暂不讨论。

最后

这些是根据工作经验总结出来的,虽然当下使用或基于webpack开发单页是主流,但在某些覆盖不到的场景下进行一些梳理还是有必要的。

源码地址:gulp-util,另外附上一个webpack多页脚手架webpack-multiple-entry,这是作者fork别人的项目来修改的,比较简单实用,感兴趣的小伙伴可以参考下。