Skip to content

Commit e18290b

Browse files
committed
feat: add codelint, tests, githook
1 parent 18fdb76 commit e18290b

20 files changed

+3214
-149
lines changed

.commitlintrc.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
extends: ["@commitlint/config-conventional"]
3+
}

.eslintignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
*.sh
2+
node_modules
3+
*.md
4+
*.woff
5+
*.ttf
6+
.vscode
7+
.idea
8+
dist
9+
/public
10+
/docs
11+
.husky
12+
.local
13+
/bin

.eslintrc.cjs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports = {
2+
env: {
3+
browser: true,
4+
es2021: true,
5+
commonjs: true,
6+
node: true
7+
},
8+
extends: [
9+
'eslint:recommended',
10+
'plugin:vue/vue3-essential',
11+
'plugin:@typescript-eslint/recommended',
12+
'plugin:prettier/recommended'
13+
],
14+
overrides: [],
15+
parser: 'vue-eslint-parser',
16+
parserOptions: {
17+
ecmaVersion: 'latest',
18+
sourceType: 'module',
19+
parser: '@typescript-eslint/parser'
20+
},
21+
plugins: ['vue', '@typescript-eslint', 'prettier'],
22+
rules: {
23+
'prettier/prettier': 'error',
24+
'arrow-body-style': 'off',
25+
'prefer-arrow-callback': 'off',
26+
'@typescript-eslint/ban-types': [
27+
'error',
28+
{
29+
extendDefaults: true,
30+
types: {
31+
'{}': false
32+
}
33+
}
34+
],
35+
'@typescript-eslint/no-var-requires': 0,
36+
'vue/multi-word-component-names': 'off'
37+
}
38+
}

.husky/commit-msg

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npx --no-install commitlint -e

.husky/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npx lint-staged

.prettierrc.cjs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
printWidth: 80,
3+
tabWidth: 2,
4+
useTabs: false,
5+
singleQuote: true,
6+
semi: false,
7+
trailingComma: "none",
8+
bracketSpacing: true
9+
}

README.md

+15-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
+ dev
66
```
77
pnpm install
8-
pnpm run dev
8+
pnpm dev
99
```
1010
+ prod
1111
```
1212
pnpm install
13-
pnpm run build
14-
pnpm run serve
13+
pnpm build
14+
pnpm serve
15+
```
16+
+ test
17+
```
18+
pnpm install
19+
pnpm test
1520
```
1621

1722
### File list
@@ -24,10 +29,15 @@ pnpm run serve
2429
│ ├─ types
2530
│ ├─ App.vue
2631
│ ├─ entry-client.ts // mount dom && replace data
27-
│ ├─ entry-server.js // change html strings and static resources
32+
│ ├─ entry-server.js // replace html strings and static resources
2833
│ └─ main.ts // create app
2934
30-
├─ server.js // server startup file
35+
├─ __tests__
36+
│ ├─ test-server // test server startup file
37+
│ └─ vuessr.spec.ts // vue ssr test
38+
39+
├─ server.js // server file
40+
├─ start-server.js // server startup file
3141
├─ vite.config.ts
3242
// ...
3343
```

__tests__/ssr.spec.ts

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import puppeteer, { Browser, Page } from 'puppeteer'
2+
import { server, testPort, ServerOptions } from './test-server'
3+
import { beforeAll, afterAll, expect, test } from 'vitest'
4+
5+
let serverConfig: null | ServerOptions = null
6+
let browser: null | Browser = null // 浏览器实例
7+
let page: null | Page = null // 页面实例
8+
9+
const url = (path: string) => `http://localhost:${testPort}${path}`
10+
11+
beforeAll(async () => {
12+
serverConfig = await server()
13+
browser = await puppeteer.launch()
14+
page = await browser.newPage()
15+
})
16+
afterAll(async () => {
17+
if (page) {
18+
await page.close()
19+
}
20+
if (browser) {
21+
await browser.close()
22+
}
23+
if (serverConfig) {
24+
await serverConfig.close()
25+
}
26+
})
27+
28+
test('goto home', async () => {
29+
if (page) {
30+
await page.goto(url('/'))
31+
const content = await page.content()
32+
expect(content).toMatch('HOME')
33+
}
34+
})
35+
36+
test('goto about', async () => {
37+
if (page) {
38+
await page.goto(url('/about'))
39+
const content = await page.content()
40+
expect(content).toMatch('1')
41+
await page.click('#count')
42+
expect(content).toMatch('2')
43+
}
44+
})

__tests__/test-server.ts

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import createServer from '../server.js'
2+
3+
export const testPort = 5120
4+
5+
export interface ServerOptions {
6+
close: () => Promise<void>
7+
}
8+
9+
export async function server() {
10+
const { app } = await createServer(true)
11+
12+
return new Promise<ServerOptions>((resolve, reject) => {
13+
try {
14+
const server = app.listen(testPort, () => {
15+
console.log(`test service started, port: ${testPort}`)
16+
})
17+
resolve({
18+
async close() {
19+
await new Promise((resolve) => {
20+
server.close(resolve)
21+
console.log(`test service closed, port: ${testPort}`)
22+
})
23+
}
24+
})
25+
} catch (error) {
26+
reject(error)
27+
}
28+
})
29+
}

package.json

+26-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
"version": "0.0.0",
55
"type": "module",
66
"scripts": {
7-
"dev": "node server",
7+
"dev": "node start-server",
88
"build": "npm run build:client && npm run build:server",
99
"build:client": "vite build --ssrManifest --outDir dist/client",
1010
"build:server": "vite build --ssr src/entry-server.js --outDir dist/server",
11-
"serve": "cross-env NODE_ENV=production node server"
11+
"serve": "cross-env NODE_ENV=production node start-server",
12+
"test": "vitest",
13+
"lint": "pnpm lint:code",
14+
"lint:code": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./"
1215
},
1316
"dependencies": {
1417
"compression": "^1.7.4",
@@ -19,11 +22,31 @@
1922
"vue-router": "4"
2023
},
2124
"devDependencies": {
25+
"@commitlint/cli": "^17.4.2",
26+
"@commitlint/config-conventional": "^17.4.2",
2227
"@types/express": "^4.17.13",
2328
"@types/node": "^18.7.13",
29+
"@typescript-eslint/eslint-plugin": "^5.48.2",
30+
"@typescript-eslint/parser": "^5.48.2",
2431
"@vitejs/plugin-vue": "^3.0.3",
32+
"eslint": "^8.32.0",
33+
"eslint-config-prettier": "^8.6.0",
34+
"eslint-plugin-prettier": "^4.2.1",
35+
"eslint-plugin-vue": "^9.9.0",
36+
"husky": "^8.0.3",
37+
"lint-staged": "^13.1.0",
38+
"prettier": "^2.8.3",
39+
"puppeteer": "^19.5.2",
2540
"typescript": "^4.6.4",
2641
"vite": "^3.0.7",
42+
"vite-plugin-eslint": "^1.8.1",
43+
"vitest": "^0.27.2",
44+
"vue-eslint-parser": "^9.1.0",
2745
"vue-tsc": "^0.39.5"
46+
},
47+
"lint-staged": {
48+
"*.{js,jsx,tsx,ts}": [
49+
"npm run lint"
50+
]
2851
}
29-
}
52+
}

0 commit comments

Comments
 (0)