自动化构建学习笔记

通过工程化提升战斗力

工程化主要解决的问题
传统语言或语法的弊端
无法使用模块化、组件化
重复的机械式工作
代码风格统一、质量保证
依赖后端服务接口支持
整体依赖后端项目
一切重复的工作都应该被自动化
创建项目 => 编码 => 预览/测试 => 提交 => 部署

工程化不等于工具
一些成熟的工程化集成

create-react-app
vue-cli
angular-cli
gatsby-cli
脚手架工具
前端工程化的发起者

脚手架工具的本质作用:创建项目基础结构、提供项目规范和约定。

相同的组织结构
相同的开发范式
相同的模块依赖
相同的工具配置
相同的基础代码
常用的脚手架工具
React 项目 -> create-react-app
Vue 项目 -> vue-cli
Angular 项目 -> angular-cli
它们可以根据信息创建对应的项目基础结构

Yeoman: 一款通用型脚手架工具,创建项目时,可以根据模板生成对应的项目结构,很灵活、易于扩展

Plop: 用于在开发过程中,创建一些特定类型的文件

Yeoman
Yeoman 基础使用
在全局范围安装 yo
$ npm install yo --global # or yarn global add yo

安装对应的 generator
$ npm install generator-node --global # or yarn global add generator-node

通过 yo 运行 generator
$ cd path/project-dir
$ mkdir my-module
$ cd my-module
$ yo node
Yeoman 使用步骤总结
明确你的需求;
找到合适的 Generator;
全局范围安装找到的 Generator;
通过 Yo 运行对应的 Generator;
通过命令行交互填写选项;
生成你所需要的项目结构;
自定义 Generator
Generator 基本结构

├── generators/ ·········································· 生成器目录
│ ├── app/ ············································· 默认生成器目录
│ | └── index.js ···································· 默认生成器实现
| └── component/ ······································· 其他生成器目录
│ └── index.js ···································· 其他生成器实现
└── package.json ········································· 模块包配置文件
自定义 Generator 的详细操作步骤:

1.创建 generator 文件目录

$ mkdir generator-lxc-test
$ cd generator-lxc-test
2.给项目初始化一个 package.json
$ npm init -yes # or yarn init -yes

3.安装 yeoman 依赖
$ yarn add yeoman-generator

4.新建 generator 入口文件
$ code generators/app/index.js

// 此文件作为 Generator 的核心入口
// 需要导出一个继承自 Yeoman Generator 的类型
// Yeoman Generator 在工作时会自动调用我们在此类型中定义的一些生命周期方法
// 我们在这些方法中可以通过调用父类提供的一些工具方法实现一些功能,例如文件写入

const Generator = require(‘yeoman-generator’);

module.exports = class extends Generator {
prompting () {
return this.prompt([
{
type: ‘input’,
name: ‘name’,
message: ‘Your project name’,
default: this.appname // appname 为项目生成的目录名称
}
])
.then(answers => {
// answers => { name: ‘user input value’ }
this.answers = answers;
});
}
// Yeoman 自动在生成文件阶段调用此方法
// 我们这里尝试往项目中写入文件
writing () {
this.fs.write(
this.destinationPath(‘temp.txt’),
Math.random().toString()
)
}
}
5.如果使用到模板,需要在 app 目录下新建 templates 目录存放模板文件,使用 EJS 语法写入变量

这是一个模板文件
内部可以使用 EJS 模板标记输出数据
例如:<%= title %>

其他的 EJS 语法也支持

<% if (success) { %>
哈哈哈
<% }%>
6.完成 index.js 后,将我们创建的 generator 链接到全局,在 generator-lxc-test 目录下执行:
$ yarn link

7.使用我们创建好的 generator

$ cd path/project-dir
$ mkdir my-test-proj
$ cd my-test-proj
$ yo lxc-test
Plop
一个小而美的脚手架工具,一般用于创建项目中特定类型文件的小工具;
可以大大提高我们在项目中创建重复文件的效率;
一般不会独立使用,会集成到项目中,自动化的创建同类型的文件;
Plop 的基本使用
1.安装 plop
$ yarn add plop --dev

2.在项目根目录下创建模板文件 plop-templates/component.hbs

{{name}} Component

3.在项目根目录下创建 plop 入口文件 plopfile.js

// plopfile.js
// Plop 入口文件,需要导出一个函数
// 此函数接收一个 plop 对象,用于创建生成器任务
module.exports = plop => {
plop.setGenerator(‘component’, {
description: ‘create a component’,
prompts: [
{
type: ‘input’,
name: ‘name’,
message: ‘component name’,
default: ‘MyComponent’
}
],
actions: [
{
type: ‘add’, // add 代表添加文件
path: ‘src/components/{{name}}/{{name}}.vue’,
templateFile: ‘plop-templates/component.hbs’
}
]
})
}
4.利用我们刚刚注册的生成器的名字启动 plop
$ yarn plop component

