首页 > 其他分享 >构建工具gulp浅谈

构建工具gulp浅谈

时间:2023-09-14 18:46:21浏览次数:42  
标签:src const 浅谈 文件 require js gulp 构建

gulp.js - 基于流(stream)的自动化构建工具

引言:

​ js作为一门脚本语言,在较早时候,只能通过<script>标签插进html去运行,单个的js文件离开了html就没有了意义。

​ 如果一个网站功能很多,要按照功能划分写十几个js文件,那么就要插入十几个<script src="">去引那些js文件,还需要注意顺序和位置,一方面难以维护,另一方面增加了网页加载时的请求数量。

​ 有了node之后,单独的js文件离开了html以后也可以在终端run起来,这样前端也可以在命令行里进行编程了,再然后,模块化标准实施之后,js有了引入和导出的概念,这带来了革命性的变化,不用再像之前提到的那样在html里写大量的<script src="">去运行js,只需要一个作为入口的script标签,另外的js文件做为模块导出并导入到这个入口js中。

​ 但是,问题在于,一旦js文件以<script src="">的形式插入html,那么require、export、import之类的模块语法就会报错,因为浏览器不支持模块化。模块语法是建立在node的环境下才有的。像webpack、rollup、gulp等打包工具的一个作用就是插入script标签的同时还可以让开发者在js文件之间使用require、export、import这些语法进行模块化开发,并且能够智能的将这些js模块合并压缩成一个紧实的js文件,同时可以对代码压缩和优化使其在生产环境中能够运行的更高效。当然,现代的打包工具已经不局限在将多个 js 文件打包成一个 js,而是成为了开发流程的一部分,保证开发能够使用较为高级的语法、处理兼容问题、静态资源优化等。

gulp是什么

  1. 自动化构建工具,把项目工作抽象成自动化任务用 gulp 构建自动化工作流,处理项目中的资源,基于(stream)流式操作。开发人员要写一系列的任务(task),加载组件、一步一步地处理 stream。gulp 更偏向将开发流程中让人痛苦或耗时的任务自动化,从而减少所浪费的时间。
  2. 出现在社区模块化时代,也就是AMD、CMD、UMD等模块化规范出现并且nodejs现世后的时期,因为其依赖于node的文件读写机制。
  3. 这是一个官方的示例
const { src, dest, parallel } = require('gulp');
const pug = require('gulp-pug');
const less = require('gulp-less');
const minifyCSS = require('gulp-csso');
const concat = require('gulp-concat');

function html() {
  return src('client/templates/*.pug')
    .pipe(pug())
    .pipe(dest('build/html'))
}

function css() {
  return src('client/templates/*.less')
    .pipe(less())
    .pipe(minifyCSS())
    .pipe(dest('build/css'))
}

function js() {
  return src('client/javascript/*.js', { sourcemaps: true })
    .pipe(concat('app.min.js'))
    .pipe(dest('build/js', { sourcemaps: true }))
}

exports.js = js;
exports.css = css;
exports.html = html;
exports.default = parallel(html, css, js);       

gulp核心api

Api 描述 参数 返回值
src ( ) 创建一个流,用于从文件系统读取 Vinyl 对象。 src(globs, [options]) 返回一个可以在管道的开始或中间使用的流,用于根据给定的 globs 添加文件。
dest ( ) 创建一个用于将 Vinyl 对象写入到文件系统的流。输出数据流到目标路径。 dest(directory, [options]) 返回一个可以在管道的中间或末尾使用的流,用于在文件系统上创建文件。
symlink ( ) 创建一个流(stream),用于连接 Vinyl 对象到文件系统。软链接。 symlink(directory, [options]) 每当 Vinyl 对象通过流被传递时,它将内容和其他细节写到给定目录下的文件系统。如果 Vinyl 对象具有 symlink 属性,将创建符号链接(symbolic link)而不是写入内容。创建文件后,将更新其元数据以匹配 Vinyl 对象。在文件系统上创建文件时,Vinyl 对象将被修改。
lastRun ( ) 检索在当前运行进程中成功完成任务的最后一次时间。当与 src() 组合时,通过跳过自上次成功完成任务以来没有更 改的文件,使增量构建能够加快执行时间。 lastRun(task, [precision]) 返回一个时间戳(以毫秒为单位),表示任务的最后完成时间。如果任务尚未运行或已经失败,则返回 undefined。为了避免缓存无效状态(invalid state),因此,如果任务出错,则返回值为 undefined
series ( ) 将任务函数和/或组合操作组合成更大的操作,这些操作将按顺序依次执行。嵌套深度没有强制限制。 series(...tasks) 返回一个组合操作,它将注册为任务或嵌套在其他 series 和/或 parallel 组合中。当执行组合操作时,所有任务将按顺序运行。如果一个任务中发生错误,则不会运行后续任务。
parallel ( ) 将任务功能和/或组合操作组合成同时执行的较大操作。嵌套组合的深度没有强制限制。 parallel(...tasks) 返回一个组合操作,它将注册为任务或嵌套在其他 series 和/或 parallel 组合中。当执行组合操作时,所有任务将以最大并发性运行。如果一个任务发生错误,其他任务可能不确定地完成,也可能不完成。
watch ( ) 监听 globs 并在发生更改时运行任务。任务与任务系统的其余部分被统一处理。 watch(globs, [options], [task]) chokidar的一个实例,用于对监听设置进行细粒度控制。
registry ( ) 允许将自定义的注册表插入到任务系统中,以期提供共享任务或增强功能。 registry([registryInstance]) 如果传递了 registryInstance,则不会返回任何内容。如果没有传递参数,则返回当前注册表实例。

