standard-version
will then do the following:
packageFiles
, falling back to the last git tag
.bump
the version in bumpFiles
based on your commits.changelog
based on your commits (uses conventional-changelog under the hood).commit
including your bumpFiles
and updated CHANGELOG.tag
with the new version number.https://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
流程:
git add
添加到暂存区;git commit
;pre-commit
脚本被调用,执行 lint-staged
;pre-push
也是如此。相关的库:
相关的库:
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'],
},
}
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,
}
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,
}
x | Cucumber | Gauge | Robot |
---|---|---|---|
编程语言支持 | Java,Ruby,JavaScript 等 13 种语言 | Java, JavaScript, Ruby 等 6 种语言 | Python, Java, C |
支持的系统 | 所有主流系统 | 所有主流系统 | 所有主流系统 |
多语言支持 | UTF-8 | UTF-8 | 用户关键字及用例层面支持 UTF-8 |
中文社区支持 | 完善 | 待完善 | 完善 |
Report | JS 不支持 HTML | 粗粒度 | 细粒度 |
失败时截图 | 不支持 | 支持 | 支持 |
自带
vue add @vue/unit-jest
Vue CLI 拥有开箱即用的通过 Jest 或 Mocha 进行单元测试的内置选项。我们还有官方的 Vue Test Utils 提供更多详细的指引和自定义设置。
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`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Facebook
</a>
`;
更多工具:关于前端测试
npm install -g testcafe
import { 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');
});
Install -> 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();
},
};
npm i puppeteer
const 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();
})();
yarn add -D chai@latest cucumber@latest
npm i -D chai@latest cucumber@latest
Steps
# 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);
});
npm 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 来管理。
详细:微前端如何落地
微应用化与微前端架构相当的类似,它们在开发时都是独立应用,在构建时又可以按照需求单独加载。如果以微前端的单独开发、单独部署、运行时聚合的基本思想来看,微应用化就是微前端的一种实践。只是使用微应用化意味着:我们只能使用唯一的一种前端框架。如果从框架不限的角度来定义,怕是离微前端有些远,不过大团队怕是不会想同时支持多个前端框架。
详细见:微前端:微应用化
参考来源:《前端如何搞监控总结篇》