gulp基础、demo实践


前言

“用自动化构建工具增强你的工作流程!”,如官网标语所说,gulp 是基于流(stream)的自动化构建工具。


一、gulp的基本知识

首先:
1.需要运行一下yarn init -y 初始化一下package.json文件;
2. 装一下需要使用的依赖项:(可以自己选版本,但是新版可能用法会不一样)
yarn add gulp@4.0.2 gulp-clean-css@4.3.0 gulp-rename@2.0.0 --dev
3.然后新建如图文件结构:
在这里插入图片描述
注:src下的css随便写点样式(尽量多写点,写点注释之类的),
准备工作就做完了

1. 简单使用(写一个简单的任务)

(1)书写格式推荐
  • 不推荐写法:
//gulpfile.js文件
const gulp = require("gulp");
gulp.task("foo", done => {
    console.log("foo task working~");
    done()
})

注:调用gulp.task是旧版本,目前能正常运行,只是不推荐(怕以后不支持);

  • 推荐写法
//gulpfile.js文件
exports.foo = done => {
    console.log("foo task working~");
    done()
}

运行命令很简单,在控制台输入 yarn gulp foo;

注意:gulp4.0版本后就取消了同步处理机制,所有任务都是异步处理了,所以需要用一个回调函数来告诉gulp任务已结束,如图done(参数名不强制)这个函数回调,不会不调用done的结果就是:(但是输出语句是正常执行了)
在这里插入图片描述

(2)用法示例
//gulpfile.js文件
exports.foo = done => {
    console.log("foo task working~");
    done()
}

控制台输入 yarn gulp foo

//gulpfile.js文件
exports.default = done => {
    console.log("default task working~");
    done()
}

控制台输入 yarn gulp(可以省略任务名)

2. gulp组合任务

gulp提供了两个api:series(串行), parallel(并行),这两个api给我们提供了任务之间的组合操作;

//gulpfile.js文件
const { series, parallel } = require("gulp")
const task1 = done => {
    setTimeout(() => {
        console.log("task1 working~");
        done();
    }, 1000);
}

const task2 = done => {
    setTimeout(() => {
        console.log("task2 working~");
        done();
    }, 1000);
}

const task3 = done => {
    setTimeout(() => {
        console.log("task3 working~");
        done();
    }, 1000);
}
exports.foo = series(task1, task2, task3);
exports.bar = parallel(task1, task2, task3);

如上图,分别有task1,task2,task3三个setimeout的延迟任务,我们使用series, parallel组合成两个新任务foo、bar,foo任务是串行的方式执行这三个任务,bar任务是并行的执行这三个任务;
执行foo任务:yarn gulp foo
在这里插入图片描述
执行bar任务:yarn gulp bar
在这里插入图片描述

3. gulp异步任务处理方式

前面我们说过,gulp的任务都是异步任务(4.0版本以后去掉了同步任务),而异步任务是没办法告诉gulp该任务是否已结束,只能任务内部通过回调方法或者事件的方式通知gulp该任务已结束;
下面我们来介绍三种异步任务处理方式:

(1)调用回调的方式
//gulpfile.js文件
exports.callback = done => {
    console.log("callback task~");
    done();
}
//gulpfile.js文件
//跟node一样,错误优先的思想
exports.callback_err = done => {
    console.log("callback task~");
    done(new Error("task failed~"))
}
(2)promise / async await的方式
  • promise方式
//gulpfile.js文件
exports.promise = () => {
    console.log("promise task~");
    return Promise.resolve()//传值会被gulp忽略
}

exports.promise_err = () => {
    console.log("promise task~");
    return Promise.reject(new Error("task failed~"))
}
  • async await方式(需要node8以上)
//gulpfile.js文件
const timeout = (time) => {
    return new Promise(resolve => {
        setTimeout(resolve, time);
    })
}

exports.async = async () => {
    await timeout(2000);
    console.log("async task~");
}
(3)stream的方式(大部分都是这种处理方式,stream中会有end的事件,该事件会触发任务的结束)
//gulpfile.js文件
const fs = require("fs");
exports.stream = () => {
    const readStream = fs.createReadStream("package.json");
    const writeStream = fs.createWriteStream("temp.txt");
    readStream.pipe(writeStream);
    //触发读操作的end事件
    return readStream;
}

