什么是持续集成?
DevOps 是一种软件开发方法。它将持续开发、持续测试、持续集成、持续部署和持续监控贯穿于软件开发的整个生命周期。
CI 代表持续集成(Continuous Integration),CD 代表持续交付(Continuous Delivery)和持续部署(Continuous Deployment)。也可以将它们看作是类似于软件开发生命周期的过程。
- 在CI环境中,开发人员将会频繁地向主干提交代码。这些新提交的代码在最终合并到主干前,需要经过编译和自动化测试(通常是单元测试和集成测试)流进行验证。
- 在CD环境中,通过自动化的构建、测试和部署循环来快速交付高质量的产品。某种程度上代表了一个开发团队工程化的程度,任何修改通过了所有已有的工作流就会直接和客户见面,只有当一个修改在工作流中构建失败才能阻止它部署到产品线。
- 持续交付的英文全称是:Continuous delivery,缩写也是CD,它是一种软件工程手法。它可以让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以释出的状况。它的目标在于让软件的建置、测试与释出变得更快以及更频繁。这种方式可以减少软件开发的成本与时间,减少风险。
自动化构建工具,编译、部署、测试、监控、本机开发上线环境。
FIS3/Webpack/jdists/package.json/chai/supertest/mocha/selenium-webdriver
持续集成平台。 Jenkins、Travis CI、Buddy
部署工具。 rsync、shelljs、yargs
实践参考《如何从零开始搭建 CI/CD 流水线》
什么是统一代码仓库多分支开发?
master
分支上保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。 他们还有一些名为 develop
或者 next
的平行分支,被用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master
分支了。
Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0
、 v2.0
等等)。
一个可发布版本提交到git
仓库的🌰
var shell = require('shelljs');
//判定git命令是否可用
if (!shell.which('git')) {
//向命令行打印git命令不可用的提示信息
shell.echo('Sorry, this script requires git');
//退出当前进程
shell.exit(1);
}
//先删除'out/Release'目录
shell.rm('-rf', 'out/Release');
//拷贝文件到'out/Release'目录
shell.cp('-R', 'stuff/', 'out/Release');
//切换当前工作目录到'lib'
shell.cd('lib');
//shell.ls('*.js')返回值是一个包含所有js文件路径的数组
shell.ls('*.js').forEach(function(file) {//遍历数组
//sed命令用于文件内容的替换,这里是对每个文件都执行如下3步操作,更改版本信息
shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), file);
});
//切换当前工作目录到上一层
shell.cd('..');
//同步执行git命令提交代码
if (shell.exec('git commit -am "Auto-commit"').code !== 0) {
shell.echo('Error: Git commit failed');
shell.exit(1);
}
什么是前端工程化?
前端模块化(模块管理、资源加载)
模块化的工程意义首先在于分治的思想,对功能进行分治,有利于我们的维护;其次是复用,有利于我们的开发。
分而治之:将一个大问题分解成多个较为独立的与原问题性质相同的小问题,将所有的小问题的解答组合起来即可得到大问题的答案。
AMD (Asynchronous Module Definition,异步模块定义)。 AMD提倡依赖前置,在定义模块的时候就要声明其依赖的模块。实践requirejs
define(['dep1','dep2'],function(dep1,dep2){
//内部只能使⽤用指定的模块
return function(){};
});
CMD (Common Module Definition,通用模块定义)。CMD提倡就近依赖(按需加载)。实践SeaJS
define(function(require,exports,module){
//此处如果需要加载某XX模块,可以引⼊入
var xx=require(‘XX’);
});
CommomJS规范。通过require,module.exports,exports来进行导入和导出,这里exports是module.exports的一个引用。
ES6 import export/export default
关于webpack:
1.Webpack执行CommonJS标准,解决了依赖配置和请求流量。
2.对于Webpack来讲万物都可以是模块,所有的文件都被合并到JS中,最终在浏览器。
3.兼容AMD与CMD。
4.JS模块化不仅仅为了提高代码复用性,更是为了让资源文件更合理地进行缓存。
前端开发组件化。
1.每一个前端模块都是一个小项目,配合mock.js可以进行本地的开发测试,package.json是标配产物。经过webpack的环境配置统一进行本地环境、上线环境的编译过程。
2.由page组装widget,由widget组装WebComponents(X-TAG)。
3.能够根据路由快速抉择配置SPA或者直出。
Web Components 是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们。
Custom Elements, 提供一种方式让开发者可以⾃定义 HTML 元素,包括特定的组成,样式和行为。
class ButtonHelloElement extends HTMLButtonElement {
constructor() {
super()
this.addEventListener('click', () => {
alert('hello world')
})
}
}
customElements.define('button-hello', ButtonHelloElement, { extends: 'button' })
HTML Templates, 用过 handlebars 的人都知道有这么一个东西:。那么 HTML Templates 便是把这个东西官⽅标准化,提供了一个 template 标签来存放以后需要但是暂时不渲染的 HTML 代码。
<template id="template">
<p>Smile!</p>
</template>
<script>
let num = 3;
const fragment =document.getElementById('template').content.cloneNode(true);
while (num-- > 1) {
fragment.firstChild.before(fragment.firstChild.cloneNode(true));
fragment.firstChild.textContent += fragment.lastChild.textContent;
}
document.body.appendChild(fragment);
</script>
Shadow DOM 最本质的需求是需要一个隔离组件代码作用域的东西,例如我组件代码的 CSS 不能影响其他组件之类的,而iframe ⼜太重并且可能有各种奇怪问题。旨在提供⼀种更好地组织⻚面元素的方式,来为日趋复杂的⻚面应用提供强大支持,避免代码间的相互影响。
<div id="app"></div>
<script>
const div = document.getElementById('app')
const shadowRoot = div.createShadowRoot()
const span = document.createElement('span')
span.textContent = 'hello world'
shadowRoot.appendChild(span)
</script>
HTML Imports 旨在成为 Web Components 的打包机制,但也可以单独使用 HTML Imports。
自动化编译
在前端开发中,我们总是会去使用很多工具、手段来优化代码、提升开发效率,例如,我们会使用sass、less等CSS预处理工具来编写更好维护的样式代码,我们也会使用CSSLint、eslint等代码检查工具来检查代码的语法错误,使用文件合并压缩等手段来减少资源大小,除此之外我们还会去做雪碧图合并、多倍图处理、字体压缩处理、代码发布等等。自动化编译流程:
foo.es -> require(‘foo.scss’) -> background:url(foo.png)
-> 读入foo.es的文件内容,编译成js内容
-> 分析js内容,找到资源定位标记 ‘foo.scss’
-> 对foo.scss进行编译:
-> 读入foo.scss的文件内容,编译成css内容
-> 分析css内容,找到资源定位标记 url(foo.png)
-> 对 foo.png 进行编译:
-> 读入foo.png的内容
-> 图片压缩
-> 返回图片内容
-> 根据foo.png的最终内容计算md5戳,替换url(foo.png)为url(/static/img/foo_2af0b.png)
-> 替换完毕所有资源定位标记,对css内容进行压缩
-> 返回css内容
-> 根据foo.css的最终内容计算md5戳,替换’foo.scss’为 ‘/static/scss/foo_bae39.css’
-> 替换完毕所有资源定位标记,对js内容进行压缩
-> 返回js内容
-> 根据最终的js内容计算md5戳,得到foo.coffee的资源url为 ‘/static/scripts/foo_3fc20.js’
静态资源管理(静态资源版本更新与缓存)
1.配置超长时间的本地缓存 — 节省带宽,提高性能
2.采用内容摘要作为缓存更新依据— 精确的缓存控制
3.静态资源CDN部署—— 优化网络请求
4.更资源发布路径实现非覆盖式发布 — 平滑升级
1.FIS3根据分析好的文件包,利用HOOK插件//分析下FIS的生成的配置文件
FIS3 是面向前端的工程构建工具。解决前端工程中性能优化、资源加载(异步、同步、按需、预加载、依赖管理、合并、内嵌)、模块化开发、自动化工具、开发规范、代码部署等问题。
2.Webpack在开发阶段打包,利用插件分析处直接提取。FileLoader&&extract-textwebpack-plugin。
3.配置publicpath分发到CDN.
什么是自动化构建?
发布npm包
1.添加用户: npm adduser
2.登录用户: npm login
3.升级补丁版本号:npm version patch
4.升级小版本号:npm version minor
5.升级大版本号:npm version major
6.发布版本:npm publish
更多自动化!
1.自动化运营平台
2.自动化雪碧图
3.自动化离线打包
4.自动化控制缓存级别
5.自动化处理Inline
6.自动化根据网速分发版本资源
7.自动化运维平台
END 2020-5-1