前端 自动化构建 入门及原理

自动化构建简介

今天请假肝学习 周三.
把一些重复的工作机械化和一些不被支持的新特转化,以及利用其它高效工具进行开发。

自动化构建初体验

前端 自动化构建 入门及原理_第1张图片
前端 自动化构建 入门及原理_第2张图片
scss也是一种自动化构建,帮我们自动转换成原始css,但也要重复执行命令,安装 npm install -g sass
在这里插入图片描述

我们可以用npm script解决这些问题

npm script 使用

package中新增一个对象
前端 自动化构建 入门及原理_第3张图片
前端 自动化构建 入门及原理_第4张图片
先安装下面这个,用于启动一个测试服务器
yarn add browser-sync --dev
在这里插入图片描述
package中添加
前端 自动化构建 入门及原理_第5张图片
启动成功
前端 自动化构建 入门及原理_第6张图片
我们要在这个服务器启动前设置样式,有个preserve之前的属性
前端 自动化构建 入门及原理_第7张图片
添加变动监听变化 ,自动编译
在这里插入图片描述
因为加了watch命令行会一种占用着,我们需要启动多个任务去解决这个问题,先安装下面这个
yarn add npm-run-all --dev
在这里插入图片描述

前端 自动化构建 入门及原理_第8张图片
在这里插入图片描述
在这里插入图片描述
build监听scss文件的变化去编译
browser-sync 监听文件变动去刷新浏览器
可以一起运行了
这样就可以刷改完后就不需要手动刷新浏览器获取最新的代码了(vue cli应该也是这个原理)

{
  "name": "my-web-app",
  "version": "0.1.0",
  "main": "index.js",
  "author": "zce  (https://zce.me)",
  "license": "MIT",
  "scripts": {
    "build": "sass scss/main.scss css/style.css --watch",
    "serve": "browser-sync . --files \"css/*.css\"",
    "start": "run-p build serve"
  },
  "devDependencies": {
    "browser-sync": "^2.26.7",
    "npm-run-all": "^4.1.5",
    "sass": "^1.22.10"
  }
}

前端 自动化构建 入门及原理_第9张图片
这样我们就完成了一个简单的自动化工作流

常用的自动化构建工具

没有webpack是因为 webpack严格说是模块打包工具。下面这些工具可以解决无聊重复性工作的自动化。
前端 自动化构建 入门及原理_第10张图片
grunt老牌构建工具 生态完善 但基于临时文件构建的速度较慢(1读写磁盘多,2一个文件处理后再继续下一步)。
gulp很好解决了grunt的问题,因为是基于内存去实现的,相对磁盘读写肯定快了很多而且支持同时多任务,使用比grunt简单
fis是百度前端团队推出的构建系统,相对前俩个微内核的构建系统 fis更像是一个捆绑套餐,项目的大部分需求都已经集成了,资源请求性能优化等。

总结

fis适合新手,其他适合灵活多变
新手希望规则,老手喜欢自由

Grunt 的基本使用

了解 后面gulp为主
先npm init --yes 先init package.json
yarn add grunt
添加 gruntfile文件(入口文件)

前端 自动化构建 入门及原理_第11张图片
多任务和默认任务
前端 自动化构建 入门及原理_第12张图片
多任务
在这里插入图片描述
异步任务
可以看到异步的console.log不打印,grunt默认支持同步代码,这个时候需要 this。async 和 done()去解决,因为是异步任务,grunt会等done的执行才会结束这个异步任务
前端 自动化构建 入门及原理_第13张图片

Grunt 标记任务失败

前端 自动化构建 入门及原理_第14张图片
异步任务 无法标记任务失败,可以用 解决

前端 自动化构建 入门及原理_第15张图片

Grunt 的配置方法

压缩文件等
前端 自动化构建 入门及原理_第16张图片
如果是对象
前端 自动化构建 入门及原理_第17张图片

Grunt 多目标任务

