Project construction Specification
I. Code specification
1.1. Integrate the EditorConfig configuration
EditorConfig helps maintain a consistent coding style for multiple developers working on the same project on different IDE editors.
# http://editorconfig.org
root = true
[*] # indicates that all files apply
charset = utf-8 Set character set to UTF-8
indent_style = space # indented style (TAB | space)
indent_size = 2 # Indent size
end_of_line = lf # control line type (lf | cr | CRLF)
trim_trailing_whitespace = true # Remove any whitespace at the beginning of the line
insert_final_newline = true Always insert a new line at the end of the file
[*.md] # indicates that the following rules apply only to md files
max_line_length = off
trim_trailing_whitespace = false
Copy the code
VSCode requires a plug-in: EditorConfig for VSCode
1.2. Use the Prettier tool
Prettier Prettier is a powerful code formatting tool that supports JavaScript, TypeScript, CSS, SCSS, Less, JSX, Angular, Vue, GraphQL, JSON, Markdown, etc. Basically the front end can use the file format it can be done, is the most popular code formatting tool.
1. Install the prettier
npm install prettier -D
Copy the code
2. Configure the. Prettierrc file:
- UseTabs: Use TAB or space indent, select false;
- TabWidth: if TAB is a space, select 2 Spaces;
- PrintWidth: When the line length is 80 characters, some people prefer 100 or 120 characters;
- SingleQuote: Use single or double quotes, select true, use single quotes;
- TrailingComma: whether to add the trailingComma entered on multiple lines, set to
none
; - Semi: Indicates whether to add a semicolon to the end of the statement. The default value is true.
{
"useTabs": false."tabWidth": 2."printWidth": 80."singleQuote": true."trailingComma": "none"."semi": false
}
Copy the code
3. Create the. Prettierignore file
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
Copy the code
4.VSCode needs to install the plug-in for Prettier
5. Test whether Prettier takes effect
- Test 1: Save code in code;
- Test 2: Configure the command for one-time modification.
Configure a script in package.json:
"prettier": "prettier --write ."
Copy the code
1.3. Use ESLint to detect
1. We chose ESLint when we created the project earlier, so Vue will help us configure the ESLint environment we need by default.
2.VSCode needs to install the ESLint plugin:
3. Resolving the conflict between ESLint and Prettier:
Install plugins :(if prettier is selected by vue when creating a project, these two plugins are installed automatically)
npm i eslint-plugin-prettier eslint-config-prettier -D
Copy the code
Add the prettier plugin:
extends: [
"plugin:vue/vue3-essential"."eslint:recommended"."@vue/typescript/recommended"."@vue/prettier"."@vue/prettier/@typescript-eslint",
'plugin:prettier/recommended'
],
Copy the code
1.4. git Husky and ESLint
Although we have already required the project to use ESLint, there is no guarantee that the problems in ESLint will be resolved before team members submit code:
-
That is, we want to ensure that the code in the repository is esLint compliant;
-
Git commit: If the git commit does not conform to the ESLint specification, it will be automatically fixed by the specification.
So how do you do this? Husky tools are available:
- Husky is a Git hook that triggers the various stages of git commit: pre-commit, commit-msg, and pre-push
How do you use Husky?
Here we can use the autoconfiguration command:
npx husky-init && npm install
Copy the code
Three things will be done here:
1. Install Husky-related dependencies:
2. Create the.husky folder in the project directory:
npx huksy install
Copy the code
3. Add a script to package.json:
Next, we need to do one operation: on commit, execute the Lint script:
Git commit will automatically validate your code.
1.5. Git Commit specification
1.5.1. Code submission style
Git commits are usually committed in a consistent style so that you can quickly locate each commit for later version control.
But if writing these manually every time is a hassle, we can use a tool: Commitizen
- Commitizen is a tool that helps us write normative Commit messages;
1. Install Commitizen
npm install commitizen -D
Copy the code
2. Install AND initialize THE Z-Xconventional – Changelog:
npx commitizen init cz-conventional-changelog --save-dev --save-exact
Copy the code
This command will help us install CZ-Conventional – Changelog:
And configure it in package.json:
This time we need to submit code using NPX cz:
- The first step is to select Type, the type of this update
Type | role |
---|---|
feat | New features |
fix | Fix the Bug (Bug fix) |
docs | Modify documentation |
style | Change code formats (white-space, formatting, missing semi Colons, etc.) |
refactor | Code Refactor |
perf | A code change that improves Performance |
test | When adding Missing tests |
build | Changing project builds or external dependencies (e.g. scopes: webpack, gulp, NPM, etc.) |
ci | Change the scripts commands in the continuous integration software configuration files and packages, such as scopes: Travis, Circle, etc |
chore | Changing the build process or ancillary tools (such as changing the test environment) |
revert | Code back |
- Step 2 Select the scope of this modification (scope)
- The third step is to select the information to submit
- Step 4 Submit detailed description
- Step 5 is a major change
- Step 6 Whether to affect an Open issue
We can also build a command in scripts to execute cz:
1.5.2. Code submission verification
What if we standardize the commit style according to CZ, but some colleagues still commit according to non-standard format through Git commit?
- We can restrict commits via commitlint;
1. Install @commitlint/ config-Conventional and @commitlint/ CLI
npm i @commitlint/config-conventional @commitlint/cli -D
Copy the code
2. Create the commitlint.config.js file in the root directory and configure commitLint
module.exports = {
extends: ['@commitlint/config-conventional']}Copy the code
3. Use husky to generate the commit-msg file and verify the commit information:
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"
Copy the code
Second, third-party library integration
2.1. The vue. Config. Js configuration
Vue.config.js can be configured in three ways:
- Method 1: Directly use the options provided by the CLI to configure:
- For example, publicPath: configures the subdirectory for application deployment (the default is
/
, which is equivalent to deploying inhttps://www.my-app.com/
); - For example, outputDir: modify the output folder;
- For example, publicPath: configures the subdirectory for application deployment (the default is
- Method 2: Use configureWebpack to modify the WebPack configuration.
- It could be an object, it could be merged directly;
- It can be a function that receives a config that can be used to modify the configuration.
- Method 3: Modify the WebPack configuration using chainWebpack:
- Is a function that receives a Webpack-chain-based config object that can be modified.
const path = require('path')
module.exports = {
outputDir: './build'.// configureWebpack: {
// resolve: {
// alias: {
// views: '@/views'
/ /}
/ /}
// }
// configureWebpack: (config) => {
// config.resolve.alias = {
// '@': path.resolve(__dirname, 'src'),
// views: '@/views'
/ /}
// },
chainWebpack: (config) = > {
config.resolve.alias.set(The '@', path.resolve(__dirname, 'src')).set('views'.'@/views')}}Copy the code
2.2. The vue – integration of the router
Install the latest version of vue-Router:
npm install vue-router@next
Copy the code
Create a Router object:
import { createRouter, createWebHashHistory } from 'vue-router'
import { RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/'.redirect: '/main'
},
{
path: '/main'.component: () = > import('.. /views/main/main.vue')}, {path: '/login'.component: () = > import('.. /views/login/login.vue')}]const router = createRouter({
routes,
history: createWebHashHistory()
})
export default router
Copy the code
Install the router:
import router from './router'
createApp(App).use(router).mount('#app')
Copy the code
Configure jumps in app.vue:
<template>
<div id="app">
<router-link to="/login">The login</router-link>
<router-link to="/main">Home page</router-link>
<router-view></router-view>
</div>
</template>
Copy the code
2.3. Vuex integration
Install vuex:
npm install vuex@next
Copy the code
Create a store object:
import { createStore } from 'vuex'
const store = createStore({
state() {
return {
name: 'coderwhy'}}})export default store
Copy the code
Install the store:
createApp(App).use(router).use(store).mount('#app')
Copy the code
For use in app.vue:
<h2>{{ $store.state.name }}</h2>
Copy the code
2.4. Element – plus integration
Element Plus, a Vue 3.0-based desktop component library for developers, designers, and product managers:
- I believe many of you have used element-UI in Vue2, and element-Plus is a UI component library developed by Element-UI for VUE3.
- It works the same way as many other component libraries, so learn element-Plus and others like Ant-Design-Vue, NaiveUI, and VantUI;
The installation element – plus
npm install element-plus
Copy the code
2.4.1. Global import
One way to introduce element-Plus is global import, which means that all components and plug-ins are automatically registered:
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import router from './router'
import store from './store'
createApp(App).use(router).use(store).use(ElementPlus).mount('#app')
Copy the code
2.4.2. Local introduction
When a component is used in development, it is introduced into a component:
<template> <div id="app"> <router-link to="/login"> </router-link> <router-view></router-view> <h2>{{$store.state.name}}</h2> <el-button> Default button </el-button> <el-button Type ="primary"> </el-button> <el-button type="success"> </el-button> <el-button type="warning"> </el-button> <el-button type="danger"> </el-button> </div> </template> <script lang="ts"> import { defineComponent } from 'vue' import { ElButton } from 'element-plus' export default defineComponent({ name: 'App', components: { ElButton } }) </script> <style lang="less"> </style>Copy the code
However, we will find that there is no corresponding style. There are two ways to introduce styles:
- Global reference style (as you did before);
- Local reference styles (via Babel’s plug-in);
1. Install the Babel plugin:
npm install babel-plugin-import -D
Copy the code
2. Configure the Babel. Config. Js
module.exports = {
plugins: [['import',
{
libraryName: 'element-plus'.customStyleName: (name) = > {
return `element-plus/lib/theme-chalk/${name}.css`}}]],presets: ['@vue/cli-plugin-babel/preset']}Copy the code
But there’s still a downside:
- These components need to be imported and registered with components when they are used in multiple pages or components.
- So we can register them globally once;
import {
ElButton,
ElTable,
ElAlert,
ElAside,
ElAutocomplete,
ElAvatar,
ElBacktop,
ElBadge,
} from 'element-plus'
const app = createApp(App)
const components = [
ElButton,
ElTable,
ElAlert,
ElAside,
ElAutocomplete,
ElAvatar,
ElBacktop,
ElBadge
]
for (const cpn of components) {
app.component(cpn.name, cpn)
}
Copy the code
2.5. Axios integration
Install axios:
npm install axios
Copy the code
Encapsulation axios:
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { Result } from './types'
import { useUserStore } from '/@/store/modules/user'
class HYRequest {
private instance: AxiosInstance
private readonly options: AxiosRequestConfig
constructor(options: AxiosRequestConfig) {
this.options = options
this.instance = axios.create(options)
this.instance.interceptors.request.use(
(config) = > {
const token = useUserStore().getToken
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(err) = > {
return err
}
)
this.instance.interceptors.response.use(
(res) = > {
// Intercepts the data of the response
if (res.data.code === 0) {
return res.data.data
}
return res.data
},
(err) = > {
return err
}
)
}
request<T = any>(config: AxiosRequestConfig): Promise<T> {
return new Promise((resolve, reject) = > {
this.instance
.request<any, AxiosResponse<Result<T>>>(config)
.then((res) = > {
resolve((res as unknown) as Promise<T>)
})
.catch((err) = > {
reject(err)
})
})
}
get<T = any>(config: AxiosRequestConfig): Promise<T> {
return this.request({ ... config,method: 'GET' })
}
post<T = any>(config: AxiosRequestConfig): Promise<T> {
return this.request({ ... config,method: 'POST' })
}
patch<T = any>(config: AxiosRequestConfig): Promise<T> {
return this.request({ ... config,method: 'PATCH'})}delete<T = any>(config: AxiosRequestConfig): Promise<T> {
return this.request({ ... config,method: 'DELETE'}}})export default HYRequest
Copy the code
2.6. VSCode configuration
{
"workbench.iconTheme": "vscode-great-icons"."editor.fontSize": 17."eslint.migration.2_x": "off"."[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"files.autoSave": "afterDelay"."editor.tabSize": 2."terminal.integrated.fontSize": 16."editor.renderWhitespace": "all"."editor.quickSuggestions": {
"strings": true
},
"debug.console.fontSize": 15."window.zoomLevel": 1."emmet.includeLanguages": {
"javascript": "javascriptreact"
},
"explorer.confirmDragAndDrop": false."workbench.tree.indent": 16."javascript.updateImportsOnFileMove.enabled": "always"."editor.wordWrap": "on"."path-intellisense.mappings": {
"@": "${workspaceRoot}/src"
},
"hediet.vscode-drawio.local-storage": "eyIuZHJhd2lvLWNvbmZpZyI6IntcImxhbmd1YWdlXCI6XCJcIixcImN1c3RvbUZvbnRzXCI6W10sXCJsaWJyYXJpZXNcIjpcImdlbmVyYWw7YmFzaWM7YXJ yb3dzMjtmbG93Y2hhcnQ7ZXI7c2l0ZW1hcDt1bWw7YnBtbjt3ZWJpY29uc1wiLFwiY3VzdG9tTGlicmFyaWVzXCI6W1wiTC5zY3JhdGNocGFkXCJdLFwicGx 1Z2luc1wiOltdLFwicmVjZW50Q29sb3JzXCI6W1wiRkYwMDAwXCIsXCIwMENDNjZcIixcIm5vbmVcIixcIkNDRTVGRlwiLFwiNTI1MjUyXCIsXCJGRjMzMzN cIixcIjMzMzMzM1wiLFwiMzMwMDAwXCIsXCIwMENDQ0NcIixcIkZGNjZCM1wiLFwiRkZGRkZGMDBcIl0sXCJmb3JtYXRXaWR0aFwiOjI0MCxcImNyZWF0ZVR hcmdldFwiOmZhbHNlLFwicGFnZUZvcm1hdFwiOntcInhcIjowLFwieVwiOjAsXCJ3aWR0aFwiOjExNjksXCJoZWlnaHRcIjoxNjU0fSxcInNlYXJjaFwiOnR ydWUsXCJzaG93U3RhcnRTY3JlZW5cIjp0cnVlLFwiZ3JpZENvbG9yXCI6XCIjZDBkMGQwXCIsXCJkYXJrR3JpZENvbG9yXCI6XCIjNmU2ZTZlXCIsXCJhdXR vc2F2ZVwiOnRydWUsXCJyZXNpemVJbWFnZXNcIjpudWxsLFwib3BlbkNvdW50ZXJcIjowLFwidmVyc2lvblwiOjE4LFwidW5pdFwiOjEsXCJpc1J1bGVyT25 cIjpmYWxzZSxcInVpXCI6XCJcIn0ifQ=="."hediet.vscode-drawio.theme": "Kennedy"."editor.fontFamily": "Source Code Pro, 'Courier New', monospace"."editor.smoothScrolling": true."editor.formatOnSave": true."editor.defaultFormatter": "esbenp.prettier-vscode"."workbench.colorTheme": "Atom One Dark"."vetur.completion.autoImport": false."security.workspace.trust.untrustedFiles": "open"."eslint.lintTask.enable": true."eslint.alwaysShowStatus": true."editor.codeActionsOnSave": {
"source.fixAll.eslint": true}}Copy the code