前端 DevOps 实施

前端 DevOps 实施

前端 DevOps 实施流程和规范构建流程发布规范使用:https://github.com/conventional-changelog/standard-version

standard-version will then do the following:

Retrieve the current version of your repository by looking at packageFiles, falling back to the last git tag.bump the version in bumpFiles based on your commits.Generates a changelog based on your commits (uses conventional-changelog under the hood).Creates a new commit including your bumpFiles and updated CHANGELOG.Creates a new tag with the new version number.CHANGELOGhttps://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-cli

$ npm install -g conventional-changelog-cli

$ cd my-project

$ conventional-changelog -p angular -i CHANGELOG.md -s规范自动化editorconfig,帮助开发人员定义和维护跨编辑器(或IDE)的统一的代码风格prettier,一个强势武断的代码格式化工具。husky,一个用于 Node.js 项目的快速安装 git hooks 的工具。lint-staged,在 git staged 阶段,执行各种 Linter 的工具。converntional-changelog,根据 Git 提交历史生成 CHANGELOG 的工具。commitLint, 对提交信息进行 Lint 的工具。styleLint,对 CSS 进行 Lint 的工具。remark-lint,使用 Remark 对 Markdown 进行 Lint基于 Husky + LintStaged流程:

待提交的代码 git add 添加到暂存区;执行 git commit;注册到 git 钩子函数的 husky pre-commit 脚本被调用,执行 lint-staged;修改的文件依次执行 lint-staged 定义的任务;lint 失败,则需要等待修复;lint 成功,而执行 commit同理,对于 pre-push 也是如此。代码规范Google JavaScript 规范:Google JavaScript Style Guide , 中文翻译:Google JavaScript 代码风格指南Airbnb JavaScript 规范:Airbnb JavaScript Style Guide() {JavaScript Standard 规范:JavaScript 代码规范,自带 linter & 代码自动修正自定义 LintStyleLint 相关相关的库:

标准:https://github.com/stylelint/stylelint-config-standard ,包含可能报错的 rule,code format 的 css 标准推荐:https://github.com/stylelint/stylelint-config-recommended , 继承于 recommend,包含了一些常见的css书写标准,启用其他规则以强制执行一些 CSS 样式指南中的通用样式约定,包括:The Idiomatic CSS Principles,Google 的 CSS 样式指南,Airbnb 的样式指南和 @mdo 的代码指南。ESLint 示例相关的库:

整合 SonarReact 示例module.exports = {

parser: 'babel-eslint',

extends: ['airbnb', 'prettier', 'plugin:compat/recommended'],

env: {

browser: true,

node: true,

es6: true,

mocha: true,

jest: true,

jasmine: true,

},

globals: {

ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。

page: true,

},

rules: {

'react/jsx-filename-extension': [1, { extensions: ['.js'] }],

'react/jsx-wrap-multilines': 0,

'react/prop-types': 0,

'react/forbid-prop-types': 0,

'react/jsx-one-expression-per-line': 0,

'import/no-unresolved': [2, { ignore: ['^@/', '^umi/'] }],

'import/no-extraneous-dependencies': [

2,

{

optionalDependencies: true,

devDependencies: ['**/tests/**.js', '/mock/**/**.js', '**/**.test.js'],

},

],

'import/no-cycle': 0,

'jsx-a11y/no-noninteractive-element-interactions': 0,

'jsx-a11y/click-events-have-key-events': 0,

'jsx-a11y/no-static-element-interactions': 0,

'jsx-a11y/anchor-is-valid': 0,

'linebreak-style': 0,

'jsx-a11y/media-has-caption': 0,

'react/no-array-index-key': 0,

},

settings: {

polyfills: ['fetch', 'Promise', 'Number.isNaN', 'Object.assign', 'Object.entries', 'URL'],

},

}https://eslint.org/https://github.com/ElemeFE/eslint-config-elemefehttps://github.com/AlloyTeam/eslint-config-alloyhttps://github.com/vuejs/eslint-plugin-vuehttps://github.com/yannickcr/eslint-plugin-reacthttps://github.com/typescript-eslint/typescript-eslintundefinedhttps://github.com/SonarSource/eslint-plugin-sonarjshttps://github.com/racodond/sonar-css-pluginundefinedundefinedVue 示例module.exports = {

root: true,

env: {

browser: true,

node: true,

},

extends: [

'eslint:recommended',

'plugin:vue/recommended',

'plugin:import/recommended',

process.env.CI ? '' : 'plugin:prettier/recommended',

'prettier',

'prettier/vue',

],

rules: {

eqeqeq: [

'error',

'always',

{

null: 'ignore',

},

],

'consistent-return': "error",

'import/no-unresolved': 'off',

'import/first': 'error',

'import/order': [

'error',

{

'newlines-between': 'always-and-inside-groups',

},

],

'import/newline-after-import': 'error',

'import/no-duplicates': 'error',

},

parserOptions: {

parser: 'babel-eslint',

ecmaVersion: 2018,

sourceType: 'module',

},

overrides: [

{

files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.{j,t}s?(x)'],

env: {

jest: true,

},

},

],

globals: {

QC: false,

},

noInlineConfig: true,

}TypeScript 示例module.exports = {

root: true,

env: {

browser: true,

node: true,

},

extends: [

'eslint:recommended',

'plugin:vue/recommended',

// 'plugin:import/recommended',

'@vue/typescript/recommended',

// '@vue/prettier',

// '@vue/prettier/@typescript-eslint',

],

rules: {

'eqeqeq': [

'error',

'always',

{

null: 'ignore',

},

],

// Best Practices

// 'array-callback-return': 'error',

// 'class-methods-use-this': 'error',

'complexity': ['error', 50],

'curly': 'error',

'consistent-return': 'error',

'eqeqeq': ['error', 'always', { null: 'ignore' }],

'no-else-return': 'error',

'no-extend-native': 'error',

'no-implicit-coercion': 'error',

'no-sequences': 'error',

'no-throw-literal': 'error',

'no-useless-return': 'error',

'no-void': 'error',

'prefer-promise-reject-errors': 'error',

// 'radix': 'error',

'yoda': 'error',

// End of 'Best Practices'

// Stylistic

'array-bracket-newline': ['error', 'consistent'],

'array-bracket-spacing': 'error',

'comma-dangle': ["error", {

"arrays": "always-multiline",

"objects": "always-multiline",

"imports": "always-multiline",

"exports": "always-multiline",

"functions": "never"

}],

'eol-last': 'error',

// End of 'Stylistic'

// 'import/no-unresolved': 'off',

// 'import/first': 'error',

// 'import/order': [

// 'error',

// {

// 'newlines-between': 'always-and-inside-groups',

// },

// ],

// 'import/newline-after-import': 'error',

// 'import/no-duplicates': 'error',

'vue/no-v-html': 'off',

'@typescript-eslint/camelcase': 'off',

'@typescript-eslint/no-use-before-define': 'off',

'@typescript-eslint/no-empty-function': 'off',

'@typescript-eslint/no-this-alias': 'off',

'@typescript-eslint/no-explicit-any': 'warn',

'@typescript-eslint/no-non-null-assertion': 'off',

'indent': 'off',

'@typescript-eslint/indent': ['error', 2],

'semi': 'off',

'@typescript-eslint/semi': ['error', 'never'],

'quotes': 'off',

'@typescript-eslint/quotes': ['error', 'single'],

},

parserOptions: {

parser: '@typescript-eslint/parser',

},

overrides: [

{

files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.{j,t}s?(x)'],

env: {

jest: true,

},

},

{

files: ['vue.config.js'],

rules: {

'@typescript-eslint/no-var-requires': 'off',

},

},

],

globals: {

QC: false,

},

noInlineConfig: true,

}前端测试通用 BDDxCucumberGaugeRobot编程语言支持Java,Ruby,JavaScript 等 13 种语言Java, JavaScript, Ruby 等 6 种语言Python, Java, C支持的系统所有主流系统所有主流系统所有主流系统多语言支持UTF-8UTF-8用户关键字及用例层面支持 UTF-8中文社区支持完善待完善完善ReportJS 不支持 HTML粗粒度细粒度失败时截图不支持支持支持Angular自带