多任务要先配置好 init先 不然报错
前端 自动化构建 入门及原理_第18张图片
配置好后
前端 自动化构建 入门及原理_第19张图片
指定某目标 grunt build:css
前端 自动化构建 入门及原理_第20张图片

前端 自动化构建 入门及原理_第21张图片

Grunt 插件的使用

插件是grunt核心
前端 自动化构建 入门及原理_第22张图片
前端 自动化构建 入门及原理_第23张图片
前端 自动化构建 入门及原理_第24张图片
前端 自动化构建 入门及原理_第25张图片
通配符的方式
在这里插入图片描述
子目录以及子目录下的文件

Grunt 常用插件及总结

grunt-scss npm模块,使用不需要环境要求。 add grunt-sass sass --dev
前端 自动化构建 入门及原理_第26张图片
报错解决 先指定实现的模块
前端 自动化构建 入门及原理_第27张图片
可以添加这个获取soursemap文件

前端 自动化构建 入门及原理_第28张图片
前端 自动化构建 入门及原理_第29张图片
每次安装一个新模块都要 添加下面方法,很麻烦
在这里插入图片描述
解决方法在这里插入图片描述
导入这个模块 后 就不需要重复导入插件了
前端 自动化构建 入门及原理_第30张图片
添加babel目标配置 files配置输出和输入,而且也要设置选项,因为要转换es6(ECMA新特新转换)需要一个preset

前端 自动化构建 入门及原理_第31张图片

安装 grunt修改完后自动编译的插件

在这里插入图片描述
添加配置选项和目标
题外话 scss和sass是同一个 因为某原因 scss变为了扩展名
前端 自动化构建 入门及原理_第32张图片
一开始不会立即执行babel 只有在文件修改保存后执行
解决,做一个映射 这样启动的时候就会立即执行
在这里插入图片描述

Grunt快退出舞台了 因为是鼻祖就介绍介绍

const sass = require('sass')
const loadGruntTasks = require('load-grunt-tasks')

module.exports = grunt => {
  grunt.initConfig({
    sass: {
      options: {
        sourceMap: true,
        implementation: sass
      },
      main: {
        files: {
          'dist/css/main.css': 'src/scss/main.scss'
        }
      }
    },
    babel: {
      options: {
        sourceMap: true,
        presets: ['@babel/preset-env']
      },
      main: {
        files: {
          'dist/js/app.js': 'src/js/app.js'
        }
      }
    },
    watch: {
      js: {
        files: ['src/js/*.js'],
        tasks: ['babel']
      },
      css: {
        files: ['src/scss/*.scss'],
        tasks: ['sass']
      }
    }
  })

  // grunt.loadNpmTasks('grunt-sass')
  loadGruntTasks(grunt) // 自动加载所有的 grunt 插件中的任务

  grunt.registerTask('default', ['sass', 'babel', 'watch'])
}

-----------------------grunt结束分割线----------------------

Gulp 的基本使用

正题!
gulp高效易用。

1 新目录
2 yarn init
3 yarn add gulp --dev
安装gulp的同时会自动安装一个叫gulpcli的模块,这样就可以运行gulp命令
4 创建 gulpfile.js (导出函数的方式)

运行!yarn gulp foo 你导出的函数
前端 自动化构建 入门及原理_第33张图片
报错了,解决:需要手动调用 done
在这里插入图片描述
前端 自动化构建 入门及原理_第34张图片
gulp4.0前 注册方法需要一个模块去实现(了解即可,以后都是函数导出了)
前端 自动化构建 入门及原理_第35张图片

Gulp 的组合任务

并行 串行任务
前端 自动化构建 入门及原理_第36张图片
并行
前端 自动化构建 入门及原理_第37张图片

Gulp 的异步任务

前端 自动化构建 入门及原理_第38张图片

  • 1 回调函数
  • 2promise(不需要返回值),也可以用 async和await
  • 3 Stram方式,最常用到因为构建大多都读写文件(先导入文件流 const fs = require(‘fs’))
