js:自动化构建 gulp

本文介绍了Gulp的任务管理机制,包括异步任务、公共与私有任务、series和parallel方法的使用。强调了如何处理文件流,以及src()和dest()方法的功能。还提到了Gulp插件的使用,如gulp-sass、gulp-babel和gulp-imagemin等,以及文件监控和清理任务。同时,文章涵盖了错误处理和自动化构建的实例。

中文官网 英文官网

入门指南: 链接

  1. 每个 gulp 任务(task)都是一个异步的 JavaScript 函数,此函数是一个可以接收 callback 作为参数的函数,或者是一个返回 stream、promise、event emitter、child process 或 observable (后面会详细讲解) 类型值的函数
  2. 任务(tasks)可以是 public(公开) 或 private(私有) 类型的。(从 gulpfile 中被导出(export),可以通过 gulp 命令直接调用)
  3. Gulp 提供了两个强大的组合方法如果需要让任务(task)按顺序执行,请使用 series()对于希望以最大并发来运行的任务(tasks),可以使用 parallel() 方法;)
  4. series() 和 parallel() 可以互相嵌套至任意深度
  5. 当从任务(task)中返回 stream、promise、event emitter、child process 或 observable 时,成功或错误值将通知 gulp 是否继续执行或结束。如果任务(task)出错,gulp 将立即结束执行并显示该错误。
  6. gulp 暴露了 src() 和 dest() 方法用于处理计算机上存放的文件。
    (src() 接受 glob 参数,并从文件系统中读取文件然后生成一个 Node 流(stream))
    (流(stream)所提供的主要的 API 是 .pipe() 方法,用于连接转换流(Transform streams)或可写流(Writable streams)。)
    (dest() 接受一个输出目录作为参数,并且它还会产生一个 Node 流(stream),通常作为终止流(terminator stream
  7. src() 也可以放在管道(pipeline)的中间,以根据给定的 glob 向流(stream)中添加文件
    dest()可用于在同一个管道(pipeline)中创建未压缩(unminified)和已压缩(minified)的文件。
  8. glob 是由普通字符和/或通配字符组成的字符串(在 glob 中,分隔符永远是 / 字符😉(避免使用 Node 的 path 类方法来创建 glob,例如 path.join 还要避免使用 __dirname 和 __filename process.cwd()) (一个星号*匹配一个字符串片段中匹配任意数量的字符;两个星号在多个字符串片段中匹配任意数量的字符,包括零个匹配**)
    由于 glob 匹配时是按照每个 glob 在数组中的位置依次进行匹配操作的,所以 glob 数组中的取反(negative)glob 必须跟在一个非取反(non-negative)的 glob 后面
  9. Gulp 插件通常是使用 .pipe() 方法并放在 src() 和 dest() 之间 gulp插件链接
    他们可以更改经过流(stream)的每个文件的文件名、元数据或文件内容。
    插件应当总是用来转换文件的。其他操作都应该使用(非插件的) Node 模块或库来实现。
    因为插件的操作不应该针对特定文件类型,因此你可能需要使用像 gulp-if 之类的插件来完成转换某些文件的操作。
  10. gulp api 中的 watch() 方法利用文件系统的监控程序(file system watcher)将 globs 与 任务(task) 进行关联。它对匹配 glob 的文件进行监控,如果有文件被修改了就执行关联的任务(task)。如果被执行的任务(task)没有触发 异步完成 信号
    调用 watch() 之后,关联的任务(task)是不会被立即执行的,而是要等到第一次文件修之后才执行。
    watch() 方法能够保证当前执行的任务(task)不会再次并发执行。当文件监控程序关联的任务(task)正在运行时又有文件被修改了,那么所关联任务的这次新的执行将被放到执行队列中等待
    **文件更改之后,只有经过 200 毫秒的延迟之后,文件监控程序所关联的任务(task)才会被执行。**这是为了避免在同使更改许多文件时(例如查找和替换操作)过早启动任务(taks)的执行。

gulp插件 链接

gulp-sass 转换sass样式
选项 outputStyle 样式完全展开
gulp-babel 转换js
选项 presets 需要传递否则转换没效果 [’@babel/preset-env’]
gulp-swig 编译html模板
gulp-imagemin 处理图片
gulp-load-plugins 统一方式导入所有插件
gulp-useref 对html引入的样式和脚本机型压缩并引入
gulp-htmlmin 压缩html (collapseWhitespace压缩空白和换行符 minifyCSS压缩引入的css minifyJS 压缩引入的js)
gulp-uglify 压缩js
gulp-clean-css 压缩css
gulp-if 对不同的文件进行判断分别处理

非gulp插件

del 文件清除
browser-sync 开发服务器(server port等选项)

报错

// 按照要求使用sass

gulp-sass no longer has a default Sass compiler; please set one yourself.
Both the "sass" and "node-sass" packages are permitted.
For example, in your gulpfile:

  const sass = require('gulp-sass')(require('sass'));

报错-安装gulp-imagemin报错

Must use import to load ES Module:

重新排查发现了新的报错

 Command failed: C:\\Windows\\system32\\cmd.exe /s /c \"./configure --with-

链接不到这个网址
// 在hosts增加
199.232.96.133 raw.githubusercontent.com
影射 或者更npm镜像更改为npm官方镜像 (都不行,是因为gulp-imagemin这个模块下载不了
最后下载7.1这个版本成功了,记得也要配置hosts 185.199.108.133 raw.githubusercontent.com

getaddrinfo ENOENT raw.githubusercontent.com


## [api](https://www.gulpjs.com.cn/docs/api/concepts/)


src选项
 base: ''  // 指定基准路径,这样会保留转换后的路径
watch选项



 
完整代码

```javascript

// gulpfile.js

const { series, parallel, src, dest, watch } = require('gulp');

const babel = require('gulp-babel');

const uglify = require('gulp-uglify');

const rename = require('gulp-rename');

const gulpif = require('gulp-if');

const sass = require('gulp-sass')(require('sass'));
const swig = require('gulp-swig')

const imagemin = require('gulp-imagemin')

const gulpLoadPlugins = require('gulp-load-plugins');
const plugins = gulpLoadPlugins();

const del = require('del')

var browserSync = require('browser-sync').create();

const useref  = require('gulp-useref')

const htmlmin = require('gulp-htmlmin');
// const uglify  = require('gulp-uglify')
const cleanCss  = require('gulp-clean-css')

// var gulpif = require('gulp-if');

// const babel = require('gulp-babel')

function defaultTask (cb) {
  // place code for your default task here
  console.log('first')
  cb();
}

function clean (cb) {
  // body omitted
  cb();
}

function build (cb) {
  // body omitted
  console.log('build')
  cb();
}

function transpile (cb) {
  // body omitted
  console.log('transpile')
  cb();
}

function bundle (cb) {
  // body omitted
  console.log('bundle')
  cb();
}
function javascript (cb) {
  // body omitted
  cb();
}

function css (cb) {
  console.log('css')
  // body omitted
  cb();
}

function promiseTask () {
  console.log('promiseTask')
  return Promise.resolve('the value is ignored');
}

//exports.default = function() {
//  return src('src/*.js')
// .pipe(babel())
//.pipe(src('vendor/*.js'))
//    .pipe(uglify())
//    .pipe(rename({ extname: '.min.js' }))
//    .pipe(dest('output/'));
//}

function isJavaScript (file) {
  // 判断文件的扩展名是否是 '.js'
  return file.extname === '.js';
}

//exports.default = function() {
//  // 在同一个管道(pipeline)上处理 JavaScript 和 CSS 文件
//  return src(['src/*.js', 'src/*.css'])
//    // 只对 JavaScript 文件应用 gulp-uglify 插件
//    .pipe(gulpif(isJavaScript, uglify()))
//    .pipe(dest('output/'));
//}

// 可以只关联一个任务
// watch('src/*.css', css);

const styles = () => {
  return src('src/assets/styles/*.scss', { base: 'src' }).pipe(sass()).pipe(dest('temp'))
}

const scripts = () => {
  return src('src/assets/scripts/*.js', { base: 'src' }).pipe(babel({ presets: ['@babel/preset-env'] })).pipe(dest('temp'))
}

let data = {
  title: 'gulp'
}

const html = () => {
  return src('src/**/*.html', { base: 'src' }).pipe(plugins.swig(data)).pipe(dest('temp'))
}

const extra = () => {
  return src('public/**', { base: 'public' }).pipe(dest('dist'))
}

const cleanFn = () => {
  return del(['dist', 'temp'])
}

const userefFn = () => {
  
  return src('temp/*.html', { base: 'temp' })
  .pipe(useref({searchPath: ['dist', 'node_modules']})
  .pipe(gulpif(/\.js$/, uglify()))
  .pipe(gulpif(/\.css$/, cleanCss()))
  .pipe(gulpif(/\.html$/, htmlmin({collapseWhitespace: true})))
  .pipe(dest('dist')))
}

const image = () => {
  return src('src/assets/images/**', { base: 'src' }).pipe(imagemin()).pipe(dest('dist'))
}
const fonts = () => {
  return src('src/assets/fonts/**', { base: 'src' }).pipe(imagemin()).pipe(dest('dist'))
}
// parallel

const server = () => {
  watch(['src/assets/styles/**', ], styles);
  watch(['src/assets/scripts/**'], scripts);
  watch(['src/*.html'], html);
  // watch(['src/assets/styles/**', 'src/assets/scripts/**', 'src/*.html'], compile);
  watch(['src/assets/fonts/**', 'src/assets/images/**', 'public/**'], browserSync.reload());

  return browserSync.init({
    server: {
      baseDir: ["temp", "public", "src"]
    },
    port: 8088,
    files: ['dist/**']
    // open: false,
  });
}

// 编译
const compile = parallel(styles, scripts, html)
exports.compile = compile


// 打包
// exports.build = series(cleanFn, compile, image, fonts, extra)
const buildFn = series(cleanFn, parallel(series(compile, userefFn), image, fonts, extra))

const develop = series(compile, server)

// 将外部使用到的任务暴露出去
exports.clean = cleanFn
exports.develop = develop
exports.build = buildFn

//exports.default = promiseTask;

//exports.build = parallel(javascript, css);

// exports.build = series(transpile, bundle);

// exports.build = build;

// exports.default = defaultTask

建议忽略这个文件
在这里插入图片描述
如需简单的自动化构建可以将命令放在scripts中
/package.json

  "scripts": {
    "serve": "gulp server",
    "dev": "gulp develop",
    "clean": "gulp clean"
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值