资讯专栏INFORMATION COLUMN

Gulp 制作写 Demo 小工具

tulayang / 730人阅读

摘要:更改文件名之后,在文件中写入的代码。控制增加前缀的版本根据页面中的标签及标签中的选择器属性,来精简样式。

项目地址

既然重新学习了 Gulp,那索性就再把以前用 Gulp 写的东西拿出来,重新写一遍。这次写的时候要把要点记录下来,不然以后忘了就没法回忆了。

因为 Gulp 现在使用没有以前那么多了,所以就不写复杂的应用了。这次写一个简单的 Demo 处理工具,只是为了把 PSD 转成 HTML 的时候,减少一些重复性操作。

由于写 Demo 的时候,只去关心页面结构和对应的样式,因此,不去考虑 js 相关的内容。主要实现以下几个功能点 :

在 Gulp 的配置文件中使用 ES6 语法书写代码

将 flexible.js 和 reset.css 注入到每个 html 文件的头部

使用 SASS 写样式

自动增加浏览器前缀,处理样式兼容

自动将 px 转成 rem

压缩样式文件

压缩图片

去除 .html 文件中的注释

浏览器实时刷新

去除页面中的无用样式

每次打包前,删除已存在的目标目录

为了这几个小目标,下面开始逐步实现这些功能点。

使用的 Gulp 版本是 3.9.1
准备工作

创建一个 package.json :

$ npm init -y

安装 Gulp 作为项目的开发依赖 :

$ yarn add gulp -D

在项目开始之前,首先需要搭建目录结构。

.
├── gulpfile.babel.js          gulp 的配置文件
├── package.json
├── src                        Demo 源代码存放的目录
│   ├── common                 公共文件存放的目录,将来注入到html文件中
│   │   ├── flexible.min.js
│   │   └── reset.css
│   ├── css
│   │   ├── _none.scss
│   │   └── useful.scss
│   ├── html
│   │   └── index.html
│   └── imgs
│       └── test.png
├── task                       任务文件夹
│   ├── task-clean.js          删除 dist 目录
│   ├── task-css.js            处理 css 的任务
│   ├── task-default.js        默认任务
│   ├── task-html.js           处理 html 的任务
│   └── task-img.js            处理图片的任务
└── yarn.lock
gulpfile.js 中支持 ES6

如果需要在 gulpfile.js 中使用 ES6 相关语法,就需要把 gulpfile.js 改成 gulpfile.babel.js。更改文件名之后,在文件中写入 ES6 的代码。

import gulp from "gulp";

gulp.task("default", () => console.log(123));

运行命令之后,发现,报错了。

$ ./node_modules/.bin/gulp

[14:15:34] Failed to load external module @babel/register
[14:15:34] Failed to load external module babel-register
[14:15:34] Failed to load external module babel-core/register
[14:15:34] Failed to load external module babel/register

出现这个错误是因为使用 ES6 语法后,需要经过 babel 进行转码后才能正常执行任务,因此,要配置 babel 相关的内容。

首先是需要安装 babel 的依赖 :

$ yarn add babel-cli babel-preset-env -D

babel 在运行的时候,需要读取其配置文件中的信息,将对应的代码进行转译。所以,.babelrc 文件必不可少。

{
  "presets": ["env"]
}

再次运行 Gulp 命令的时候,会发现还是有错误。

$ ./node_modules/.bin/gulp

[14:20:33] Failed to load external module @babel/register

这个错误就很奇怪了,命名已经安装了 babel 的依赖了,为什么还会有这个错误呢?这是因为在解析 .babel.js 文件中,加载 babel 组件不正确造成的。babel-core/register 已经过时了,现在使用 babel-register 来代替了。如果要修复这个问题,就需要修改 node_modules 中 interpret 模块中的 index.js