const fs = require('fs')

exports.callback = done => {
  console.log('callback task')
  done()
}

exports.callback_error = done => {
  console.log('callback task')
  done(new Error('task failed'))
}

exports.promise = () => {
  console.log('promise task')
  return Promise.resolve()
}

exports.promise_error = () => {
  console.log('promise task')
  return Promise.reject(new Error('task failed'))
}

const timeout = time => {
  return new Promise(resolve => {
    setTimeout(resolve, time)
  })
}

exports.async = async () => {
  await timeout(1000)
  console.log('async task')
}

exports.stream = () => {
  const read = fs.createReadStream('yarn.lock')
  const write = fs.createWriteStream('a.txt')
  read.pipe(write)  //pipe导入写入流中   文件流读完后有个end函数调用  这样gulp就知道结束了
  return read
}
//文件流读完后有个end函数调用  这样gulp就知道结束了  以下代码模拟这个过程
// exports.stream = done => {
//   const read = fs.createReadStream('yarn.lock')
//   const write = fs.createWriteStream('a.txt')
//   read.pipe(write)  //pipe导入写入流中
//   read.on('end', () => {  //监听end时间
//     done()
//   })
// }

Gulp 构建过程核心工作原理

大多数都是读文件然后进行转换
前端 自动化构建 入门及原理_第39张图片
通过node文件流实现模拟
前端 自动化构建 入门及原理_第40张图片


const fs = require('fs')
const { Transform } = require('stream')

exports.default = () => {
  // 文件读取流
  const readStream = fs.createReadStream('normalize.css')

  // 文件写入流
  const writeStream = fs.createWriteStream('normalize.min.css')

  // 文件转换流
  const transformStream = new Transform({
    // 核心转换过程
    transform: (chunk, encoding, callback) => {
      const input = chunk.toString()
      const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '')  //转换空格 达到压缩的目的
      callback(null, output)
    }
  })

  return readStream
    .pipe(transformStream) // 转换
    .pipe(writeStream) // 写入
}

Gulp 文件操作 API

大多数都是用插件进行转换,相比原生的API 就是上面node哪个,gulp的api会更强大。
前端 自动化构建 入门及原理_第41张图片
上面只是单纯输入输出,现在中间做加工,先下载压缩插件,yarn add gulp-clean-css --dev
在这里插入图片描述
前端 自动化构建 入门及原理_第42张图片
yarn gulp后就获得压缩后的代码了。

再添加一个 指定名字插件 下载安装 导入 代码添加 运行gulp 获得处理后的重命名的min文件 yarn add gulp-rename --dev
前端 自动化构建 入门及原理_第43张图片

Gulp 案例 - 样式编译

下载代码

git clone https://github.com/zec/zec-gulp-demo.git
前端 自动化构建 入门及原理_第44张图片

src文件夹下都会被转换,后面还可以配置压缩图片
开干!
先 yarn add gulp --dev
根目录创建 gulpfile.js
定义任务 (输出的文件夹dist dist意思是分发发布的意思)
写完导出才能使用,不然因为私有无法使用。
运行 gulp style
前端 自动化构建 入门及原理_第45张图片
输出来的文件不是我们希望的 我们希望的是原来的目录结构 src/asset/style/…
前端 自动化构建 入门及原理_第46张图片
解决:前端 自动化构建 入门及原理_第47张图片
在这里插入图片描述
添加转换过程(安装插件实现)
yarn add gulp-sass --dev(内部会安装node-sass)
导入
使用!
前端 自动化构建 入门及原理_第48张图片
带_的不会被转换

前端 自动化构建 入门及原理_第49张图片

问题2 {}位置问题
在这里插入图片描述

前端 自动化构建 入门及原理_第50张图片
展开后
在这里插入图片描述

Gulp 案例 - 脚本编译

