前端构建实践 (gulp + Grunt)

基于自己项目开发流程定制的构建步骤

CSS

  1. less to css (具体开发使用的是 less)
  2. css concat
  3. css autoprefixer
  4. css min

JS

  1. js concat
  2. js lint
  3. js uglify

使用 Grunt 基本步骤:

  1. 安装 Nodejs
  2. npm init 新建 package.json (主要用来记录,开发的时候用到的 grunt 的版本号,以及第三方 task ,方便以后复用)
  3. npm install -g grunt-cli (命令行工具全局安装即可)
  4. npm install -S grunt && npm install -D grunt-contrib-xxx ......(项目用到的一些第三方 task)
module.exports = function(grunt) {

  // 注册任务
  // 任务关键词;任务回调
  grunt.registerTask('hi', function() {
    console.log('Ok, I said hi.');
  });

  grunt.registerTask('bye', function() {
    console.log('Ok, I said bye.');
  });

  // 通过关键词,引用已经注册了的任务
  grunt.registerTask('both', ['hi', 'bye']);
  
  // 第三方 task 需要的初始配置
  grunt.initConfig({
    concat: {
      // distribution
      // 其实这里叫啥也没有关系
      // concat 层次以下的,每一个配置对应一个任务,没个任务都可以有不同的配置

      // 对于 JS 来说,concat 起到的作用仅仅只是拼接起来
      concat_js: {
        // 文件名可以用正则表达式
        src: ['js/*.js'],
        dest: 'build/js/scripts.js'
      },

      // 仅仅只是文件拼接,对 CSS 来说还好
      concat_css: {
        src: ['css/*.css'],
        dest: 'build/css/styles.css'
      }
    },

    // 监听文件更新(其实只要你按了保存都会触发),执行例行任务
    watch: {
      js_refresh: {
        files: ['js/*.js'],
        tasks: ['concat:concat_js', 'jshint', 'uglify']
      },
      css_refresh: {
        files: ['css/*.css'],
        tasks: ['concat:concat_css', 'autoprefixer', 'cssmin']
      },
      less_refresh: {
        files: ['css/*.less'],
        tasks: ['less', 'concat:concat_css', 'autoprefixer', 'cssmin']
      }
    },
    
    // JS 检查
    jshint: {
      after_concat: ['build/js/*.js']
    },

    // JS 压缩
    uglify: {
      after_concat: {
        files: {
          'build/js/scripts.min.js': ['build/js/scripts.js']
        }        
      }
    },

    // CSS 加前缀
    autoprefixer: {
      after_concat: {
        src: ['build/css/*.css']
      }
    },

    // CSS 压缩
    cssmin: {
      after_concat: {
        files: [{
          expand: true,
          cwd: 'build/css',
          src: ['*.css', '!*.min.css'],
          dest: 'build/css',
          ext: '.min.css'
        }]
      }
    },

    // less 编译,这里的 less to css 只能一对一对地添加,还没找到更加高效的方法
    less: {
      before_concat: {
        files: {
          'css/screen-background.css': 'css/screen-background.less',
          'css/text-color.css': 'css/text-color.less'          
        }
      }
    }
  });

  // 拼接文件
  grunt.loadNpmTasks('grunt-contrib-concat');
  // 监听文件变化
  grunt.loadNpmTasks('grunt-contrib-watch');

  // JS 代码检查
  // document.write 这种接口的使用会被抱错,因为不安全  
  grunt.loadNpmTasks('grunt-contrib-jshint');
  // JS 压缩
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // auto-prefixer
  grunt.loadNpmTasks('grunt-autoprefixer');
  // CSS 压缩
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  // 编译 less
  grunt.loadNpmTasks('grunt-contrib-less');



  // 一般来说的默认任务都是,执行完必要流程之后,watch
  grunt.registerTask('default', ['less', 'concat:concat_css', 'autoprefixer', 'cssmin', 'concat:concat_js', 'jshint', 'uglify', 'watch']);
};

// JS 合并,代码检查,压缩
// CSS less to css,合并,加前缀,压缩

// default: less to css, css concat, css autoprefixer, css min > js concat js hint js uglify

项目结构

使用第三方 task

  • tasks
  • 找到对应的 github 项目地址,按照文档或例子要求配置 Gruntfile.js 并使用即可

使用 gulp 基本步骤

  1. 安装 Nodejs
  2. npm init 新建 package.json (主要用来记录,开发的时候用到的 grunt 的版本号,以及第三方 task ,方便以后复用)
  3. npm install -g gulp-cli (命令行工具全局安装即可)
  4. npm install -S gulp && npm install -D gulp-xxx ......(项目用到的一些第三方 task)
var gulp = require('gulp');
var less = require('gulp-less');
var path = require('path');
var concatCss = require('gulp-concat-css');
var autoPrefixer = require('gulp-autoprefixer');
var cssMin = require('gulp-cssmin');
var rename = require('gulp-rename');
var concat = require('gulp-concat');
var jslint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var pump = require('pump');

// 定义任务
// 关键词,对应任务回调
gulp.task('hi', function() {
  console.log('hi, neo......');
});

// less to css
gulp.task('less_to_css', function() {
  return gulp.src('./css/*.less')
    .pipe(less({
      paths: [ path.join(__dirname, 'less', 'includes') ]
    }))
    .pipe(gulp.dest('./css'));
});

// css concat
gulp.task('css_concat', ['less_to_css'], function() {
  return gulp.src('./css/*.css')
    // 目标文件名
    .pipe(concatCss('styles.css'))
    // 目标文件夹
    .pipe(gulp.dest('build/css'));
});

// autoprefix
gulp.task('prefix', ['css_concat'], function() {
  return gulp.src('./build/css/*.css')
    .pipe(autoPrefixer({
      browsers: ['last 2 versions'],
      cascade: false
    }))
    .pipe(gulp.dest('build/css'));
});

// css min
gulp.task('css_min', ['prefix'], function() {
  return gulp.src('./build/css/styles.css')
    .pipe(cssMin())
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest('build/css'));
});

// js concat
gulp.task('js_concat', function() {
  return gulp.src('./js/*.js')
    .pipe(concat('scripts.js'))
    .pipe(gulp.dest('./build/js'));
});

// js hint
// 这个 jshint 允许 document.write 的使用
gulp.task('js_lint', ['js_concat'], function() {
  return gulp.src('./build/js/*.js')
    .pipe(jslint())
    .pipe(jslint.reporter('default'));
});

// js uglify than min
gulp.task('uglify', ['js_lint'], function(cb) {
  pump([
    gulp.src('./build/js/scripts.js'),
    uglify(),
    rename({suffix: '.min'}),
    gulp.dest('./build/js')
  ], cb);
});

// 重新组织任务流
gulp.task('css_related', ['less_to_css', 'css_concat', 'prefix', 'css_min']);
gulp.task('js_related', ['js_concat', 'js_lint', 'uglify']);
gulp.task('default', ['css_related', 'js_related']);

gulp.watch('./css/*.less', ['css_related']);
gulp.watch('./js/*.js', ['js_related']);

// 我之前自己开发工作的构建流程
// css
// 1. less to css
// 2. 合并
// 3. autoprefix
// 4. 压缩

// js
// 1. 合并
// 2. 代码检查
// 3. uglify

// 文件监听

refs:

ps:

  • 博客园的 markdown 编辑器貌似不支持行内的 box-shadow CSS 属性
原文地址:https://www.cnblogs.com/mengshi13/p/6081860.html