module: "@babel/register" 改成 module: "babel-register"。具体修改的位置就是下面代码中的第三行 :

  ".babel.js": [
    {
      module: "@babel/register",

在 gulpfile.babel.js 中,我们将 task 目录下的文件加载到该配置文件中,这个时候需要用到的模块是 require-dir

在项目中安装 require-dir 模块 :

$ yarn add require-dir -D

模块完成之后,改造 gulpfile.babel.js。

import requireDir from "require-dir";

requireDir("./task");
删除目标目录

一般情况下,把最终生成好的文件放入 dist 目录中,那么目标目录就是 dist。

删除文件夹或文件,一般使用 del 模块,这个模块异步方法返回的是一个 Promise 对象。

// ./task/task-clean.js

gulp.task("clean", () => {
  return del("./dist").then(paths => {
    // 如果 paths 长度为 0,说明文件夹不存在
    if (paths.length) {
      console.log(paths + " 删除成功")
    } else {
      console.log("文件夹不存在");
    }
  });
});

通过上面的代码创建的 clean 任务,在执行任务 clean 的时候,就可以把 dist 目录进行删除了。

处理图片

图片的处理相对就比较简单了,只需要压缩图片并拷贝到对应的目录中就可以了。压缩图片使用的模块是 gulp-imagemin

gulp.task("imgs", () => {
  return gulp.src([
      "./src/imgs/*.jpg",
      "./src/imgs/*.png",
      "./src/imgs/*.gif",
      "./src/imgs/*.svg"
    ], {
      base: "src"
    })
    .pipe(imagemin())
    .pipe(gulp.dest("./dist"));
});

通过上面的代码创建的 imgs 任务,在执行任务 imgs 的时候,就可以把 ./src/imgs 中的内容压缩并拷贝到 ./dist/imgs 中了。

处理 html

处理 html 文件的时候,就稍微复杂点了。因为牵涉到压缩和替换。如果要替换 html 中的内容,使用的模块是 gulp-replace;如果需要压缩 html 文件,那么就需要使用 gulp-htmlmin

在这里,需要替换 html 中引入 flexible.js 的地方为对应的内容,就需要写成下面的形式 :

    .pipe(replace("", () => {
      // 获取 flexible.min.js 文件中的内容
      let flexibleData = fs.readFileSync(path.resolve(__dirname, "../src/common/flexible.min.js"));
      // 返回一个流,写入共下一个内容使用
      return ``;
    }))

同时初始化 css 的样式也要注入到 html 文件中,这个时候就要把 html 中对应的路径替换成对应的文件内容 :

    .pipe(replace("", () => {
      // 获取 reset.css 文件中的内容
      let flexibleData = fs.readFileSync(path.resolve(__dirname, "../src/common/reset.css"));
      // 返回一个流,写入共下一个内容使用
      return ``;
    }))

对应的文件替换完成之后,就需要删除 html 文件中的所有注释信息 :

    .pipe(htmlmin({
      collapseWhitespace: false, // 删除文档中的空格和换行,默认是false,不删除
      removeComments: true // 清除注释内容
    }))

最后就是将对应的 html 文件拷贝到对应的文件夹中。完整的任务代码如下 :

gulp.task("html", () => {
  return gulp.src("./src/html/*.html", {
      base: "src"
    })
    .pipe(replace("", () => {
      // 获取 flexible.min.js 文件中的内容
      let flexibleData = fs.readFileSync(path.resolve(__dirname, "../src/common/flexible.min.js"));
      // 返回一个流,写入共下一个内容使用
      return ``;
    }))
    .pipe(replace("", () => {
      // 获取 reset.css 文件中的内容
      let flexibleData = fs.readFileSync(path.resolve(__dirname, "../src/common/reset.css"));
      // 返回一个流,写入共下一个内容使用
      return ``;
    }))
    .pipe(htmlmin({
      collapseWhitespace: false, // 删除文档中的空格和换行,默认是false,不删除
      removeComments: true // 清除注释内容
    }))
    .pipe(gulp.dest("./dist"));
});
处理样式

样式文件的处理相对就比较复杂一点了。需要实现以下几个功能点 :

将 sass 文件转成 css

将 px 转成 rem

自动增加浏览器前缀

排序 css 属性

压缩 css 代码

首先定义一个规则,以下划线开头的 .scss 文件不进行转换。将以下划线开头的 .scss 文件作为提供公共方法的文件。

  gulp.src(["./src/css/*.scss", "!./src/css/_*.scss"], {
      base: "src"
    })

对 .scss 文件进行转译,生成的 css 文件不删除注释,因为注释信息在 px 转成 rem 的时候会用到。在转换的过程中,使用的模块是 gulp-sass

    .pipe(sass({
      outputStyle: "compact" // sass文件的输出方式,保留注释内容
    }))

将 px 转成对应的 rem,需要依赖两个模块 gulp-postcsspostcss-px2rempostcss-px2rem 是核心的转换模块。

    .pipe(postcss([px2rem({
      remUnitpx2rem: 75 // // 将px转成rem,基准值是75,也就是用 75px/75=1rem
    })]))

接下来就可以做 css 的兼容处理,为属性增加浏览器前缀了。自动增加浏览器前缀使用到的模块是 gulp-autoprefixer

    .pipe(autoprefixer({
      browsers: ["last 2 versions", "Android >= 4.0"] // 控制增加前缀的版本
    }))

根据页面中的标签及标签中的选择器属性,来精简样式。主要就是使用 postcss 的插件 postcss-uncss 来精简样式,但是 postcss-uncss 模块又依赖 uncss 模块,因此,这两个模块都需要安装。安装完成之后,就可以设置精简样式的代码了。

    .pipe(postcss([uncss({ // 去除多余的样式
      html: ["./src/**/*.html"]
    })]))

下面做的就是排序和压缩 css 了。排序 css 属性用到的模块是 gulp-csscomb,压缩 css 用到的模块是 gulp-cssnano

    .pipe(csscomb()) // 排序CSS属性
    .pipe(cssnano()) // 压缩CSS代码
    .pipe(gulp.dest("./dist"));
默认任务

在默认任务中,首先序列化任务的执行顺序。在每次执行任务之前,先把 dist 目录删除,然后执行 html css imgs 任务。这个时候就要使用 gulp-sequence 模块来定义任务执行的顺序。为了实现任务的顺序执行,就要在每个任务中返回一个流,或者调用一个回调函数,否则执行顺序会不正常。

gulp.task("build", gulpSequence("clean", ["html", "css", "imgs"]));

如果要实现代码修改,浏览器自动刷新,就要使用 browser-sync 模块了。

gulp.task("default", ["build"], () => {
  // 启动浏览器
  browserSync({
    server: {
      baseDir: "./dist"
    },
  }, (err, bs) => {
    console.log(bs.options.getIn(["urls", "local"]));
  });
  // 监视文件变化,执行对应的任务
  gulp.watch("src/html/*.*", ["html"]);
  gulp.watch("src/css/*.*", ["css"]);
  gulp.watch("src/imgs/*.*", ["imgs"]);
});

在执行默认任务后,修改代码,并没有发现浏览器跟着刷新。

$ ./node_modules/.bin/gulp

这是因为每个任务中没有通知浏览器刷新,因此,要在每个任务中加入流发生变化,通知浏览器刷新。

    .pipe(browserSync.reload({ // 管道刷新
      stream: true
    }))
    .pipe(gulp.dest("./dist"));
使用

在 src/html 写 html 文件

在页面的头部加入

在 src/css 中写 .scss 样式

将图片放入 imgs 文件夹中

执行命令 : ./node_modules/.bin/gulp

当然,命令也可以简化,就是在 package.json 中配置。

  "scripts": {
    "gulp": "gulp"
  }

这个时候在命令行执行命令就变成下面的形式了 :

$ npm run gulp

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92245.html

相关文章

  • HTML 代码复用实践

    摘要:安装好之后,来简单的组织一下文件的目录生产环境的存放文件夹公共部分的存放文件夹编辑后的文件在新建的,配置好接着新建两个文件,分别是头部和底部这是的内容这是的内容最后在新建一个,把要用到的和给进来。 前言 通常我们所做的一些页面,我们可以从设计图里面看出有一些地方是相同的。例如:头部,底部,侧边栏等等。如果是制作静态页面的同学,对于这些重复的部分只能够通过复制粘贴到新的页面来,如果页面...

    Profeel 评论0 收藏0
  • iconfont实践

    摘要:所以实现小图标时雪碧图跟图标字体会在一个网站共存,自定义图标字体为什么比较耗时,且太复杂图标无法实现请往下看开发流程就了解了。参考资料细谈浅谈图标字体向下兼容优雅降级技术绘制小图标技巧雪碧图图标字体矢量小图标设计本文对应源码源码地址演示地址 showImg(https://segmentfault.com/img/bVRnAC?w=431&h=220); 之前写了一篇关于雪碧图的博文,...

    bitkylin 评论0 收藏0
  • 浅谈 CSS Sprites 雪碧图应用

    摘要:编写配置文件,以下是关键配置代码雪碧图合并输出到文件参数执行目录参数生成的和图片的文件名之所以推荐,是因为非常的灵活,看懂模块的可以根据你的项目情况编写对应的配置文件。 showImg(https://segmentfault.com/img/bVGpAw?w=518&h=156); 前言 网站开发90%会用到小图标, 多小图标调用显示是前端开发常见的问题;目前小图标显示常见有两种方式...

    MkkHou 评论0 收藏0
  • 应该了解的 Web 图标解决方案

    摘要:那么,在我们当下的前端开发中,最常见的图标解决方案有哪些呢大概是三种,图片和。 showImg(https://segmentfault.com/img/remote/1460000006774999);A picture is worth a thousand words, 一图胜千言。 没错,从 Web 诞生的那天开始,图标就成为视觉层面不可或缺的一个元素,在一个 Web 页面中,...

    zhangwang 评论0 收藏0
  • 应该了解的 Web 图标解决方案

    摘要:那么,在我们当下的前端开发中,最常见的图标解决方案有哪些呢大概是三种,图片和。 showImg(https://segmentfault.com/img/remote/1460000006774999);A picture is worth a thousand words, 一图胜千言。 没错,从 Web 诞生的那天开始,图标就成为视觉层面不可或缺的一个元素,在一个 Web 页面中,...

    ingood 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<