新任务 添加script
yarn add gulp-babel --dev
导入
前端 自动化构建 入门及原理_第51张图片
可能会报错,因为不像gulp-sass那样会自动帮你安装核心模块,babel需要你手动去安装
在这里插入图片描述
解决 yarn add @babel/core @babel/preset-env --dev
添加转换 ,运行!(注意一点要加 preset不然转换没效果,因为babel只是个平台不做转换,真正做转换的是内部的插件 比如preset)

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

前端 自动化构建 入门及原理_第52张图片
成功
前端 自动化构建 入门及原理_第53张图片

Gulp 案例 - 页面模板编译

下载模板引擎转换插件 yarn add gulp-swig --dev
在这里插入图片描述
前端 自动化构建 入门及原理_第54张图片
html模板中 使用的数据 这个时候就需要配置选择进行填充了
准备数据
前端 自动化构建 入门及原理_第55张图片

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()
}

有了数据后 在swing中传递
在这里插入图片描述
启动 填充成功!
在这里插入图片描述
这三个任务不能一个一个运行因为耗时没有必要 需要同时运行

创建编译任务 利用之前说的串行和并行任务
导入
在这里插入图片描述
此时就不需要导出三个任务 导出 parallel即可
前端 自动化构建 入门及原理_第56张图片
yarn gulp compile
在这里插入图片描述

Gulp 案例 - 图片和字体文件转换

在这里插入图片描述
yarn add gulp-imagemin --dev
导入
添加代码
运行
前端 自动化构建 入门及原理_第57张图片
前端 自动化构建 入门及原理_第58张图片
压缩了多少都有显示
imagemin只会处理能压缩的文件(svg不能被压缩 需要其他插件 下面介绍)
字体SVG等也能压缩
前端 自动化构建 入门及原理_第59张图片

Gulp 案例 - 其他文件及文件清除

处理public目录
前端 自动化构建 入门及原理_第60张图片

自动清除dist文件

yarn add del --dev
在这里插入图片描述
导入
前端 自动化构建 入门及原理_第61张图片
在包装一下build执行顺序
导入 series
前端 自动化构建 入门及原理_第62张图片
前端 自动化构建 入门及原理_第63张图片

Gulp 案例 - 自动加载插件

由于插件会越来越多不利于管理,比如每次你都要导入require一下很麻烦,可以安装 下面的插件解决
在这里插入图片描述
yarn add gulp-load-plugins --dev
导入
前端 自动化构建 入门及原理_第64张图片

Gulp 案例 - 开发服务器

文件改动后自动更新页面
安装服务器(这个服务器可以监听文件,自动热更新)
在这里插入图片描述
yarn add browser-sync --dev
导入
在这里插入图片描述
把这个定义到任务中
前端 自动化构建 入门及原理_第65张图片
3运行 yarn gulp serve

网页可能样式会乱
因为我们只处理我们自己的代码,如下代码没有处理
前端 自动化构建 入门及原理_第66张图片
前端 自动化构建 入门及原理_第67张图片

前端 自动化构建 入门及原理_第68张图片
前端 自动化构建 入门及原理_第69张图片
重启serve,样式好 了
前端 自动化构建 入门及原理_第70张图片

取消启动提示
在这里插入图片描述
在这里插入图片描述
设置port在这里插入图片描述
是否自动打开在这里插入图片描述
指定监听文件 **表示所有文件
在这里插入图片描述

Gulp 案例 - 监视变化以及构建优化

导入 gulp api watch
在这里插入图片描述
前端 自动化构建 入门及原理_第71张图片
前端 自动化构建 入门及原理_第72张图片
这样就实现了源码修改后 同步到浏览器
试试 yarn gulp serve
(如果遇到不更新的问题可以用下面的方法)
前端 自动化构建 入门及原理_第73张图片
开发阶段不需要监视文件压缩等,这样会加大开销
可以这样配置
前端 自动化构建 入门及原理_第74张图片

先新增组合任务 因为可能有时候删了dist,这样serve就跑步起来了
前端 自动化构建 入门及原理_第75张图片
开发阶段主要用compile就行了
前端 自动化构建 入门及原理_第76张图片
yarn gulp develop试试效果

