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文件夹里的文件正确即可。

  • 相关阅读:
    shell脚本查找tcp过多ip地址封掉
    tomcat日志传参乱码问题
    nginx部署vue跨域proxy方式
    nginx部署VUE跨域访问api
    springboot2.1.3 + redisTemplate + Lock 操作 redis 3.0.5
    java8 lamb表达式对List排序
    Mysql5.7降级到5.6遇到的坑
    mac中git使用
    mac中git flow使用
    mac安装openjdk8-maven-mysql-git-docker
  • 原文地址:https://www.cnblogs.com/mcbai/p/7141969.html
Copyright © 2011-2022 走看看