自动化构建
一切重复工作本应自动化

源代码 => 自动化构建 => 生产代码

自动化构建工作流

作用:脱离运行环境兼容带来的问题
使用提高效率的语法、规范和标准

ECMAScript Next
Sass
模板引擎
构建转换那些不被支持的特性
自动化构建初体验
利用 package.json 中的 script 属性,配置一些简单的自动构建命令

“scripts”: {
“build”: “sass scss/main.scss css/style.css --watch”,
“serve”: “browser-sync . --files “css/*.css””,
“start”: “run-p build serve”
},
常用的自动化构建工具
Grunt ,最早的前端构建系统,工作过程是基于临时文件实现的,所以构建速度相对较慢,插件生态非常完善
Gulp ,构建是基于内存实现的,支持同时执行多个任务,效率较高,使用方式更直观易懂,插件生态也很完善
FIS ,百度的前端团队推出的前端构建系统,相当于捆绑套餐,将一些典型的需求都集成在内部
Grunt 的使用
Grunt 的基本使用
先要安装 grunt ,yarn add grunt
在项目根目录创建 Grunt 的入口文件 gruntfile.js
用于定义一些需要 Grunt 自动执行的任务
需要导出一个函数
此函数接收一个 grunt 的形参,内部提供一些创建任务时可以用到的 API
// gruntfile.js
module.exports = grunt => {
grunt.registerTask(‘foo’, () => {
console.log(‘hello grunt~’);
});

grunt.registerTask('bar', '任务描述', () => {
    console.log('other task~');
});

grunt.registerTask('default', ['foo', 'bar']);

// 执行异步任务
grunt.registerTask('async-task', function () {
    const done = this.async();
    setTimeout(() => {
        console.log('async task working~');
        done();
    }, 3000);
});

}
Grunt 标记任务失败
在 registerTask 第二个参数,也就是回调函数里 return false 即可
处理多个任务,其中一个任务失败的情况,可以用 --force 命令强制执行所有任务
异步任务,标记失败的处理:const done = this.async(); … done(false);
Grunt 的配置方法
使用 grunt.initConfig() 这个方法进行配置
在 registerTask 第二个参数,也就是回调函数里通过 grunt.config(‘foo’) 获取配置
module.exports = grunt => {
grunt.initConfig({
// foo: ‘bar’
foo: {
bar: 123
}
});
grunt.registerTask(‘foo’, () => {
// const foo = grunt.config(‘foo’);
// console.log(foo); // bar
const bar = grunt.config(‘foo.bar’);
console.log(bar); // 123
});
}
Grunt 多目标任务
多目标模式,可以让任务根据配置形成多个子任务
通过 grunt.registerMultiTask(‘build’, function () {}) 执行多任务
通过 grunt.initConfig({ build: {…} }) 配置多个子任务
Grunt 插件的使用
先下载相关插件 yarn add grunt-contrib-clean
通过 grunt.loadNpmTasks(‘grunt-contrib-clean’) 导入插件
通过 grunt.initConfig() 配置插件
module.exports = grunt => {
grunt.initConfig({
clean: {
// temp: ‘temp/app.js’
// temp: ‘temp/*.txt’
temp: ‘temp/**’
}
});
grunt.loadNpmTasks(‘grunt-contrib-clean’);
}
Grunt 常用插件介绍
yarn init -yes
yarn add grunt grunt-sass sass --dev
创建 gruntfile.js 文件
yarn grunt sass

yarn add grunt-babel @babel/core @babel/preset-env --dev
yarn add load-grunt-tasks --dev

Gulp 的使用
Gulp 的基本使用
yarn init -yes
yarn add gulp
创建 gulpfile.js 文件
yarn gulp my-task 执行指定任务
yarn gulp 执行默认的 default 任务

// gulpfile.js gulp 的入口文件

exports.foo = done => {
console.log(‘foo task working~’);
done(); // 标识任务完成
}
exports.default = done => {
console.log(‘default task working~’);
done();
}

// gulp 4.0 版本之前,创建任务的方式
const gulp = require(‘gulp’);
gulp.task(‘bar’, done => {
console.log(‘bar working~’);
done();
});
Gulp 的组合任务
const { series, parallel } = require(‘gulp’);
const task1 = done => {
setTimeout(() => {
console.log(‘task1 working~’);
done();
}, 1000);
}
// …
// 创建串行任务
exports.foo = series(task1, task2, task3);

// 创建并行任务
exports.bar = parallel(task1, task2, task3);
Gulp 的异步任务
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~’);
}

// 处理文件流
const fs = require(‘fs’);
exports.stream = done => {
const readStream = fs.createReadStream(‘package.json’);
const writeStream = fs.createWriteStream(‘temp.txt’);
readStream.pipe(writeStream);
readStream.on(‘end’, () => {
done();
});
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值