如果想图片字体改变了也重启的话
前端 自动化构建 入门及原理_第77张图片
这些文件改变后,bs会reload,浏览器会重新请求这样就能拿到最新的了。
方法2 如果只想监控某一方法然后reload的话,这里reload传参是以文件流的形式
前端 自动化构建 入门及原理_第78张图片
如果三个都加 那么 files就不需要了
前端 自动化构建 入门及原理_第79张图片

Gulp 案例 - useref 文件引用处理

走完上面基本就完成了,但是dist还是有点问题的
例如某些依赖其他文件夹的,并没有拷贝到dist目录,如果上线肯定找不到,本地可以是因为做了些配置路由映射
前端 自动化构建 入门及原理_第80张图片
针对上述问题处理,1.low的方法就是直接拷贝过去,2.是下面要介绍的插件

useref插件

被这些代码包括的会指定一个路径,也就是把包裹的文件打包到指定的文件目录,如果包裹多个会合并到一起,还会帮你自动压缩。
前端 自动化构建 入门及原理_第81张图片
安装插件
yarn add gulp-useref --dev
(useref = 引用关系)
添加一个方法
注意要文件生成过后才有效,不然你找模板html是没用的
前端 自动化构建 入门及原理_第82张图片
yarn gulp useref 运行!
新生成的就不和我们之前看到的一样了,把所有html里rel的css合并成一个文件了
前端 自动化构建 入门及原理_第83张图片
多个js也被合并到一个了
在这里插入图片描述
前端 自动化构建 入门及原理_第84张图片
前端 自动化构建 入门及原理_第85张图片
这个过程中,可以多添加几个操作,下面会介绍到

Gulp 案例 - 文件压缩

上面说了 开干
安装压缩插件
在这里插入图片描述
yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev
需要判断对不同文件的操作,这个时候就需要一个额外的插件去判断,yarn add gulp-if --dev

记得先删除之前的文件不然没效果
前端 自动化构建 入门及原理_第86张图片
如果没效果 看看你的dist index.html是不是没有那些包裹注释了
所以得先执行 compile 后执行 useref
记得上次才压缩 不然很慢

剩下的几个
前端 自动化构建 入门及原理_第87张图片
yarn gulp compile
yarn gulp useref
这个时候会发现 main.css没内容,这是因为文件读写冲突,一边读一边写。
解决方法》
把最终的转换结果放在其他目录
前端 自动化构建 入门及原理_第88张图片
这里发现html没压缩,html需要额外指定几个参数
前端 自动化构建 入门及原理_第89张图片

yarn gulp useref 搞定!
还可以指定html一些空属性,注释删除。

Gulp 案例 - 重新规划构建过程

因为之前的构建,现在上线前有多了一步useref,这么做就多余了,可以先放到temp目录,然后输出最终上线的dist
前端 自动化构建 入门及原理_第90张图片
下面这个三个不需要放到temp,因为这三个只需要build的时候去做
,只有被useref影响的才需要前端 自动化构建 入门及原理_第91张图片
serve修改一个
前端 自动化构建 入门及原理_第92张图片
useref 改俩个
前端 自动化构建 入门及原理_第93张图片

先删除之前生成的文件

前端 自动化构建 入门及原理_第94张图片
执行!
前端 自动化构建 入门及原理_第95张图片
运行试一下
前端 自动化构建 入门及原理_第96张图片

Gulp 案例 - 补充

接下来要解决俩个小问题
一般leader构建完了这套系统 会发给小弟,但是你不想写文档和说明怎么去用的话,你就导出几个常用的就行了
clean compile build develop导出就行了。这样就简介很多。
前端 自动化构建 入门及原理_第97张图片
第二步,在package中script中添加命令(因为会去node_module里找命令,这里就不需要run了)
前端 自动化构建 入门及原理_第98张图片
小试牛刀
在这里插入图片描述