//还原end事件的结束操作
exports.stream_end = (done) => {
    const readStream = fs.createReadStream("package.json");
    const writeStream = fs.createWriteStream("temp.txt");
    readStream.pipe(writeStream);
    readStream.on("end", () => {
        done()
    })
}

4. gulp构建核心工作原理

构建任务具体要做的事情,也就是所谓的构建过程,原理如图:
在这里插入图片描述

具体请看代码:

//gulpfile.js文件
const fs = require("fs");
const { Transform } = require("stream")
exports.default = () => {
    const read = fs.createReadStream("src/normalize.css");
    const write = fs.createWriteStream("normalize.min.css");
    const transform = new Transform({
        transform: (chunk, encoding, callback) => {
            //核心转换过程实现
            //chunk =》读取流中读取到的内容(Buffer)
            const input = chunk.toString();
            const output = input.replace(/\s+/g, "").replace(/\/\*.+?\*\//g, "");
            callback(null, output);
        }
    })

    //把读出来文件流导入到写文件流
    read
        .pipe(transform)//转换
        .pipe(write)//写入
    return read;
}

5. gulp的api使用

//gulpfile.js文件
const { src, dest } = require("gulp");
const cleanCss = require("gulp-clean-css");
const rename = require("gulp-rename");
exports.default = () => {
    return src("src/*.css")
        .pipe(cleanCss())
        .pipe(rename({ extname: '.min.css' }))
        .pipe(dest("dest"));
}

利用gulp提供src方法读取文件变成流,再通过dest方法把流写入到另一个文件里,中间我们可以加各种操作,比如压缩、更改扩展名等;

二、gulp的demo实践(主要是书写gulpfile.js文件)

新构建一个基础文件目录结构:
github原始代码库地址=》https://github.com/usefire/gulp-demo
git地址:https://github.com/usefire/gulp-demo.git
目录结构:
在这里插入图片描述

1.工作流

(1)基本工作流

第一步:yarn install装一下插件
第二步:在gulpfile.js文件写上各种任务

//gulpfile.js文件
const { src, dest, parallel, series, watch } = require("gulp")
const del = require("del")
/**自动加载插件 */
const loadPlugins = require("gulp-load-plugins")
const plugins = loadPlugins()
const sass = require("gulp-sass")(require("sass"))//因为新版本不内置sass,这里就手动版吧
// const babel = require("gulp-babel")
// const swig = require("gulp-swig")
// const imagemin = require("gulp-imagemin")

const data = {
    menus: [
        {
            name: 'Home',
            icon: 'aperture',
            link: 'index.html'
        },
        {
            name: 'Features',
            link: 'features.html'
        },
        {
            name: 'About',
            link: 'about.html'
        },
        {
            name: 'Contact',
            link: '#',
            children: [
                {
                    name: 'Twitter',
                    link: 'https://twitter.com/w_zce'
                },
                {
                    name: 'About',
                    link: 'https://weibo.com/zceme'
                },
                {
                    name: 'divider'
                },
                {
                    name: 'About',
                    link: 'https://github.com/zce'
                }
            ]
        }
    ],
    pkg: require('./package.json'),
    date: new Date()
}

const clean = () => {
    return del(['temp'])
}

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

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

const page = () => {
    return src("src/**/*.html", { base: 'src' })
        .pipe(plugins.swig({ data, defaults: { cache: false } }))
        .pipe(dest("temp"))
}
const compile = series(clean, parallel(style, script, page))
module.exports = {
    clean,
    compile 
}

其中gulp-load-plugins插件得作用是自动加载package.json文件中的Gulp插件(简化require引入),用parallel和series方法组成一个先清空temp文件再并发执行sass、js、html编译任务的compile组合任务,我们只要再命令行执行yarn gulp compile 就能得到编译后的文件。

(2)加上热更新、统一处理html中资源地址和代码压缩功能

1.加上browser-sync插件,开启一个服务,再配置相关的属性来达到热更新的目的,具体更多配置请看browser-sync文档;
2.使用gulp-useref插件,将HTML引用的多个CSS和JS合并起来,减小依赖的文件个数,从而减少浏览器发起的请求次数
3.使用gulp-if插件,对gulp-useref插件读取出来的文件做分流,对不同文件做不同的操作,比如压缩等
gulp-useref和gulp-if更多配置和用法,请查阅相关文档

const { src, dest, parallel, series, watch } = require("gulp")
const del = require("del")
const loadPlugins = require("gulp-load-plugins")
const plugins = loadPlugins()

/**2.自动加载插件 */
const sass = require("gulp-sass")(require("sass"))//因为新版本不内置sass,这里就手动版吧
// const babel = require("gulp-babel")
// const swig = require("gulp-swig")
// const imagemin = require("gulp-imagemin")
/**3.启动小服务 */
const browserSync = require("browser-sync")
const bs = browserSync.create();

const data = {
    menus: [
        {
            name: 'Home',
            icon: 'aperture',
            link: 'index.html'
        },
        {
            name: 'Features',
            link: 'features.html'
        },
        {
            name: 'About',
            link: 'about.html'
        },
        {
            name: 'Contact',
            link: '#',
            children: [
                {
                    name: 'Twitter',
                    link: 'https://twitter.com/w_zce'
                },
                {
                    name: 'About',
                    link: 'https://weibo.com/zceme'
                },
                {
                    name: 'divider'
                },
                {
                    name: 'About',
                    link: 'https://github.com/zce'
                }
            ]
        }
    ],
    pkg: require('./package.json'),
    date: new Date()
}

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

const style = () => {
    return src("src/assets/styles/*.scss", { base: "src" })
        .pipe(sass({ outputStyle: 'expanded' }))
        .pipe(dest("temp"))
        .pipe(bs.reload({ stream: true }))
}

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

const page = () => {
    return src("src/**/*.html", { base: 'src' })
        .pipe(plugins.swig({ data, defaults: { cache: false } }))
        .pipe(dest("temp"))
        .pipe(bs.reload({ stream: true }))
}

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

const font = () => {
    return src("src/assets/fonts/**", { base: "src" })
        .pipe(plugins.imagemin())
        .pipe(dest("dist"))
}

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

const useref = () => {
    return src("temp/*.html", { base: 'temp' })
        .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
        //读取了html中所有引入的css,js的引入路径文件(包含本地和第三方)
        //这里读出了html,css,js三种格式文件,需要使用压缩插件gulp-htmlmin,gulp-uglify,gulp-clean-css,使用gulp-if判断文件流类型
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({
            collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true
        })))
        // .pipe(dest('dist')) //会有读写混乱的问题
        .pipe(dest("dist"))
}

