2

基于gulp的项目搭建

gulp简介

gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能够极大的提高开发效率。

在 Web 前端开发工作中有很多“重复工作”,比如压缩CSS/JS文件。而这些工作都是有规律的。找到这些规律,并编写 gulp 配置代码,让 gulp 自动执行这些“重复工作”。

下面的配置文件提供了基于 browserSync 的代码实时预览功能,开发过层中可自动刷新

项目结构

└── project
    ├── static                     -- html
    ├── images                     -- js/css/img...  项目需要所有资源放在images文件夹下
    ├── preview                    -- 项目预览目录
    ├── build                      -- 项目发布目录
    ├── gulpfile.js                -- gulp任务配置
    └── config.json                -- 项目配置文件

gulp配置

引入依赖

gulp插件列表

var gulp = require('gulp'),
    browserSync = require('browser-sync').create(), //浏览器同步测试
    reload = browserSync.reload,
    watch = require('gulp-watch'),  //文件监控
    uglify = require('gulp-uglify'),    //压缩js
    concat = require('gulp-concat'),    //合并文件
    jshint = require('gulp-jshint'),    //js检查
    csslint = require('gulp-csslint'),  //css检查
    csso = require('gulp-csso'),    //css压缩
    prefixer = require('gulp-autoprefixer'),
    clean = require('gulp-clean'),  //文件清理
    rename = require("gulp-rename"),    //文件名操作
    zip = require('gulp-zip'),  //压缩
    imagemin = require('gulp-imagemin'),    //图片压缩
    template = require('gulp-template'),    //模版替换
    processhtml = require('gulp-processhtml'),  //引用替换
    gulpif = require('gulp-if'),    //变量判断
    minimist = require('minimist'), //命令行参数
    fileinclude = require('gulp-file-include'), //html引用
    shell = require('gulp-shell'),  //执行脚本

    config = require('./config.json');  //配置文件

配置命令行参数

// 环境变量参数 
    var knownOptions = {
        string: 'env',
        default: {
            env: 'dev'
        }
    };

    // 文件名参数
    var filetask = {
        string: 'file',
        default: {
            file: 'all'
        }
    };

    // --env dev
    // --env pro

    var options = minimist(process.argv.slice(2), knownOptions, filetask);

js任务

    // ----- js -----
    gulp.task('jstask', function() {
        if (!options.file) {
            console.log('检查全部js文件');
            console.log('运行gulp jstask --file 文件名,查看对应文件错误信息');
            return gulp.src('./images/*.js')
                // js检查
                .pipe(jshint())
                .pipe(jshint.reporter('fail'));
        } else {
            console.log('检查js文件: ./images/' + options.file);
            return gulp.src('./images/' + options.file)
                // js检查
                .pipe(jshint())
                .pipe(jshint.reporter('default'));
        }
    });

    // js压缩发布
    gulp.task('jstask-min', ['jstask'], function() {
        return gulp.src('./build/*.js')
            // 合并js
            .pipe(concat('main.min.js'))
            // 压缩js
            .pipe(uglify())
            .pipe(gulp.dest('./build'));
    });

css任务

// ----- css -----
    gulp.task('csstask', function() {
        if (!options.file) {
            console.log('检查全部css');
            console.log('运行gulp csstask --file 文件名,查看对应文件错误信息');
            return gulp.src('./images/*.css')
                // css检查
                .pipe(csslint())
                .pipe(csslint.reporter('fail'));

        } else {
            console.log('检查css文件: ./images/' + options.file);
            return gulp.src('./images/' + options.file)
                // css检查
                .pipe(csslint())
                .pipe(csslint.reporter());
        }
    });

    // css压缩发布
    gulp.task('csstask-min', ['csstask'], function() {
        return gulp.src('./build/*.css')
            //压缩css 
            .pipe(csso())
            .pipe(gulp.dest('./build/'));
    });

html任务

