• gulp学习


    gulp 基础

    gulp 是基于 nodejs 的用自动化构建工具,可以通过 gulp 和各种插件实现前端的开发自动化工作流程。

    快速入门

    第一步: 全局安装 gulp:

    $ npm install --global gulp

    第二步: 作为项目的开发依赖(devDependencies)安装

    $ npm install --save-dev gulp

    第三步:

    在项目根目录下创建一个名为 gulpfile.js 的文件:

    var gulp = require('gulp');
    
    gulp.task('default', function() {
      // 将你的默认的任务代码放在这
    });

    第四步: 运行 gulp:

    $ gulp

    默认的名为 default 的任务(task)将会被运行,在这里,这个任务并未做任何事情。 想要单独执行特定的任务(task),请输入 gulp 。

    gulp API 文档

    gulp 一共就 4 个 api, src 、dest 、task 、watch

    具体细节请参考官方文档

    适合初学者的 gulp+requirejs 的项目模板

    虽然,webpack已经大行其道。作为初学者,gulp 依然是最快的入门学习前端工作流的工具。本项目本着为中小型团队打造一个基于:gulp+sass+requirejs+es6+eslint+arttemplate 的基本的项目模板。

    项目模板在线 github 地址

    gulp 相关应用

    • js(用 requirejs 管理模块)
      • 压缩
      • 转码
      • 版本号
      • 自动修改注入 requirejs 的 paths
      • es6 转码
      • eslint 检测
      • 添加版本信息
    • style
      • sass
      • 合并
      • 压缩
      • 加前缀
      • 打版本
      • sourcemap(开发)
    • 图片压缩优化
    • html
      • 压缩
      • 修改 url 地址
    • 打包前清理
    • 打包后拷贝目录

    编辑器的一致性

    • .editorconfig 文件控制编辑器的一致性
    • eslint 校验一致性,并配置 vscode 自动修改符合 eslint 校验,可以安装 eslint 插件。

    本地测试和代理配置

    • 运行本地测试
    $ npm run dev

    本地启动服务器地址: http://localhost:8000

    打包

    $ npm run build
    
    # 会把最终结果输出到dist目录

    项目的目录结构

    .
    ├── gulpfile.js
    ├── package.json
    ├── readme.md
    ├── src
    │   ├── app.js
    │   ├── asset
    │   │   └── img
    │   │       └── a.jpg
    │   ├── controller
    │   │   └── student
    │   │       └── listController.js
    │   ├── index.html
    │   ├── js
    │   │   ├── E.js
    │   │   ├── index.js
    │   │   ├── rev-manifest.json
    │   │   └── tmpl
    │   │       ├── header.js         // 自动生成
    │   │       ├── student.js        // 自动生成
    │   │       └── user.js
    │   ├── lib
    │   │   ├── arttemplate
    │   │   │   ├── es5-sham.min.js
    │   │   │   ├── es5-shim.min.js
    │   │   │   ├── json3.min.js
    │   │   │   └── template-web.js
    │   │   └── require.js
    │   ├── service
    │   │   └── index.js              // 所有的服务
    │   ├── style
    │   │   ├── a.css
    │   │   ├── main.css
    │   │   ├── rev-manifest.json
    │   │   └── scss
    │   │       ├── b.scss
    │   │       └── index.scss
    │   ├── template                 //  art-template模板
    │   │   ├── header
    │   │   │   └── header.html
    │   │   ├── student
    │   │   │   ├── stuList.html
    │   │   │   ├── t.html
    │   │   │   └── userList.html
    │   │   └── user
    │   │       └── footer.html
    │   └── view
    │       ├── about.html
    │       └── student
    │           └── list.html
    └── yarn.lock

    gulpfile 细节

    'use strict';
    const fs = require('fs');
    const path = require('path');
    
    // 引入gulp包, nodejs代码
    const gulp = require('gulp'),
      // 引入gulp-sass 包
      sass = require('gulp-sass'),
      // gulp版本定义
      rev = require('gulp-rev'),
      concat = require('gulp-concat'), // 合并文件 --合并只是放一起--压缩才会真正合并相同样式
      rename = require('gulp-rename'), // 设置压缩后的文件名
      // 替换版本url
      revCollector = require('gulp-rev-collector'),
      // css 压缩
      cleanCss = require('gulp-clean-css'),
      // 兼容处理css3
      autoprefixer = require('gulp-autoprefixer'),
      // css代码map
      sourcemaps = require('gulp-sourcemaps'),
      // js 压缩
      uglify = require('gulp-uglify'),
      // img 压缩
      imgagemin = require('gulp-imagemin'),
      // 清理文件夹
      clean = require('gulp-clean'),
      // 顺序执行
      runSequence = require('gulp-run-sequence'),
      // 给js文件替换文件路径
      configRevReplace = require('gulp-requirejs-rev-replace'),
      // 过滤
      filter = require('gulp-filter'),
      // js校验
      eslint = require('gulp-eslint'),
      // babel 转换es6
      babel = require('gulp-babel'),
      // 本地的测试服务器
      connect = require('gulp-connect'),
      // 本地测试服务器中间件
      proxy = require('http-proxy-middleware'),
      // 服务器的代理插件
      modRewrite = require('connect-modrewrite'),
      // 打开浏览器
      open = require('gulp-open'),
      // html 压缩
      htmlmin = require('gulp-htmlmin'),
      replace = require('gulp-replace'),
      // 自动编译artTemplate模板成js文件
      tmodjs = require('gulp-tmod');
    // minifyHtml = require('gulp-minify-html'); 样式处理工作流:编译sass → 添加css3前缀 → 合并 →
    // 压缩css →添加版本号
    gulp.task('style', function(e) {
      // 过滤非sass文件
      var sassFilter = filter(['**/*.scss'], { restore: true });
      return gulp
        .src(['./src/style/**/*.{scss,css}', '!./src/style/main.css']) // 读取sass文件
        .pipe(sassFilter)
        .pipe(sass()) // 编译sass
        .pipe(sassFilter.restore)
        .pipe(
          autoprefixer({
            // 兼容css3
            browsers: ['last 2 versions'], // 浏览器版本
            cascade: true, // 美化属性,默认true
            add: true, // 是否添加前缀,默认true
            remove: true, // 删除过时前缀,默认true
            flexbox: true // 为flexbox属性添加前缀,默认true
          })
        )
        .pipe(concat('main.css')) // 合并css
        .pipe(
          cleanCss({
            // 压缩css
            compatibility: 'ie8',
            // 保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
            keepSpecialComments: '*'
          })
        )
        .pipe(rev()) // 文件名加MD5后缀
        .pipe(gulp.dest('./dist/style/')) // 输出目标文件到dist目录
        .pipe(rev.manifest()) // 生成一个rev-manifest.json
        .pipe(gulp.dest('./src/style/')); // 将 rev-manifest.json 保存到 src目录
    });
    
    // 替换目标html文件中的css版本文件名,js版本的文件名,html 压缩
    gulp.task('html', function(e) {
      return gulp
        .src(['./src/**/*.json', './src/**/*.html', '!./src/template/**']) // - 读取 rev-manifest.json 文件以及需要进行css名替换的文件
        .pipe(revCollector({ replaceReved: true })) // - 执行html文件内css文件名的替换和js文件名替换
        .pipe(
          htmlmin({
            removeComments: true, // 清除HTML注释
            collapseWhitespace: true, // 压缩HTML
            // collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
            removeEmptyAttributes: true, // 删除所有空格作属性值 <input id="" /> ==> <input />
            removeScriptTypeAttributes: true, // 删除<script>的type="text/javascript"
            removeStyleLinkTypeAttributes: true, // 删除<style>和<link>的type="text/css"
            minifyJS: true, // 压缩页面JS
            minifyCSS: true // 压缩页面CSS
          })
        )
        .pipe(gulp.dest('./dist/')); // - 替换后的文件输出的目录
    });
    
    // 图片压缩
    gulp.task('imgmin', function(e) {
      return gulp
        .src('./src/asset/**/*.{png,jpg,gif,ico}')
        .pipe(
          imgagemin({
            optimizationLevel: 5, // 类型:Number  默认:3  取值范围:0-7(优化等级)
            progressive: true, // 类型:Boolean 默认:false 无损压缩jpg图片
            interlaced: true,
            // 类型:Boolean 默认:false 隔行扫描gif进行渲染
            multipass: true // 类型:Boolean
            // 默认:false 多次优化svg直到完全优化
          })
        )
        .pipe(gulp.dest('./dist/asset'));
    });
    
    // js 压缩添加版本
    gulp.task('js', function(e) {
      return gulp
        .src(['./src/**/*.js', '!./src/lib/**'])
        .pipe(eslint())
        .pipe(
          eslint.results(results => {
            // Called once for all ESLint results.
            console.log(`JS总校验文件: ${results.length}`);
            console.log(`JS警告个数:: ${results.warningCount}`);
            console.log(`JS错误个数: ${results.errorCount}`);
          })
        )
        .pipe(eslint.format())
        .pipe(eslint.failAfterError())
        .pipe(babel({ presets: ['env'] }))
        .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest('./dist'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('./src/js/'));
    });
    
    // 给requirejs引用的文件修改版本号的路径
    gulp.task('revjs', function() {
      return gulp
        .src('./dist/*.js')
        .pipe(
          configRevReplace({
            manifest: gulp.src('./src/js/rev-manifest.json')
          })
        )
        .pipe(uglify())
        .pipe(gulp.dest('dist/'));
    });
    
    // 打包要复制的路径2
    var copyPathArr = ['./src/lib/**/*', './src/asset/**/*', './src/*.ico'];
    // 拷贝gulp文件
    gulp.task('copy', function(e) {
      return gulp.src(copyPathArr, { base: './src' }).pipe(gulp.dest('./dist/'));
    });
    // 清理dist目录下的历史文件
    gulp.task('cleanDist', function() {
      gulp
        .src(['dist/style/**', 'dist/js/**', 'dist/*.js'], { read: false })
        .pipe(clean());
    });
    gulp.task('dist', [], function() {
      runSequence(
        'cleanDist',
        'tpl',
        'style',
        'js',
        'revjs',
        'html',
        'copy',
        'imgmin'
      );
    });
    
    gulp.task('tpl', function() {
      // 拿到所有的路径
      let basePath = path.join(__dirname, 'src/template');
      let files = fs.readdirSync(basePath);
      files.forEach((val, index) => {
        let dirPath = path.join(basePath, val);
        let stat = fs.statSync(dirPath);
        if (!stat.isDirectory()) {
          return;
        }
        var fileter = 'src/template/' + val + '/**/*.html';
        console.log(fileter);
        gulp
          .src('src/template/' + val + '/**/*.html')
          .pipe(
            tmodjs({
              templateBase: 'src/template/' + val,
              runtime: val + '.js',
              compress: false
            })
          )
          // 自动生成的模板文件,进行babel转换,会报错,此转换插件已经停更,所以间接改这个bug
          // 参考bug:https://github.com/aui/tmodjs/issues/112 主要是this  →  window
          .pipe(replace('var String = this.String;', 'var String = window.String;'))
          .pipe(gulp.dest('src/js/tmpl/'));
      });
    });
    
    // ============= 开发样式处理
    gulp.task('style:dev', function(e) {
      var sassFilter = filter(['**/*.scss'], { restore: true });
      return gulp
        .src(['./src/style/**/*.{scss,css}', '!./src/style/main.css']) // 读取sass文件
        .pipe(sourcemaps.init())
        .pipe(sassFilter)
        .pipe(sass()) // 编译sass
        .pipe(sassFilter.restore)
        .pipe(concat('main.css'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./src/style/'));
    });
    
    // 开发监控sass文件变化编译sass到css文件 可以增加es6的编译,jslint
    gulp.task('dev', ['open'], function() {
      gulp.watch('src/style/**', ['style:dev']);
      gulp.watch('src/template/**', ['tpl']);
    });
    
    // 配置测试服务器
    gulp.task('devServer', function() {
      connect.server({
        root: ['./src'], // 网站根目录
        port: 38900, // 端口
        livereload: true,
        middleware: function(connect, opt) {
          return [
            modRewrite([
              // 设置代理
              '^/api/(.*)$ http://192.168.0.102:8080/mockjsdata/1/api/$1 [P]'
            ])
          ];
        }
      });
    });
    
    // 启动浏览器打开地址
    gulp.task('open', ['devServer'], function() {
      gulp.src(__filename).pipe(open({ uri: 'http://localhost:38900/index.html' }));
    });
  • 相关阅读:
    C# 反射数据库数据过程中值类型存在DBNull的处理方法 == System.DBNull.Value
    Git 未能顺利结束 (退出码 128)解决办法 git常用命令流程图
    IDEA之The directory xxxxx is under Git, but is not registered in the Settings.
    git push提交成功后如何撤销回退 我是手动修改再提交一次 。。或者IDEA有代码修改历史记录功能 进行回退
    IDEA,发现Project文件目录不见了,只剩External Libraries的原因
    分布式事务 seata
    idea设置类,方法模板 阿里检测
    随笔
    初学一点点空间分解和有理标准型
    Vue2+Cesium1.9+热力图开发笔记
  • 原文地址:https://www.cnblogs.com/NightTiger/p/10288069.html
Copyright © 2020-2023  润新知