const server = () => {
    watch('src/assets/styles/*.scss', style)
    watch("src/assets/scripts/*.js", script)
    watch("src/**/*.html", page)
    //dev环境,不监听这些文件,因为只涉及到搬运文件和压缩,无编译
    // watch("src/assets/images/**", image)
    // watch("src/assets/fonts/**", font)
    // watch("public/**", extra)
    //图片字体发生变化刷新浏览器
    watch([
        "src/assets/images/**", "src/assets/fonts/**", "public/**",
    ], bs.reload)

    bs.init({
        notify: false,
        port: 4090,
        // files: 'dist/**',//当不使用这个监听方式时,需要在对应的任务的pipe里加上.pipe(bs.reload({ stream: true })),如上的style和js,html
        server: {
            //开发环境可以匹配"src", "public"下的字体或者图片
            baseDir: ["temp", "src", "public"],
            routes: {
                //优先级最高
                "/node_modules": "node_modules"
            }
        }
    })
}

const compile = parallel(style, script, page)
//转义-》搬运和压缩图片和字体-》压缩html、js、css
const build = series(
    clean,
    parallel(
        series(compile, useref),
        image,
        font,
        extra
    ))
//dev环境不做图片和字体等的搬运和压缩,只进行转换(js、scss等)
const develop = series(compile, server)

module.exports = {
    clean,
    build,
    develop
}
(1)开发环境(develop)

1.如图二,需要对browser-sync这个小型服务做一定的配置,设置端口为4090,配置服务取加载资源时寻找的文件目录(routes优先级高于baseDir),比如图一中bootstrap.css文件是在node_modules目录中,还有字体图片等;
2.如图二,利用gulp中的watch方法监听js、css、html文件,当文件变更就执行对应的任务;
3.如图二,图片和字体等在开发调试阶段,只要监听当他们发生变化,刷新一下浏览器就好,不用做其他处理,这里需要使用到这个服务reload api;
4.如图二,正常来说,我们需要配置服务的files属性,用于当对应文件变更就刷新浏览器,但是我们可以用另一种方式来实现这种监听;其中watch方法已经监听当文件发生变化,执行了对应的编译任务,那我们为啥不在它编译完后就通知浏览器刷新呢,所以如图三,在每个任务后面加上reload方法就行;
在这里插入图片描述
在这里插入图片描述

