最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 自动化构建之--Gulp实现

    正文概述 掘金(LC十三)   2021-02-12   642

    在项目根目录安装gulp模块

    yarn add gulp --dev
    npm install --save-dev gulp
    

    根目录下创建gulpfile.js文件, 作为gulp配置的入口文件

    导入gulp模块的部分api:

    const { src, dest  } = require("gulp");
    const sass = require("gulp-sass");
    

    1.style任务:

    • 样式编译

    • 定义为私有任务,通过module export导出具体任务

    • src创建读取流, dest创建写入流, dist用于分发发布

    • 这里想通过编译后,与src中的目录结构相同,那么需要指定目标路径

    • 如果每个任务都手动指定目标路径显然重复臃肿,可以通过在读取流中添加配置项,指定写入流路径

    • saas({ outputStyle: "expanded" })通配展开样式

    • 通过插件转换文件yarn gulp-sass --dev安装转换插件并引入

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

    通过yarn gulp style命令运行编译任务。

    2.脚本任务:

    • 同样定义为私有任务, 通过module export导出任务
    • 安装插件yarn add @babel/core @babel/preset-env --dev, 转换js
    • 此时运行报错

    自动化构建之--Gulp实现

    • 原因: 这里的Babel只是帮你唤起转换进程, 并没有像sass模块那样真正的转换, 所以需要手动安装@babel/core模块来实现编译
    • 解决办法: yarn add @babel/core @babel-preset-env --dev
    • preset会默认把所有的ECMAScript代码全部做转换, 并在转换流中添加配置项
    • 这里如果不指定配置项{ presets: ["@babel/preset-env"] }, 那么编译后的文件与源文件没差, 是因为BabelECMAScript的平台, 具体转换是Babel内部的插件, preset-env就是最新的打包集合.
    const script = () => {
      return src("src/assets/scripts/*.js", { base: "src" })
        .pipe(babel({ presets: ["@babel/preset-env"] }))
        // .pipe(babel())
        .pipe(dest("dist"))
    }
    

    通过yarn gulp script命令运行编译任务。

    3.页面模板编译-html文件

    • 安装插yarn add gulp-swig --de
    • 通过指swi配置项配``htm`中的动态数据
    • 由于html文件不止在src下, 也有在其子目录下, 所以这里使用通配符 **/*.html
    const page = () => {
      return src("src/**/*.html", { base: "src" })
        // .pipe(swig({ data }))
        .pipe(swig())
        .pipe(dest("dist"))
    }
    

    4.组合任务 通过parallel方法, 创建组合任务

    // 导入parallel模块创建并行任务
    
    const compile = parallel模块(style, script, page)
    
    // 导出
    module.exports = {
      compile
    }
    

    通过yarn gulp compile命令运行编译任务。执行结果:

    自动化构建之--Gulp实现

    5.图片转换

    • 安装插件yarn add gulp-imagemin --dev
    • 图片是无损压缩, 只是删除了源数据一些, svg格式只是代码格式化处理
    /**
     * 图片任务
     */
    const image = () => {
      return src("src/assets/images/**", { base: "src" })
        .pipe(imagemin())
        .pipe(dest("dist"))
    }
    

    通过yarn gulp image命令运行编译任务。执行结果: 自动化构建之--Gulp实现

    6.文字任务

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

    添加到组合任务中并导出:

    // 组合任务
    const compile = parallel(style, script, page, image, font)
    
    // 导出模块
    module.exports = {
      compile
    }
    

    7.其他文件

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

    compile任务构建src项目中的需要编译的文件,为了不混淆,这里重新创建一个任务

    const compile = parallel(style, script, page, image, font)
    const build = parallel(compile, extra);
    
    // 导出模块
    module.exports = {
      build
    }
    

    8.文件清除

    • 安装插件: yarn add del --dev
    • del模块返回promise对象, 可以支持clean方法标记完成
    • del模块不属于gulp
    • 清除任务执行在编译之前, 先清除后编译, 不能使用并行, 导入serice串行执行。
    const { src, dest, parallel, series } = require("gulp");
    const del = require("del");
    
    // 定义清除任务
    const clean = () => {
      return del(["dist"])
    }
    
    const build = series(clean, parallel(compile, extra));
    

    通过yarn gulp build命令运行编译任务。执行结果: 自动化构建之--Gulp实现

    8.自动加载插件

    • 随着编译任务越来越多, 手动加载插件就变得繁重, 这里采用一个插件加载.
    • 安装插件: yarn add gulp-load-plugins --dev
    • plugins是一个对象, 所有插件会成为这个对象上的属性
    • 将所有插件重命名为plugins.{name}的形式
    const loadPlugins = require("gulp-load-plugins");
    const plugins = loadPlugins();
    
    // const plugins.sass = require("gulp-sass");
    // const plugins.babel = require("gulp-babel");
    // const plugins.swig = require("gulp-swig");
    // const plugins.imagemin = require("gulp-imagemin");
    

    9.热更新开发服务器

    • 开发调试应用, 实现代码更改后自动编译, 自动刷新浏览器页面
    • 安装模块: yarn add browser-sync --dev
    • browser-sync模块支持代码更改后热更新到浏览器
    • 并不是gulp插件, 提供create方法自动创建开发服务器
    • baseDir方法指定运行到浏览器的路径, 这里指定编译后的dist
    // 导入插件
    const loadPlugins = require("gulp-load-plugins");
    // 创建开发服务器
    const bs = browserSync.create();
    // 初始化并启动
    const serve = () => {
      bs.init({
        server: {
          baseDir: "dist"
        }
      })
    }
    

    此时启动后, 会没有加载node_modules下的一些资源拷贝, 所以页面并没有加载全部, 通过给bs模块配置路由指向本地目录的node_modules, 如果routes有配置会先执行, 然后再执行baseDir中的路径.

    // 单独定义开发服务器启动
    const serve = () => {
      bs.init({
        notify: false, // 启动时不弹出提示
        port: 2080, // 端口
        // open: false,
        server: {
          baseDir: "dist",
          routes: {
            "/node_modules": "node_modules"
          }
        }
      })
    }
    

    此时加入热更新, 执行顺序应该是先clean清除后, 执行build编译源代码到dist目录, 编译完成后再执行serve更新到浏览器页面, 这里暂不考虑源代码变更后执行, 先加入dist目录下文件变化后更新. 加入files指定路径, 这里就是dist下的所有文件.

    const serve = () => {
      bs.init({
        notify: false, // 启动时不弹出提示
        port: 2080, // 端口
        // open: false,
        files: "dist/**",
        server: {
          baseDir: "dist",
          routes: {
            "/node_modules": "node_modules"
          }
        }
      })
    }
    

    通过yarn gulp serve启动服务, 修改dist下任意文件可观察到已生效.

    10.监视变化以及构建优化

    • 借助gulp中的watch方法监听. 此方法第一个参数接收通配符, 第二个参数即执行函数, 在serve启动的时候监听文件变化.
    • 此时在启动serve的时候, 就会先执行watch的监听, 一旦发现有变化, 执行对应的编译任务, 编译完后启动服务器, 那么此时久完成了之前src变化后, 同步到浏览器页面.

    如下:

    // 导入watch方法
    const { src, dest, parallel, series, watch } = require("gulp");
    
    const serve = () => {
      watch("src/assets/styles/*.scss", style)
      watch("src/assets/styles/*.js", script)
      watch("src/**/*.html", page)
      watch("src/assets/images/**", image)
      watch("src/assets/fonts/**", font)
      watch("public/**", extra)
    
      bs.init({
        notify: false, // 启动时不弹出提示
        port: 2080, // 端口
        // open: false,
        files: "dist/**",
        server: {
          baseDir: "dist",
          routes: {
            "/node_modules": "node_modules"
          }
        }
      })
    }
    

    那么这里还存在两个问题:

    • 上面的图片, 字体以及public目录下的文件只是做了拷贝, 并不会影响源文件, 所以这些文件只需在上线之前进行编译压缩即可, 所以开发阶段忽略这些文件的编译.如下: serve中的watch方法不再监听图片文字等, baseDir改为数组, 会按照顺序依次向后查询.
    • 如果是首次编译, 直接执行serve, 那么此时dist文件还没有生成, 那么就找不到对应路径, 报错, 所以这里将serve任务和build组合, 编译生成dist目录后再启动web服务器, 串行执行.
    • 也希望上面三类文件变化后自动更新浏览器, 可使用watch[]的形式
    // 单独定义开发服务器启动
    const serve = () => {
      watch("src/assets/styles/*.scss", style)
      watch("src/assets/styles/*.js", script)
      watch("src/**/*.html", page)
      // 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: 2080, // 端口
        // open: false,
        files: "dist/**",
        server: {
          baseDir: ["dist", "src", "public"],
          routes: {
            "/node_modules": "node_modules"
          }
        }
      })
    }
    

    组合任务, 开发模式下, 编译后在执行serve:

    const compile = parallel(style, script, page)
    
    const build = series(clean, parallel(compile, extra, image, font));
    
    const develop = series(compile, serve)
    
    // 导出模块
    module.exports = {
      clean,
      compile,
      build,
      serve,
      develop
    }
    

    通过yarn gulp develop命令运行编译任务。执行结果: 自动化构建之--Gulp实现

    11.useref文件引入处理

    • node_modules/下的文件引入, 之前的处理是指向本地的开发文件, 上线后dist并没有这些文件
    • 安装插件: yarn add gulp-useref --dev
    • 原理: 这个插件会根据dist目录下的标识将这些引入的文件编译到一个新的文件.如图

    自动化构建之--Gulp实现

    const useref = () => {
      return src("dist/*.html", { base: "dist" })
        .pipe(plugins.useref({ searchPath: ["dist", "."] }))
        .pipe(dest("dist"))
    }
    

    通过yarn gulp useref命令运行编译任务。执行后的目录结构: 自动化构建之--Gulp实现

    12.文件压缩

    • 安装插件: yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev
    • 同时需要判断是哪类文件, 执行哪类的压缩安装if插件: yarn add gulp-if --dev

    此时存在一个问题: dist目录同时进行读写操作, 会造成文件冲突, 有的文件不能写入, 所以这时需要指定临时目录temp, 在编译完后, 进行useref对引入的文件进行处理, 最后写入到dist目录. 那么此时的gulpfile.js如下:

    // 实现这个项目的构建任务
    
    /**
     * 导入gulp模块的部分api
     */
    const { src, dest, parallel, series, watch } = require("gulp");
    const del = require("del");
    const browserSync = require("browser-sync")
    const loadPlugins = require("gulp-load-plugins");
    
    const plugins = loadPlugins();
    const bs = browserSync.create();
    
    // 定义清除任务
    const clean = () => {
      return del(["dist", "temp"])
    }
    
    /**
     * 样式编译
     * 定义为私有任务,通过module export 导出具体任务
     * src 创建读取流 dest创建写入流 dist用于分发发布
     * 这里想通过编译后,与src中的目录结构相同,那么需要指定目标路径
     * 如果每个任务都手动指定目标路径显然重复臃肿,可以通过在读取流中添加配置项,指定写入流路径
     * 通过插件转换文件yarn gulp-sass --dev 安装转换插件并引入
     */
    const style = () => {
      return src("src/assets/styles/*.scss", { base: "src" })
        .pipe(plugins.sass({ outputStyle: "expanded" }))
        .pipe(dest("temp"))
        .pipe(bs.reload({ stream: true })) // 以流的形式推到浏览器, serve就不需要files参数了
    }
    
    
    /**
     * 脚本任务
     * base拷贝的基本目录
     * 安装插件yarn add @babel/core @babel/preset-env --dev, 转换js
     */
    const script = () => {
      return src("src/assets/scripts/*.js", { base: "src" })
        .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
        // .pipe(babel())
        .pipe(dest("temp"))
        .pipe(bs.reload({ stream: true }))
    }
    
    /**
     * 页面编译任务
     * 通过指定swig配置项配置html中的动态数据
     */
    const page = () => {
      return src("src/**/*.html", { base: "src" })
        // .pipe(swig({ data }))
        .pipe(plugins.swig())
        .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 serve = () => {
      watch("src/assets/styles/*.scss", style)
      watch("src/assets/styles/*.js", script)
      watch("src/**/*.html", page)
      // 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: 2080, // 端口
        // open: false,
        // files: "dist/**",
        server: {
          baseDir: ["temp", "src", "public"],
          routes: {
            "/node_modules": "node_modules"
          }
        }
      })
    }
    
    // 引入文件的处理
    const useref = () => {
      return src("temp/*.html", { base: "temp" })
        .pipe(plugins.useref({ searchPath: ["temp", "."] }))
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({ 
          collapseWhitespace: true,
          minifiCss: true,
          minifiJs: true 
        })))
        .pipe(dest("dist"))
    }
    
    
    
    // 组合任务
    const compile = parallel(style, script, page)
    /**
     * compile任务构建src项目中的需要编译的文件,为了不混淆,这里重新创建一个任务
     * 清除任务执行在编译之前,先清除后编译,不能使用并行。
     */
    const build = series(
      clean, 
      parallel(
        series(compile, useref), 
        extra, 
        image, 
        font
      )
    );
    
    const develop = series(compile, serve)
    
    // 导出模块
    module.exports = {
      clean,
      compile,
      build,
      serve,
      develop,
      useref
    }
    

    13.补充package.json文件中, 加入上面的任务命令, 更方便的使用

    "scripts": {
        "clean": "gulp clean",
        "lint": "gulp lint",
        "serve": "gulp serve",
        "build": "gulp build",
        "start": "gulp start",
        "deploy": "gulp deploy --production"
      },
    

    起源地下载网 » 自动化构建之--Gulp实现

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元