gulp核心配置文件gulpfile

  1. 命名:gulpfile.js文件或是文件夹。对于typescript,使用文件重命名为gulpfile.ts并安装ts-node、typescript、@babel/core模块。对于babel,重命名为gulpfile.babel.js并安装@babel/core、@babel/register模块。

  2. gulpfile分割:每个任务(task)可以被分割为独立的文件,然后导入(import)到 gulpfile 文件中并组合。目录中需要包含一个名为index.js的文件,其它文件按照模块规范,导出符合task规范的函数在index.js文件中导入即可。当使用typescript时,文件夹名称需要改为gulpfile.ts,同时目录下的文件改为.ts结尾。

值得注意的是,只有在index.js文件中通过exports.[taskName]的形式导出的函数才能注册到公开的task树中。通过exports.default导出的为默认执行。

gulp核心机制

  1. 示例图:
  1. task:每个 gulp 任务(task)都是一个异步的 JavaScript 函数,此函数是一个可以接收 callback 作为参数的函数,或者是一个返回 stream、promise、event emitter、child process 或 observable 类型值的函数,必须保证return以上类型值或是执行callback(),否则会告警Did you forget to signal async completion?

    task需要是具名函数,因为函数名称就是task的名称,不过匿名函数也不会报错,但是会造成误解。

  2. vinyl

    vinyl: 虚拟的文件格式,描述文件的元数据对象,vinyl对象可以在插件中流转,也可以被vinyl适配器所使用,例如dest()函数。每一个Vinyl实例代表一个独立的文件、目录或者symlink符号连接。实际项目中,除了需要一个简洁的方式去描述一个文件之外,我们还需要访问这些文件,所以vinyl适配器对外暴露接口src()和dest(),它们都最终返回一个流(stream),src接口生产一个Vinyl 对象,dest接口消费一个Vinyl 对象。

  3. stream

    gulp在流转vinyl对象时是基于stream方式,使其在一次数据流转过程就可以进行多次的处理操作。

    stream流的工作方式:

    流(stream)是node.js处理流式数据的抽象接口,流是可读可写的,所有的流都是EventEmitter实例。Writable - 可写入数据的流(例如 fs.createWriteStream())。
    Readable - 可读取数据的流(例如 fs.createReadStream())。
    Duplex - 可读又可写的流(例如 net.Socket)。
    Transform - 在读写过程中可以修改或转换数据的 Duplex 流。

例子:从字符串创建文件

function test2 (cb) {
  var src = require('stream').Readable({ objectMode: true })
  src._read = function () {
    this.push(new Vinyl({
      cwd: "/",
      base: "/",
      path: '/file.js',
      contents: Buffer.from('var x = 123', 'utf-8')
    }))
    this.push(null)
  }

  src.pipe(dest('build/'))

  cb()
}

gulp内部,vinyl对象输出流通过through2包装为Transform流进行流转,所以使用src接口得到的是一个Transform流。

常用插件

  • gulp-load-plugins:自动加载 package.json 中的 gulp 插件
  • gulp-rename: 重命名
  • gulp-uglify:文件压缩
  • gulp-concat:文件合并
  • gulp-less:编译 less
  • gulp-sass:编译 sass
  • gulp-clean-css:压缩 CSS 文件
  • gulp-htmlmin:压缩 HTML 文件
  • gulp-babel: 使用 babel 编译 JS 文件
  • gulp-eslint:eslint校验
  • gulp-imagemin:压缩 jpg、png、gif 等图片。注意版本兼容。
  • gulp-livereload:当代码变化时,它可以帮我们自动刷新页面

gulp的适用场景

  1. 多页面,静态资源密集操作型场景
  2. 轻量化的任务,单独打包css文件,轻量而且逻辑清晰。
  3. 流程化,一些特殊的任务,将图片发布至图床,下载某些特定文件处理后存放至本地等

gulp中使用rollup

const { rollup } = require('rollup');
const typescript = require('rollup-plugin-typescript2');
const babel = require ('gulp-babel');
const { src, dest } = require('gulp')
const uglify = require('gulp-uglify')