图一

在这里插入图片描述
图二
在这里插入图片描述
图三

4.运行命令 yarn gulp develop,该任务只对js、css、html做编译处理,图片和字体等不需要做处理,地址端口就是我们在bs.init里配置的端口,
在这里插入图片描述

(2)生产编译

在开发环境,因为是本地调试,所以我们可以不对bootstrap.css或者图片等资源路径做处理没啥问题,只要在本地服务里配置号映射就好了,但是当发到远程服务上去,这些资源就会丢失找不到了,那怎么办呢?请看下面分解

  1. (如图一)需要用到一个插件gulp-useref,它解析html中引入的js和css资源,并根据注释(html编译时会给js、css的引入链接加上注释,具体请看编出的html文件的代码)合并js和css,生成新的文件并修改引入链接地址;
  2. (如图一)使用gulp-if插件来分类流,并对他们做不同的压缩操作等其他操作,最后都把他们写道dist目录中
  3. ( 如图二)通过任务把字体、图片和公共文件搬运到dist目录下
  4. 最后把这些任务组合成build任务,运至yarn gulp build打包成dist,然后使用dist发布到服务就行

在这里插入图片描述
图一
在这里插入图片描述
图二
在这里插入图片描述
图三

三、工作流封装

1.本地调试

当我们很多项目都需要同一份工作流配置时:
第一种方式:我们可以复制gulpfile.js到不同目录下,并创建指定的目录结构,这样没问题,只是不方便维护,比如你想修改某个配置,则需要多个项目同时修改,所以pass;
第二种方式就是打包成一个npm包,哪个项目想使用只要引入一下就好了,修改配置时,只要改个npm包再发布就好了,这个方法可行;

项目目录结构
在这里插入图片描述

  1. 运行新建一个名为yw-gulpfile文件夹,在yw-gulpfile文件夹下运行命令 yarn init -y,生成一个package.json文件;
  2. 根目录新建lib/index.js
  3. package.json相关说明:插件里的package.json,里面的字段配置与npm发布息息相关。
name npm包名
version npm包版本号,版本号是很有讲究的,一般用0.0.0形式分为三部分。第一部分用于不兼容更新,第二部分用于功能新增,第三部分用于bug修复。
description npm包的描述
main 引用npm包的入口文件
keywords npm官方仓库搜索时的关键词
license 开源协议类型,对应LICENSE文件。
files npm上传文件白名单,有些文件是默认会上传的,例如LICENSE、package.json、README.md。(.npmignore文件配置的是黑名单)
repository 源码仓库地址
homepage 插件官网,没有时默认取repository的地址
dependencies dependencies定义插件在生产环境所依赖的包,外部项目安装该插件时也会自动安装插件dependencies里的包(如果外部项目已安装过这些依赖就不再重复安装了),所以注意区分插件的dependencies和devDependencies
peerDependencies 插件本身可能依赖一些其他包(即上述dependencies定义的包),且对依赖包有版本要求,就可以用peerDependencies来指定这些依赖的版本范围,如果外部项目在安装当前插件前已经安装过这些依赖,但不符合版本范围,在安装当前插件时就会有警告提示。
typings ts类型声明文件的路径
bin 用于配置命令脚本,我这里组件插件用不到,如果你的插件是node命令,就用这个配置命令名及对应的可执行脚本文件路径。npm在安装插件时会自动在node_modules/.bin目录创建指向你插件脚本的链接。
sideEffects 用于tree shaking优化,默认为true,设置为false或一个数组(排除列表)可以让插件支持tree shaking,不清楚的请慎用。
  1. 修改package.json里的main为lib/index.js,然后把gulp-demo项目里的gulpfile.js文件里代码剪切到lib/index.js文件里,再把gulp-demo项目package.json里的devDependencies依赖都复制到yw-gulpfile项目的package.json里的dependencies依赖里(因为是yw-gulpfile项目发布了以后用的依赖),yw-gulpfile项目运行 yarn install ,最后运行yarn link(用于调试)。
  2. 回到gulp-demo项目,运行yarn link yw-gulpfile,node_module就能找到这个包了,然后需要在gulpfile.js里写上module.exports = require("yw-gulpfile"),运行yarn gulp build,会报:gulp找不到,这个问题发到npm包以后就不会有了,先临时装一下: yarn add gulp gulp-cli --dev; 再次运行yarn gulp build,会报错:读不到package.json,这是因为之前gulpfile.js里我们读取了这个文件,且data数据是写死的,所以我们要把data数据变成可配置的;
  3. 把lib/index.js里的各种路径和参数变成可配置的:gulp-demo根目录新建一个page.config.js文件,把data数据复制过去,然后在lib/index.js读取该文件就好了,然后data数据使用读取过来的data数据就行,babel的preset也要重新写,不然读取不到:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    7.回到gulp-demo项目,运行yarn gulp build就正常打包了,ok,第一步调试完成;