Unit: JasmineE2E: ProtractorVuevue add @vue/unit-jest单元测试(UT)Vue CLI 拥有开箱即用的通过 Jest 或 Mocha 进行单元测试的内置选项。我们还有官方的 Vue Test Utils 提供更多详细的指引和自定义设置。快照测试DOM SnapshotsJest: https://jestjs.io/docs/zh-Hans/next/snapshot-testing

describe('TodoItem snapshot test', () => {

it('first render', () => {

const wrapper = shallowMount(TodoItem, {

propsData: {

item: {

finished: true,

content: 'test TodoItem',

},

},

});

expect(wrapper.html()).toMatchSnapshot();

});

});示例结果:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `

className="normal"

href="http://www.facebook.com"

onMouseEnter={[Function]}

onMouseLeave={[Function]}

>

Facebook

`;Visual SnapshotsWraith is a screenshot comparison tool, created by developers at BBC News.Hermione is a utility for integration testing of web pages using WebdriverIO v4 and Mocha.Differencify is a library for visual regression testing via comparing your local changes with reference screenshots of your website.更多工具:关于前端测试

E2E 测试TestCafeCucumber.jsNightwatchPuppeteerCypressTestCafenpm install -g testcafeimport { Selector } from 'testcafe';

fixture`Getting Started`.page`http://devexpress.github.io/testcafe/example`;