// Rollup 提供了基于 promise 的 API,在 `async` 任务(task)中工作的很好
module.exports = async function rol() {
  const bundle = await rollup({
    input: 'src/vendor/main.ts',
    plugins: [
      typescript({
        check: false,
        clean: true,
        tsconfigOverride: { compilerOptions: { removeComments: true } }
      })
    ]
  });

  await bundle.write({
    file: 'output/bundle.js',
    format: 'umd'
  });

  src ('output/bundle.js')
  .pipe (
    babel ({
      presets: ['@babel/env'],
    })
  )
  .pipe (uglify())
  .pipe (rrename({ extname: '.min.js' }))
  .pipe (dest ('output/'))
}

gulp中使用webpack

const { src, dest } = require('gulp');
const gulpWebpack = require('webpack-stream');
const webpack = require('webpack');

module.exports = function testWebpack (cb) {
  return src('src/entry.js')
    .pipe(gulpWebpack({
      watch: true,
      mode: 'development',
    	...[options]
    }, webpack))
    .pipe(dest('wp_dist/'));
}

结尾

gulp现在使用的场景已经很少了,可能更多的是做开发流程的规范(也很少了),不再是主力开发打包工具,不太推荐使用啦,毕竟插件都好久没有维护了。尽量webpack能解决的就使用webpack解决,实在解决不了可以尝试使用,因为gulp可以以一种侵入式不大的方式使用。

标签:src,const,浅谈,文件,require,js,gulp,构建
From: https://www.cnblogs.com/szq233/p/17703153.html

相关文章

  • 可视化应用构建之推单
    一, 引言要说明什么是推单之前,需要先说明什么单据。生活中常见到的,在购物APP中可以看到订单,收到的物品有包装清单;还有发票,收据等都可以理解为单据。那么推单是什么含义呢? 看字面意思好像是从一张单据生成另一张单据,这么理解不全对,实际上应用构建中的推单是推数据。比如有两张单据;......
  • 可视化应用构建之推单
    一, 引言要说明什么是推单之前,需要先说明什么单据。生活中常见到的,在购物APP中可以看到订单,收到的物品有包装清单;还有发票,收据等都可以理解为单据。那么推单是什么含义呢? 看字面意思好像是从一张单据生成另一张单据,这么理解不全对,实际上应用构建中的推单是推数据。比如有两张......
  • buildroot 构建根文件系统(8)添加网络时间同步
    一、开发背景构建最小系统后成功运行后,时间都是从初始化时间开始计算,形如:ThuJan 109:57:55UTC1970二、开发需求开机联网后自动从网络中获取最新的时间,同步到系统中三、开发环境LinuxUbuntu4.15.0-65-generic+buildroot-2023.02.3+i.mx6d(cortex-A9)......
  • 在本地硬盘中构建GIT本地远程仓库
    首先创建一个本地仓库创建文件夹mkdir/temp/local_repository初始化仓库cd/temp/local_repositorygitinit初始化仓库cd/temp/local_repositorygitinit建立远程托管仓库local_repository.git是一个文件夹,命名没有限制,但结尾要以.git为准cd/tempgitcl......
  • Spring Boot构建web项目01
    配置:破解版IDEA2019.3.3Maven--3.6.3java--1.8(8)jdk--8  打开IDEA,new一个project,选择SpringInitializr 改写maven管理和java版本8 选择web项目    添加指定父级工程信息和java版本依赖<modelVersion>4.0.0</modelVersion><parent><gro......
  • 学成在线网站——banner部分的构建
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>学成在线首页</title>&......
  • 网络分层:构建信息交流的桥梁
    引言本系列即将结束,最后一章将仔细讨论网络系统,这是面试中经常被问及的一个知识点,也是工作中常遇到的一个系统知识点。那么为什么我们需要网络系统呢?我们之前提到过,进程间通信有许多方法,其中一种是通过套接字(socket)进行跨网络通信。这意味着我们不再仅限于内部系统调用,而是需要与......
  • C与CPP常见编译工具链与构建系统简介
    笔者最近在研究CEF的CMake工程,心血来潮想要对各种编译工具链以及构建系统做一个简单的总结,于是就有了本文。本文不会讲解任何关于C/C++语言方面的内容,主要C/C++的编译出发,介绍各种编译工具链与构建系统的关系。此外,由于笔者水平有限,无法从非常专业的角度剖析C/C++的语言特性与编译......
  • 剑指 Offer 66. 构建乘积数组
    题目链接:剑指Offer66.构建乘积数组题目描述:**给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B[i]的值是数组A中除了下标i以外的元素的积,**即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。解法思路:代码:funcconstructArr(a[......
  • 基础设施SIG月度动态:「龙蜥大讲堂」基础设施系列专题分享完美收官,容器镜像构建 2.0 版
    基础设施SIG(OpenAnolisInfraSIG)目标:负责OpenAnolis社区基础设施工程平台的建设,包括官网、Bugzilla、Maillist、ABS、ANAS、CI门禁以及社区DevOps相关的研发工程系统。01SIG整体进展1.龙蜥大讲堂-基础设施系列专题分享完美收官,8月邀请了多位SIG核心贡献者分享了包括......