2.抽象路径和形成可配置

更改lib/index.js文件,把所有目录改成间接的目录地址,以后我们只要在page.config.js配置文件里传build参数覆盖默认的就行了,如下:
(yw-gulpfile项目的lib/index.js文件)

//入口文件
const { src, dest, parallel, series, watch } = require("gulp")
const del = require("del")
const loadPlugins = require("gulp-load-plugins")
const plugins = loadPlugins()

/**2.自动加载插件 */
const sass = require("gulp-sass")(require("sass"))//因为新版本不内置sass,这里就手动版吧
// const babel = require("gulp-babel")
// const swig = require("gulp-swig")
// const imagemin = require("gulp-imagemin")
/**3.启动小服务 */
const browserSync = require("browser-sync")
const bs = browserSync.create();

const cwd = process.cwd(); //定位到宿主的根目录
let config = {
    //默认配置
    build: {
        src: 'src',
        dist: "dist",
        temp: 'temp',
        public: 'public',
        paths: {
            styles: "assets/styles/*.scss",
            scripts: "assets/scripts/*.js",
            pages: "*.html",
            images: 'assets/images/**',
            fonts: "src/assets/fonts/**"
        }
    }

}

try {
    const loadConfig = require(`${cwd}/page.config.js`)
    config = Object.assign({}, config, loadConfig)
} catch (e) {
    //不用处理
    console.log('e: ', e);
}


const clean = () => {
    return del([config.build.dist, config.build.temp])
}

//可以拼接的方式,也可以直接配置
const style = () => {
    return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
        .pipe(sass({ outputStyle: 'expanded' }))
        .pipe(dest(config.build.temp))
        .pipe(bs.reload({ stream: true }))
}

const script = () => {
    return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.babel({ presets: [require("@babel/preset-env")] }))
        .pipe(dest(config.build.temp))
        .pipe(bs.reload({ stream: true }))
}

const page = () => {
    return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.swig({ data: config.data, defaults: { cache: false } }))
        .pipe(dest(config.build.temp))
        .pipe(bs.reload({ stream: true }))
}

const image = () => {
    return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.imagemin())
        .pipe(dest(config.build.dist))
}

const font = () => {
    return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.imagemin())
        .pipe(dest(config.build.dist))
}

const extra = () => {
    return src("**", { base: config.build.public, cwd: config.build.public })
        .pipe(dest(config.build.dist))
}

const useref = () => {
    return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
        .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] }))
        //读取了html中所有引入的css,js的引入路径文件(包含本地和第三方)
        //这里读出了html,css,js三种格式文件,需要使用压缩插件gulp-htmlmin,gulp-uglify,gulp-clean-css,使用gulp-if判断文件流类型
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({
            collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true
        })))
        // .pipe(dest('dist')) //会有读写混乱的问题
        .pipe(dest(config.build.dist))
}

const server = () => {
    watch(config.build.paths.styles, { cwd: config.build.src }, style)
    watch(config.build.paths.scripts, { cwd: config.build.src }, script)
    watch(config.build.paths.pages, { cwd: config.build.src }, page)
    //dev环境,不监听这些文件,因为只涉及到搬运文件和压缩,无编译
    // watch("src/assets/images/**", image)
    // watch("src/assets/fonts/**", font)
    // watch("public/**", extra)
    //图片字体发生变化刷新浏览器,需要分开写,因为目录不一样
    watch([
        config.build.paths.images,
        config.build.paths.fonts,
    ], { cwd: config.build.src }, bs.reload)
    watch(["**"], { cwd: config.build.public }, bs.reload)

    bs.init({
        notify: false,
        port: 4090,
        // files: 'dist/**',//当不使用这个监听方式时,需要在对应的任务的pipe里加上.pipe(bs.reload({ stream: true })),如上的style和js,html
        server: {
            //开发环境可以匹配"src", "public"下的字体或者图片
            baseDir: [config.build.temp, config.build.src, config.build.public],
            routes: {
                //优先级最高
                "/node_modules": "node_modules"
            }
        }
    })
}