// ----- html 内容替换 -----

    //迁移public文件夹 
    gulp.task('public', function() {
        return gulp.src('./static/public/*')
            .pipe(gulp.dest('./preview/public'));
    });

    gulp.task('contenttask', ['public'], function() {
        console.log('打包环境: ' + options.env);
        return gulp.src('./template/**/*.{html,shtml}')
        
        // 替换内容
        // 使用<%=变量名%>作为变量
        .pipe(gulpif(options.env === 'dev', template(config.dev_template, {
                'interpolate': /<%=([\s\S]+?)%>/g
            })))
            .pipe(gulpif(options.env === 'pro', template(config.pro_template, {
                'interpolate': /<%=([\s\S]+?)%>/g
            })))
            // 替换引用
            .pipe(processhtml())
            .pipe(gulp.dest('./build'))

        // 生产以站点id为文件名的.site文件
        .pipe(gulpif(options.env === 'dev', shell(['touch <%= siteId %>.site'], {
                templateData: {
                    siteId: config.testSiteId
                }
            })))
            .pipe(gulpif(options.env === 'pro', shell(['touch <%= siteId %>.site'], {
                templateData: {
                    siteId: config.proSiteId
                }
            })));
    });

    gulp.task('contenttask-preview', ['public'], function() {
        return gulp.src('./static/**/*.{html,shtml}')
            // 替换内容
            .pipe(template(config.preview_template))
            // 替换引用
            .pipe(processhtml())
            .pipe(fileinclude({
                prefix: '@@',
                basepath: '@file'
            }))
            .pipe(gulp.dest('./preview'));
    });

    gulp.task('contenttask-watch', ['public'], function() {
        return gulp.src('./static/**/*.{html,shtml}')
            .pipe(watch('./static/**/*.{html,shtml}')) // 只重新编译被更改过的文件
            // 替换内容
            .pipe(template(config.debug_template))
            // 替换引用
            .pipe(processhtml())
            .pipe(fileinclude({
                prefix: '@@',
                basepath: '@file'
            }))
            .pipe(gulp.dest('./preview'));
    });

文件操作

// ----- 文件操作 ----- 

    // 文件清理
    gulp.task('clean', function() {
        return gulp.src(['./build', './preview', './*.site'], {
                read: false
            })
            .pipe(clean({
                force: true
            }));
    });

    gulp.task('clean-build', function() {
        return gulp.src(['./build'], {
                read: false
            })
            .pipe(clean({
                force: true
            }));
    });

    gulp.task('clean-preview', function() {
        return gulp.src(['./preview'], {
                read: false
            })
            .pipe(clean({
                force: true
            }));
    });

图片压缩

// ----- 压缩图片 ----- 

    //压缩图片 - imagemin
    gulp.task('imagemin', function() {
        return gulp.src('./images/*.{png,jpg,jpeg,gif}')
            .pipe(imagemin({
                progressive: true,
                svgoPlugins: [{
                    removeViewBox: false
                }],
                use: [pngquant({
                    quality: '100'
                })]
            }))
            .pipe(gulp.dest('./images'));
    });

本地预览

// 开启本地 Web 服务器功能
    gulp.task('webserver-static', function() {
        // 开发预览
        browserSync.init({
            port: config.serverPort,
            server: {
                baseDir: ["preview", "./"], //根目录
                directory: true, //是否显示目录
                middleware: function(req, res, next) {
                    var fs = require('fs');
                    var ssi = require('ssi'); //支持shtml
                    var baseDir = './preview/';
                    var pathname = require('url').parse(req.url).pathname;
                    var filename = require('path').join(baseDir, pathname.substr(-1) === '/' ? pathname + 'index.shtml' : pathname);
                    var parser = new ssi(baseDir, baseDir, '/**/*.shtml', true);
                    if (filename.indexOf('.shtml') > -1 && fs.existsSync(filename))
                        res.end(parser.parse(filename, fs.readFileSync(filename, {
                            encoding: 'utf8'
                        })).contents);
                    else
                        next();
                }
            }
        });

        // 监听文件变化刷新页面
        gulp.watch('./**/*').on("change", browserSync.reload);
    });

配置任务

// ----- 任务 ----- 

    //默认任务
    gulp.task('default', function() {
        gulp.run('help');
    });

    gulp.task('help', function() {
        console.log('gulp build --env dev          ---测试环境模板打包');
        console.log('gulp build --env pro          ---生产环境模板打包');
        console.log('gulp debug                    ---本地调试');
        console.log('gulp jstask                   ---js文件检查');
        console.log('gulp jstask --file 文件名     ---检查js文件');
        console.log('gulp csstask                  ---css文件检查');
        console.log('gulp csstask --file 文件名    ---检查css文件');
        console.log('gulp imagemin                 ---图片压缩');
    });

    //项目完成提交任务
    gulp.task('build', ['clean-build'], function(a) {
        gulp.run('contenttask');
        gulp.run('imagemin');
    });

    // 预览
    gulp.task('preview', ['clean-preview'], function(a) {
        gulp.run('contenttask-preview');
    });

    // 本地调试
    gulp.task('debug', ['clean-preview'], function(a) {
        gulp.run('contenttask-watch');
        gulp.run('webserver-static');
    });

    //项目完成提交任务
    gulp.task('build-min', ['clean'], function() {
        gulp.run('jstask-min');
        gulp.run('csstask-min');
        gulp.run('contenttask');
        gulp.run('imagemin');
    });

气象卫星随机号
269 声望9 粉丝

引用和评论

0 条评论