zoukankan      html  css  js  c++  java
  • gulp实用配置(2)——中小项目

    上一篇的gulp配置很简单,主要就是为了demo的查看和调试,这一篇则会相对详细一些,包括压缩合并打时间戳等。

    在互联网环境比较好的城市,需要多人协作的,大一点的项目应该都用上了模块化(这里主要指commonjs和ES6模块系统,不是再早的require.js和sea.js)。代码也会更注重如何分离和注入,而不再是单纯的合并。

    但是在很多小公司,开发模式或技术都还是比较传统的,或者一些小项目也完全不需要用上那些比较前沿的技术。

    所以这篇配置就主要为了这样的中小项目。

    1.所需工具和版本

    包管理工具:yarn v0.24.5

    自动化构建工具:gulp v4.0

    2.工具安装

    yarn add global gulpjs/gulp#4.0

    3.开发环境配置

    var gulp = require('gulp'),
        pug = require('gulp-pug'),
        less = require('gulp-less'),
        //当发生异常时提示错误 确保本地安装gulp-notify和gulp-plumber
        notify = require('gulp-notify'),
        plumber = require('gulp-plumber'),
        sourcemaps = require('gulp-sourcemaps'),
        browserSync = require('browser-sync').create()
        reload = browserSync.reload;
    
    var LessAutoprefix = require('less-plugin-autoprefix'),
        autoprefix = new LessAutoprefix({ browsers: ['last 2 versions'] });
    
    // 文件路径
    var paths = {
      pug: {
        src: 'src/pug/pages/*.pug',
        dest: 'dev/html/',
        watch: 'src/pug/**/*.pug'
      },
      less: {
        src: 'src/less/**/*.less',
        dest: 'dev/css/',
        watch: 'src/less/**/*.less'
      },
      js: {
        src: 'src/js/**/*.js',
        dest: 'dev/js/',
        watch: 'src/js/**/*.js'
      },
      img: {
        src: 'src/img/**/*',
        dest: 'dev/img/',
        watch: 'src/img/**/*'
      }
    }
    
    // 启动 browserSync 服务,自己启动server,并且为浏览器实时刷新提供服务
    gulp.task('browserSync', function() {
      return browserSync.init({
        server: {
          baseDir: './'
        },
        files: './dev/**/*'
      });
    })
    
    // 将pug文件转换为html
    gulp.task('pug', function buildHTML() {
      return gulp.src(paths.pug.src)
        .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
        .pipe(pug())
        .pipe(gulp.dest(paths.pug.dest));
    });
    
    // 编译less文件
    gulp.task('less', function() {
      return gulp.src(paths.less.src)
        .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
        .pipe(sourcemaps.init())
        .pipe(less({
          plugins: [autoprefix]
        }))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(paths.less.dest));
    })
    
    // 复制js文件
    gulp.task('js', function() {
      return gulp.src(paths.js.src)
        .pipe(gulp.dest(paths.js.dest));
    })
    
    // 复制img文件
    gulp.task('img', function() {
      return gulp.src(paths.img.src)
        .pipe(gulp.dest(paths.img.dest));
    })
    
    
    // 监听文件变化
    gulp.task('watch', function() {
      gulp.watch(paths.pug.watch, gulp.parallel('pug'))
      gulp.watch(paths.less.watch, gulp.parallel('less'))
      gulp.watch(paths.js.watch, gulp.parallel('js'))
      gulp.watch(paths.img.watch, gulp.parallel('img'))
    })
    
    // 默认任务,在命令行输入`gulp`来启动任务
    gulp.task('default', gulp.parallel('watch', 'browserSync', 'pug', 'less', 'js'))

    gulp-pug这个插件是用来编译pug模板的,也就是以前的jade模板,pug模板是一个很强大的前后端通用的模板引擎,而且学习也很简单,具体用法可以看我另外一篇关于pug的教程文章——基于express+mongodb+pug的博客系统——pug篇。

    大家知道gulp在监听任务的过程中,如果某个环节出了错误,gulp就会被中断,然后得重新启动gulp任务才行,这是一件很麻烦的事。这里可以通过gulp-notify和gulp-plumber两个插件来避免gulp任务中断。

    4.生产环境配置

    var gulp = require('gulp'),
      del = require('del'),
      pug = require('gulp-pug'),
      less = require('gulp-less'),
      cleanCSS = require('gulp-clean-css'),
      base64 = require('gulp-tobase64'),
      // img64 = require('gulp-imgbase64'),
      imagemin = require('gulp-imagemin'),
      babel = require('gulp-babel'),
      uglify = require('gulp-uglify'),
      rev = require('gulp-rev'), // 添加时间戳
      revCollector = require('gulp-rev-collector');
    
    
    var LessAutoprefix = require('less-plugin-autoprefix'),
      autoprefix = new LessAutoprefix({
        browsers: ['last 2 versions']
      });
    
    // 文件路径
    var paths = {
      pug: {
        src: 'src/pug/pages/*.pug',
        dest: 'dist/html/'
      },
      less: {
        src: 'src/less/main.less',
        dest: 'dist/css/'
      },
      js: {
        src: ['src/js/**/*.js', '!src/js/lib/*.js'],
        dest: 'dist/js/'
      },
      img: {
        src: 'src/img/**/*',
        dest: 'dist/img/'
      }
    };
    
    
    // 将pug文件转换为html
    gulp.task('pug', function() {
      return gulp.src(paths.pug.src)
        .pipe(pug())
        .pipe(gulp.dest(paths.pug.dest));
    });
    
    // 编译less文件
    gulp.task('less', function() {
      return gulp.src(paths.less.src)
        .pipe(less({
          plugins: [autoprefix]
        }))
        .pipe(base64({
          maxsize: 8
        }))
        .pipe(cleanCSS({
          compatibility: 'ie8' // 兼容性前缀保留
        }))
        .pipe(rev())
        .pipe(gulp.dest(paths.less.dest))
        .pipe(rev.manifest())
        .pipe(gulp.dest('rev/css'))
    });
    
    // 压缩图片
    gulp.task('img', function() {
      return gulp.src(paths.img.src)
        .pipe(imagemin({
          optimizationLevel: 3,
          progressive: true,
          interlaced: true
        }))
        .pipe(gulp.dest(paths.img.dest));
    });
    
    // 编译JS文件
    gulp.task('js', function() {
      return gulp.src(paths.js.src)
        .pipe(babel({
          presets: ['es2015']
        }))
        .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest(paths.js.dest))
        .pipe(rev.manifest())
        .pipe(gulp.dest('rev/js'));
    });
    // 引用的外部 JS 库,不需要做压缩和打时间戳等处理
    // 所以直接复制就行
    gulp.task('copyJs', function() {
      return gulp.src('src/js/lib/*.js')
        .pipe(gulp.dest('dist/js/lib/'))
    })
    
    // 替换加了MD5时间戳的文件
    gulp.task('rev', gulp.series(gulp.parallel('img64', 'less', 'js'), function() {
      return gulp.src(['rev/**/*.json', 'dist/html/*.html'])
        .pipe(revCollector({
          replaceReved: true
        }))
        .pipe(gulp.dest(paths.pug.dest));
    }));
    // Clean 任务执行前,先清除之前生成的文件
    gulp.task('clean', function() {
      return del('dist/')
    });
    
    // 默认任务,在命令行输入`gulp`来启动任务
    gulp.task('default', gulp.series('clean', gulp.series('img', gulp.parallel('rev', 'copyJs'))))

    在生成环境中,代码需要压缩合并,另外在每次代码更新发布新版本时,为了用户客户端能下载更新代码,所以我们还需要给CSS和JS文件打上时间戳。

    gulp-rev这个插件就专门给文件打MD5戳的,打完MD5戳之后,HTML文件里的引用当然也需要更改,如果每个都去手动更改肯定会是一件很麻烦的事,所以我们还需要gulp-rev-collector这个插件来帮我们替换打了MD5戳的文件。

    gulp-imgbase64,这个插件可以指定html文件中,哪些img元素转换为base64,需要更加个性化转换的可以使用这个插件。

    5.项目目录结构

    XXX——

      | — dist

        | — html

        | — css

        | — img

        | — js

          | — lib

      | — dev

        | — html

        | — css

        | — img

        | — js

          | — lib

      | — src

        | — pug

          | — components

          | — pages

          | — layout.pug

        | — less

          | — pages

          | — main.less

          | — reset.less

          | — common.less

          | — feature.less

        | — img

        | — js

          | — lib

    src文件夹里是主要的业务代码,这里面是需要长期维护的代码。

    dev文件夹是开发时gulp生成代码的地方。

    dist文件夹是生成时gulp生成代码的地方。

    在这份配置里,我并没有像其他很多人那样,把开发时通过gulp生成的代码也放在src文件夹里,因为那样会造成很多引用上的麻烦,而且把开发和生产的代码环境都分开,能很好保持src文件夹里的纯净,不会有任何杂乱代码。

    所以一些没经过gulp处理的文件,我会直接把它们复制到dev或者dist文件夹里对应的位置。

    dist文件夹在每次gulp任务生成代码前都会被清空,所以我们不用关心dist文件夹里的内容。

    而dev文件夹可能会有很多冗余文件,但我们也不需要担心它会对我们造成任何影响,文件删除或覆盖都不重要,只需要保证src文件夹里的文件正确即可。

  • 相关阅读:
    Maven 环境的配置
    zTree的简单例子
    plsql免安装客户端的配置
    HDU 1232 畅通工程
    HDU 5698 瞬间移动
    Codeforces 1015E1 Stars Drawing (Easy Edition)
    Codeforces 784B Santa Claus and Keyboard Check
    Codeforces 500C New Year Book Reading
    NSarray 赋值 拷贝 等问题记录
    UINavigationController 操作记录
  • 原文地址:https://www.cnblogs.com/mcbai/p/7141969.html
Copyright © 2011-2022 走看看