const compile = parallel(style, script, page)
//转义-》搬运和压缩图片和字体-》压缩html、js、css
const build = series(
    clean,
    parallel(
        series(compile, useref),
        image,
        font,
        extra
    ))
//dev环境不做图片和字体等的搬运和压缩,只进行转换(js、scss等)
const develop = series(compile, server)

module.exports = {
    clean,
    build,
    develop
}

回到回到gulp-demo项目,运行 yarn gulp build,能正常打包,ok,完事了

3.用cli命令执行 和 发布到npm仓库

(1)用cli命令执行

到这你会发现,gulp-demo项目下还有gulpfile.js文件,那能不能直接不要这个文件,我只要执行命令,就知道我的gulpfile.js是使用的yw-gulpfile项目里的入口文件(lib/index.js);可以的,方式如下:

a) 直接在gulp-demo项目的npm script里配置执行命令 :gulp build --gulpfile ./node_modules/yw-gulpfile/lib/index.js --cwd .
运行yarn build 就能正常打包了。(—cwd 是指定工作目录,.为当前目录)

在这里插入图片描述
b)我们可以在yw-gulpfile项目里提供一个bin cli来执行传参和调用gulp cli就行了,具体操作如下:
在这里插入图片描述
在这里插入图片描述
图一
在这里插入图片描述
图二

(如图一)在yw-gulpfile项目下新建bin/yw.js,然后在package.json里配置bin就好了,然后回到gulp-demo项目重新走一遍yarn link就好了;
(如图二) 在bin/jw.js里写上bin命令就好了(注意:#!/usr/bin/env node这个注释必须写,才能设别成bin命令文件),最后回到gulp-demo项目执行yw build就能正常打包了

(2)发布成npm包
  1. 去npm官网注册账号,官网:https://www.npmjs.com/
  2. 先把yw-gulpfile项目提交到github上

先github建立yw-gulpfile仓库,回到本地yw-gulpfile项目,在命令行输入:git remote add origin https://github.com/usefire/yw-gulpfile.git,然后git add和commit,再git push -u origin master,最后修改一下package.json就可以准备发布了;如下:

{
  "name": "yw-gulpfile",
  "version": "1.0.1",
  "description": "this is a test",
  "main": "lib/index.js",
  "bin": {
    "yw": "bin/yw.js"
  },
  "directories": {
    "lib": "lib"
  },
  "author": "usefire",
  "license": "MIT",
  "keywords": [
    "gulpfile",
    "yw",
    "yw-gulpfile"
  ],
  "homepage": "https://github.com/usefire/yw-gulpfile",
  "bugs": {
    "url": "https://github.com/usefire/yw-gulpfile/issues"
  },
  "repository": {
    "type": "github",
    "url": "https://github.com/usefire/yw-gulpfile.git"
  },
  "files": [
    "lib",
    "bin"
  ],
  "scripts": {
    "lint": "standard --fix"
  },
  "dependencies": {
    "@babel/core": "^7.21.3",
    "@babel/preset-env": "^7.20.2",
    "browser-sync": "^2.29.1",
    "caz": "^1.1.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-imagemin": "^7.1.0",
    "gulp-load-plugins": "^2.0.8",
    "gulp-sass": "^5.1.0",
    "gulp-swig": "^0.9.1",
    "gulp-uglify": "^3.0.2",
    "gulp-useref": "^5.0.0",
    "sass": "^1.60.0"
  },
  "devDependencies": {
    "standard": "^17.0.0"
  }
}
  1. 在把yw-gulpfile项目下控制台输入npm login登录npm,然后执行npm publish,好了发布完成;
  2. 回到gulp-demo项目,装上该插件: yarn add yw-gulpfile --dev ,然后执行yarn yw build就能正常 打包啦

四、总结

官方文档:[https://www.gulpjs.com.cn/](https://www.gulpjs.com.c n/)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值