下面会介绍如何提取多个项目构建化过程 共同的自动化构建过程。

-----------------------gulp结束分割线----------------------

封装工作流 - 准备

主要解决复用问题。这里主要讲解把刚刚做好的demo进行一个通用封装。

前端 自动化构建 入门及原理_第99张图片
前端 自动化构建 入门及原理_第100张图片
创建一个新仓库
创建新文件夹
下载脚手架
yarn global add zce-cli (我安装这个报错了 全局上找不到,到C:\Users\jack\AppData\Roaming\npm\node_modules 一看 确实没有)
npm i zce-cli -g 后 到C:\Users\jack\AppData\Roaming\npm\node_modules 有了
在这里插入图片描述
zce init nm zce-pages
在这里插入图片描述在这里插入图片描述

创建好后进入目录
在这里插入图片描述
设置git
在这里插入图片描述
git add .
git commit -m’init’

在这里插入图片描述-u的意思是以流的方式推
前端 自动化构建 入门及原理_第101张图片

封装工作流 - 提取 gulpfile

刚刚做的gulpdemo 这里叫A 刚刚提交仓库的通用文件叫B
把A的依赖复制到B
在之前的demo中打开刚刚这个项目 code . -a -a表示同一窗口打开
前端 自动化构建 入门及原理_第102张图片
1 把A的gulpfile 内容 复制到 B的index
2把A的devDependencies 复制到B的 Dependencies(因为这里的依赖一定会使用到)复制好后 在B yarn 一下 安装依赖

3 删除A项目的 node_module 3.1清空package中的devDependencies 和gulpfile

获得一个干净的项目
正常是先发布B 然后在A项目中使用,但现在是开发阶段,先link
前端 自动化构建 入门及原理_第103张图片
把zec-page项目link到全局,这样其他项目也可以使用了 npm link 因为这里用的是npm link 所有build的时候要npm build yarn build会报找不到模块
前端 自动化构建 入门及原理_第104张图片
回到A项目下 ,link后获得node_moudel的文件夹
前端 自动化构建 入门及原理_第105张图片
因为zec-pages项目导出的是gulpfile,在A项目的gulpfile引用就好了,然后因为之前删除了生产依赖 先yarn一下
前端 自动化构建 入门及原理_第106张图片

前端 自动化构建 入门及原理_第107张图片
yarn build
报错
在这里插入图片描述
因为现在新项目下的node_module没有bin/gulp命令
安装
yarn add gulp-cli --dev
在这里插入图片描述
又报错,找不到本地gulp
yarn add gulp --dev
前端 自动化构建 入门及原理_第108张图片
继续安装本地gulp
在这里插入图片描述
这些问题到后面发布后就不存在了,因为你下载B项目后会自动安装所有这些模块
继续报错
前端 自动化构建 入门及原理_第109张图片
而且这里的Data是需要抽出来的,不可能每个项目都需要这样结构的data,我们可以在A项目中创建配置文件,然后读取
前端 自动化构建 入门及原理_第110张图片
下面继续介绍怎么解决

封装工作流 - 解决模块中的问题

应该把那些不应该提取的东西抽掉,例如data
先在新项目创建一个js文件
把data放到里面导出
前端 自动化构建 入门及原理_第111张图片
在旧项目删除data,进行动态获取
前端 自动化构建 入门及原理_第112张图片
把下面方法的data都换成configdata,这里不能config.data 只能 data: config.data 只有page方法要换 因为只有html模板用这些数据
前端 自动化构建 入门及原理_第113张图片
回到新项目尝试运行
在这里插入图片描述
B项目的page中忘记添加bin了 bin的字段是整个项目的入口
在这里插入图片描述

这时又报另外的错误
在这里插入图片描述
新项目没有这个模块,解决》在旧项目对preset修改,require会自动去找一层一层地
前端 自动化构建 入门及原理_第114张图片
现在正常了
前端 自动化构建 入门及原理_第115张图片

封装工作流 - 抽象路径配置