test('My first test', async (t) => {

await t.typeText('#developer-name', 'John Smith').click('#submit-button');

});NightwatchInstall -> Installation

module.exports = {

'Demo test ecosia.org': function (browser) {

browser

.url('https://www.ecosia.org/')

.waitForElementVisible('body')

.assert.titleContains('Ecosia')

.assert.visible('input[type=search]')

.setValue('input[type=search]', 'nightwatch')

.assert.visible('button[type=submit]')

.click('button[type=submit]')

.assert.containsText('.mainline-results', 'Nightwatch.js')

.end();

},

};Puppeteernpm i puppeteerconst puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch();

const page = await browser.newPage();

await page.goto('https://example.com');

await page.screenshot({ path: 'example.png' });

await browser.close();

})();Cucumber.jsyarn add -D chai@latest cucumber@latest

npm i -D chai@latest cucumber@latestSteps

# features/simple_math.feature

Feature: Simple maths

In order to do maths

As a developer

I want to increment variables

Scenario: easy maths

Given a variable set to 1

When I increment the variable by 1

Then the variable should contain 2

Scenario Outline: much more complex stuff

Given a variable set to

When I increment the variable by

Then the variable should contain

Examples:

| var | increment | result |

| 100 | 5 | 105 |

| 99 | 1234 | 1333 |

| 12 | 5 | 17 |// features/support/steps.js

const { Given, When, Then } = require('cucumber');

const { expect } = require('chai');

Given('a variable set to {int}', function (number) {

this.setTo(number);

});

When('I increment the variable by {int}', function (number) {

this.incrementBy(number);

});

Then('the variable should contain {int}', function (number) {

expect(this.variable).to.eql(number);

});Cypressnpm install cypress示例:

describe('My First Test', () => {

it('clicking "type" navigates to a new url', () => {

cy.visit('https://example.cypress.io');

cy.contains('type').click();

// Should be on a new URL which includes '/commands/actions'

cy.url().should('include', '/commands/actions');

});

});前端架构拆分方式:

微应用化微前端:微前端微前端架构是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。

由此带来的变化是,这些前端应用可以独立运行、独立开发、独立部署。以及,它们应该可以在共享组件的同时进行并行开发——这些组件可以通过 NPM 或者 Git Tag、Git Submodule 来管理。详细:微前端如何落地

微应用化微应用化与微前端架构相当的类似,它们在开发时都是独立应用,在构建时又可以按照需求单独加载。如果以微前端的单独开发、单独部署、运行时聚合的基本思想来看,微应用化就是微前端的一种实践。只是使用微应用化意味着:我们只能使用唯一的一种前端框架。如果从框架不限的角度来定义,怕是离微前端有些远,不过大团队怕是不会想同时支持多个前端框架。详细见:微前端:微应用化

前端监控参考来源:《前端如何搞监控总结篇》

相关内容

详细步骤教你如何安装米聊
365bet登录

详细步骤教你如何安装米聊

⌚ 08-11 👁️‍🗨️ 680
苹果a1549价格
365bet登录

苹果a1549价格

⌚ 07-04 👁️‍🗨️ 1894

友情链接