• Gulp(1): 打包压缩小程序 小程序瘦身


    在当今前端技术愈加成熟的环境下,小程序的压缩瘦身,相对变得容易多了。
    webpack 中一切皆模块,基于其丰富的自由配置,会从入口处对所有依赖进行整合并重新分配,本是一个极大的优势,但在小程序中却也是一个弊端。
    相比较而言,gulp 任务规划,功能明确,运行可控,对于小程序这样的对文件索引更严格的模式下,更显得得心应手。

    1. 安装 gulp

    选择一个目录,安装 gulp

    npm i -D gulp
    

    创建配置文件 gulpfile.js,输入:

    
    function defaultTask(cb) {
      // task
      console.log('hello gulp')
      cb();
    }
    exports.default = defaultTask
    

    在 package.json 中添加脚本命令 "dev": "gulp" , 然后命令行执行 npm run dev,就会执行默认任务,并打印 ' hello gulp '。
    创建文件夹 demo,并在其中创建 test.js、common.css 等测试文件,填充基本内容。为后续操作做准备。

    2. 基本配置

    可以说,gulp是面向任务的工具,所有功能都由一个个任务组合而成,每个任务都是一个函数。
    处理小程序中的文件,最主要的api 是 src()读取文件流、 dest()输出文件流、 pipe()处理数据流。
    如下,先安装 gulp-babelgulp-uglify两个插件用于转义es6 并压缩js。

    npm i -D gulp-babel @babel/core @babel/preset-env gulp-uglify
    

    gulpfile.js 中改为:

    
    const { src, dest } = require('gulp');
    const babel = require('gulp-babel');
    const uglify = require('gulp-uglify');
    
    exports.default = function() {
      return src('demo/*.js')
        .pipe(babel())
        .pipe(uglify())
        .pipe(dest('dist/'));
    }
    

    src()dest()都是接受 glob 参数,传入地址目录,此处不再展开。
    值得注意的是,gulp 不支持同步任务,意味着,所有的任务必须使用 callback 或 async函数,或返回 stream、promise、event emitter、child process、observable。若在使用中出现 "Did you forget to signal async completion?" 警告,表示未使用前面提到的返回方式。
    执行 npm run dev即可看到,同级目录内出现 dist 文件夹,内部包含前面提到的测试文件的压缩版js。
    随后引入 gulp-clean-css用于压缩 wxss 文件,gulp-htmlmin用于压缩 wxml,同时需要 gulp-iflazypipe 进行条件编译,对js、wxss、wxml 文件进行分别处理。

    npm i -D gulp-clean-css gulp-htmlmin gulp-if lazypipe
    

    gulp-if 第一个参数为判断条件,第二参数为判断为 true 时,执行的任务,第三参数为判断为 false 时,执行的任务,可不传。
    对js的处理需要两步操作,首先进行 babel转换,然后 uglify压缩,在这里就需要用 lazypipe 把这两个操作转化为操作链。
    注意,lazypipe 实例在调用 pipe() 时,pipe 中函数的参数,需紧跟 pipe 中函数的后面:
    lazypipe().pipe(fn[, arg1[, arg2[, ...]]])

    Vinyl 是描述文件的元数据对象,同样存在于文件流中,可以使用 Vinyl api 获取文件流的文件类型,如:file.extname = '.js';

    
    const { src, dest} = require('gulp');
    const gulpif = require('gulp-if');
    const lazypipe = require('lazypipe');
    const babel = require('gulp-babel');
    const uglify = require('gulp-uglify');
    const cleanCss = require('gulp-clean-css');
    const htmlmin = require('gulp-htmlmin');
    
    const isJS = (file) => file.extname === '.js';
    const isCSS = (file) => file.extname === '.wxss' || file.extname === '.css';
    const isWXML = (file) => file.extname === '.wxml';
    
    const jsChannel = lazypipe()
      .pipe( babel, { presets: ['@babel/env'] } )
      .pipe( uglify, {
        // 压缩配置
        compress: {
          drop_console: true,
        },
        // 输出配置
        output: {
          comments: false,    // 移除注释
        },
        toplevel: false,    // 混淆最高作用域中的变量和函数名
      })
    
    async function fileHandle() {
      src('demo/**/*', {
        allowEmpty: true
      })
      // 分别处理 js、wxss
      .pipe(gulpif( isJS, jsChannel()))
      .pipe(gulpif( isCSS, cleanCss()))
      // 取消对 wxml 的处理,<input></input>等与 html 中存在冲突
      // .pipe(gulpif( isWXML, htmlmin({
      //   caseSensitive: true,    // 大小写敏感
      //   removeComments: true,   // 删除HTML注释
      //   keepClosingSlash: true, // 单标签上保留斜线
      // })))
      .pipe(dest('dist/'))
    }
    exports.default = fileHandle
    

    引入 del 库,
    npm i -D del
    在编译前,清空输出目录,这里涉及到顺序执行,所以还需使用 gulp.series组合任务。

    const { series} = require('gulp');
    const del = require('del');
    
    // 清理
    async function clean(){
      await del(output);
    }
    
    exports.clean = clean
    exports.default = series( clean, fileHandle)
    

    另外,把输入输出目录 提取出来,统一配置
    最后,gulpfile.js 源码如下:

    
    const { src, dest, series} = require('gulp');
    const gulpif = require('gulp-if');
    const lazypipe = require('lazypipe');
    const babel = require('gulp-babel');
    const uglify = require('gulp-uglify');
    const del = require('del');
    const cleanCss = require('gulp-clean-css');
    const htmlmin = require('gulp-htmlmin');
    
    // const entry = '../wx'    // 小程序地址
    const entry = './demo'      // 示例地址
    const output = './dist'     // 输出目录
    
    
    const isJS = (file) => file.extname === '.js';
    const isCSS = (file) => file.extname === '.wxss' || file.extname === '.css';
    const isWXML = (file) => file.extname === '.wxml';
    
    const jsChannel = lazypipe()
      .pipe( babel, { presets: ['@babel/env'] } )
      .pipe( uglify,  )
    
    // 清理
    async function clean(){
      await del(output);
    }
    async function fileHandle() {
      src([ 
        `${entry}/**/*`,
        `!${entry}/**/.*`,
        `!${entry}/node_modules/*`,
        `!${entry}/**/*.md`,
      ], {
        allowEmpty: true
      })
      // 分别处理 js、wxss、wxml
      .pipe(gulpif( isJS, jsChannel()))
      .pipe(gulpif( isCSS, cleanCss()))
      // 取消对 wxml 的处理,<input></input>等与 html 中存在冲突
      // .pipe(gulpif( isWXML, htmlmin({
      //   caseSensitive: true,    //  大小写敏感
      //   removeComments: true,   // 	删除HTML注释
      //   keepClosingSlash: true, // 单标签上保留斜线
      // })))
      .pipe(dest(output))
    }
    
    exports.clean = clean
    exports.default = series( clean, fileHandle)
    

    package.json

    {
      "devDependencies": {
        "@babel/core": "^7.11.1",
        "@babel/preset-env": "^7.11.0",
        "del": "^5.1.0",
        "gulp": "^4.0.2",
        "gulp-babel": "^8.0.0",
        "gulp-clean-css": "^4.3.0",
        "gulp-htmlmin": "^5.0.1",
        "gulp-if": "^3.0.0",
        "gulp-uglify": "^3.0.2",
        "lazypipe": "^1.0.2"
      },
      "scripts": {
        "dev": "gulp",
        "clean": "gulp clean"
      }
    }
    
  • 相关阅读:
    TFIDF<细读>
    数据挖掘工程师的面试问题与答题思路【转】
    CTR常见规则摘录
    分类中数据不平衡问题的解决经验[转载]
    机器学习积累【2】
    机器学习-常见问题积累【1】
    数据的归一化和标准化
    数据挖掘之特征选择
    jupyter-notebook快捷键
    python基础学习记录一
  • 原文地址:https://www.cnblogs.com/_error/p/13495394.html
Copyright © 2020-2023  润新知