对于代码里写死的路径例如下面的图,这样就不是很灵活了,现在我们进行自定义路径前端 自动化构建 入门及原理_第116张图片
配置
前端 自动化构建 入门及原理_第117张图片
替换
前端 自动化构建 入门及原理_第118张图片
完整代码

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 cwd = process.cwd()
let config = {
  // default 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: 'assets/fonts/**'
    }
  }
}

try {
  const loadConfig = require(`${cwd}/pages.config.js`)
  config = Object.assign({}, config, loadConfig)
} catch (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(plugins.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 serve = () => {
  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)
  // 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: 2080,
    // open: false,
    // files: 'dist/**',
    server: {
      baseDir: [config.build.temp, config.build.dist, config.build.public],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

const useref = () => {
  return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
    .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] }))
    // html js css
    .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(config.build.dist))
}

const compile = parallel(style, script, page)

// 上线之前执行的任务
const build =  series(
  clean,
  parallel(
    series(compile, useref),
    image,
    font,
    extra
  )
)

const develop = series(compile, serve)

module.exports = {
  clean,
  build,
  develop
}


yarn build 试试
然后把这个配置复制到新项目中
前端 自动化构建 入门及原理_第119张图片
抽象完毕

封装工作流 - 包装 Gulp CLI

如何去掉gulpfile(这样每次就不用手动导出了,直接放在B项目里面使用就可以了,达到完全封装)
删除后 无法使用了 如图下
前端 自动化构建 入门及原理_第120张图片
可以指定gulpfile,其实在这个新项目的node_module下这个index就是gulpfile

前端 自动化构建 入门及原理_第121张图片
指定方法
在这里插入图片描述
前端 自动化构建 入门及原理_第122张图片
但是这样也有问题,工作目录不是本目录了,需要指定一下
在这里插入图片描述
不过这样这么多参数就很复杂了

解决:集成cli
新建cli目录
2package中添加bin
前端 自动化构建 入门及原理_第123张图片
继续配置入口文件
前端 自动化构建 入门及原理_第124张图片

写完去新项目做个测试
先重新link一下,这样才能注册到全局
在这里插入图片描述
添加gulp命令
前端 自动化构建 入门及原理_第125张图片
开始传递参数
前端 自动化构建 入门及原理_第126张图片
前端 自动化构建 入门及原理_第127张图片
前端 自动化构建 入门及原理_第128张图片

前端 自动化构建 入门及原理_第129张图片

执行成功

封装工作流 - 发布并使用模块

发布前先添加文件,file中的目录会发布到npm中
前端 自动化构建 入门及原理_第130张图片
yarn publish 之前先提交git

yarn publish
前端 自动化构建 入门及原理_第131张图片
如果不想改镜像源,添加一个参数即可
yarn publish --registry=https://registry.yarnpkg.com
在这里插入图片描述
publish到yarn的镜像源

上传成功
前端 自动化构建 入门及原理_第132张图片

新建目录测试

先zce-pages复制几个文件过来
在这里插入图片描述
在这里插入图片描述
运行!
可能会有同步问题,因为你发布的是npm源,你下载是从淘宝源,可能会存在同步问题,如果有下面有解决方式
登录淘宝镜像,搜你publish的包 然后更新
前端 自动化构建 入门及原理_第133张图片
安装完后 node_module下有个bin目录,下面应该有这个
前端 自动化构建 入门及原理_第134张图片
运行试试在这里插入图片描述
添加script方便后续操作
前端 自动化构建 入门及原理_第135张图片

封装工作流 - 总结

前端 自动化构建 入门及原理_第136张图片
前端 自动化构建 入门及原理_第137张图片
前端 自动化构建 入门及原理_第138张图片
然后执行 在这里插入图片描述

FIS 的基本使用

了解即可
可以根据淘宝镜像源推断是否主力
前端 自动化构建 入门及原理_第139张图片

FIS 编译与压缩

了解即可

你可能感兴趣的:(拉钩大前端,前端工程化)