preface
Uvu recently announced that Vue3 will become the new default version of VUE on February 7, 2022, which is not a good idea. It took some time to complete a set of startup templates for Vue3. I stepped on the pit for my friends in advance.
-
The first half of this article is the template
Out of the box features overview
-
The second half of the article is for some of the partners who want to start their own configuration explained
Configuration process
This article is too long to avoid omissions or mistakes. If you find them, feel free to discuss them in the comments section or issue them on Github
Out of the box functions configured:
-
Programming languages: TypeScript 4.x, JavaScript
-
Front-end framework: Vue 3.x
-
Build tool: Vite 2.x
-
UI framework: Element Plus
-
Icon tool: ICones
-
CSS precompilation: Sass
-
CSS framework: Windi CSS
-
HTTP tool: Axios
-
Route management: Vue Router 4.x
-
State management: Pinia
-
Code specification: EditorConifg, Prettier, ESLint, Airbnb JavaScript Style Guide
-
Submit specifications: HusKY, Commitlint, Lint-Staged
There are some other plug-ins for various functions:
-
Implement automatic loading on demand (recommended for wall cracks) : unplugin-auto-import, unplugin-vue-components, vite-plugin-style-import, unplugin-icons
-
Componentization of SVG ICONS: viet-SVG-loader
-
Let the various apis support responsiveness: VueUse
-
Let the page load with feedback: NProgress
-
Markdown: viet-plugin-MD is supported
All of the above features have been configured and verified, and you can have fun using the template!
This template doesn’t configure GitHub Actions, change documents, unit tests, etc. If you need to, check out my other document to configure # Build a canonical TypeScript SDK project from scratch
Github
Github.com/nekobc19989…
Method of use
download
- Click the Use This Template button to jump to the address where the project was created
- Or just use Git Clone
git clone https://github.com/nekobc1998923/vue3-ts-template.git
Copy the code
The installation
npm install
Copy the code
run
npm run dev
Copy the code
packaging
npm run build
Copy the code
vetur -> volar
As a side note, vetur is obviously not as good as Volar when it comes to vue3 support, so we recommend that you disable vuetur and use Volor instead
If you are also maintaining a vue2 project, you can use vscode’s workspace feature for standalone use
Configuration process:
The following is a configuration process of the entire template. If you need to configure a template by yourself, you can read ~
Code directory structure
The structure of the entire template code directory looks like this:
.husky
: configuration folder for husky hooks.vscode
: used to put vscode configuration in the projectpresets
Plugin configuration for vite plugins, and some.d.ts declaration filespublic
: is used to store common files such as header ICONS that are packaged in the dist root directorysrc
: Used to put project code filesapi
: Some interface configuration for HTTPassets
: used to store static resources such as CSScomponents
: Used to hold Vue componentslayout
: Used to put the layout of the projectrouter
: is used to store the routing configuration of the projectstore
: used to put the configuration of state management Piniautils
: used to put tool method classes in the projectviews
: the.vue view used to hold the project
Vite
Vite initialization
Vite creates a vue3 + typescript basic project with just a short command. Here my-vue-app needs to be changed to your project name:
npm init vite@latest my-vue-app --template vue-ts
Copy the code
Alias using alias
We configure vite.config.ts
Resolve: {alias: {' @ ': resolve (__dirname,'. / SRC), / / @ pointing to the SRC directory to},},Copy the code
Don’t forget to configure tsconfig.json as well
Configure vite service Settings
Let’s configure vite.config.ts and add the following configuration
It is worth noting that only after host is configured can we access the project locally via IP
Port: 8080, // port number open: true, // automatically open the browser cors: StrictPort: true, // Cross-domain Settings allow strictPort: true, // Exit if the port is occupied // proxy: {'/ API ': {// Local 8000 front-end code interface proxy to 8888 service port target: 'http://localhost:8888/', changeOrigin: true, / / allow cross-domain rewrite: (path) = > path. The replace ('/API/', '/'),,}},},Copy the code
Build configuration
We can set up the package to remove console from the code, and configure the packaged static resources to different directories under Dist
Build: {brotliSize: false, // Remove the warning chunkSizeWarningLimit: 2000, // remove console.log terserOptions in production: { compress: { drop_console: false, pure_funcs: ['console.log', 'console.info'], drop_debugger: true, }, }, assetsDir: RollupOptions: {output: {chunkFileNames: 'static/js/[name]-[hash].js', entryFileNames: 'static/js/[name]-[hash].js', assetFileNames: 'static/[ext]/[name]-[hash].[ext]', }, }, },Copy the code
Configure vite environment variables
Often, we need to distinguish between production and development environments. We create three new files in the root directory to store environment variables:
.env
.env.development
.env.production
Env is configured as follows:
VITE_API_BASEURL = /api
VITE_BASE = /base-vue3/
VITE_APP_TITLE = base-vue3
Copy the code
VITE_API_BASEURL is the API base prefix for the project
VITE_BASE is the base path prefix for the project
VITE_APP_TITLE is the web page title of the project
Automatically load apis & components & styles on demand
- Do you get tired of using it every time
vue
When,You need to constantly import vue’s API - Do you get tired of using it every time
Component library
When,Components need to be introduced continuously on demand - Are you tired of using it sometimes
Third-party Component Library
When,Additional CSS styles need to be introduced
Unplugin-auto-import: automatically introduce vue\vue-router\pinia, etc. apis on demand
Unplugin-vue-components: Automatically introduce third-party component library components and our own custom components on demand
Viet-plugin-style-import: Automatically introduces the style styles we use in third-party component libraries, such as Element Plus’s Message component
Now there are two plug-ins that can help us solve this problem. We can use them directly when we call them without import, and when we package them, only the apis and components that we actually use will be built into the final product. They are unplugin-vue-components and unplugin-auto-import
Install the configuration
We’ll start by installing dependencies:
npm install -D unplugin-vue-components unplugin-auto-import vite-plugin-style-import
Copy the code
Then we configure vite.config.ts to add the following;
// vite.config.ts import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' export default { plugins: [ // ... AutoImport({ dts: './presets/auto-imports.d.ts', imports: ['vue', 'pinia', 'vue-router', '@vueuse/core'], // Generate corresponding .eslintrc-auto-import.json file. // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals eslintrc: { enabled: true, // Default `false` filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json` globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') }, }), Components({ dts: '. / presets/components. Which s', / / imports specify the component location, the default for SRC/components dirs: ['src/components/'], }), styleImport({ }), ], }Copy the code
Since we are using ESLint we also need to configure.eslintrc.js:
// .eslintrc.js
module.exports = {
/* ... */
extends: [
// ...
'./.eslintrc-auto-import.json',
],
}
Copy the code
@vitejs/plugin-vue-jsx
This plugin allows us to support JSX writing
npm i @vitejs/plugin-vue-jsx -D
Copy the code
Then configure vite.config.ts
import vueJsx from '@vitejs/plugin-vue-jsx';
export default defineConfig({
plugins: [...,vueJsx()]
})
Copy the code
vite-svg-loader
This plugin allows us to import SVG files directly to use, just like using Vue components
The installation process
npm i vite-svg-loader -D
Copy the code
Then configure vite.config.ts
import svgLoader from 'vite-svg-loader'
export default defineConfig({
plugins: [...,svgLoader()]
})
Copy the code
Use the sample
<script setup lang="ts"> import MyIcon from '@/assets/example.svg? component'; </script> <template> <MyIcon /> </template>Copy the code
@vitejs/plugin-legacy
npm i @vitejs/plugin-legacy -D
Copy the code
Then configure vite.config.ts
import svgLoader from 'vite-svg-loader'
export default defineConfig({
plugins: [...,
legacy({
targets: ['defaults', 'not IE 11'],
}),
]
})
Copy the code
vite-plugin-md
This plug-in helps us introduce MarkDown for use as a Vue component
It is worth noting that since we have configured automatic import on demand components above, all we need to do is to put the.md file in the Components directory and use it directly
Install the configuration
npm i vite-plugin-md -D
Copy the code
Then configure vite.config.ts
// vite.config.ts
import Markdown from 'vite-plugin-md';
export default {
plugins: [
Markdown(),
]
}
Copy the code
TypeScript configuration
The full tsconfig.json configuration is directly pasted here
{ "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "esModuleInterop": True, "lib": [" esNext ", "dom"], // baseUrl tells the compiler where to look for modules. All non-relative module imports are treated as relative to baseUrl. "BaseUrl" : ". ", / / the relative module into the path of the map configuration "paths" : {" @ / * ": [" SRC / *"],}}, "include" : ["/SRC / * * * ts "and"/SRC / * * *. Which s ", "/ SRC / * * *. The TSX", "/ SRC / * * *. Vue", "presets. / / * * * which s",], / / compilers excluded by default file "exclude" : ["node_modules"] }Copy the code
Code style specification
I have detailed the configuration process in another of my articles: Build a canonical TypeScript SDK project from scratch
We only need to install an additional dependency, which will automatically install it for us when we select the Vue environment during ESLint initialization
npm i -D eslint-plugin-vue
Copy the code
Then the final.eslintrc.js configuration will have some different configuration, I posted the complete configuration here:
module.exports = { env: { browser: true, es2021: true, node: true, }, globals: { defineEmits: true, document: true, localStorage: true, GLOBAL_VAR: true, window: true, defineProps: true, defineExpose: true, }, extends: [ './.eslintrc-auto-import.json', 'airbnb-base', 'plugin:@typescript-eslint/recommended', 'the plugin: vue/vue3 - it', 'the plugin: prettier/it', / / add prettier plugins], parserOptions: {ecmaVersion: 'latest', parser: '@typescript-eslint/parser', sourceType: 'module', }, plugins: ['vue', '@typescript-eslint', 'import'], rules: { 'no-console': 'off', 'import/no-unresolved': 'off', 'import/extensions': 'off', 'import/no-extraneous-dependencies': 'off', }, };Copy the code
Vue Router 4.x
Install the configuration
We need to install the vuE-Router4.x version
npm install vue-router@4 --save
Copy the code
We will create an index.ts file under SRC /router to store our router configuration
Mount the configured router to vue: modify the entry main.ts file
unplugin-icons
We often struggle to find different ICONS, but now there is a great plugin and a great library to solve the problem of finding and using ICONS
Icones: is a very good icon library, which integrates many ICONS
Unplugin-icons: Automatically import the ICONS we want to use on demand, without manually importing them
Install the configuration
npm i -D unplugin-icons @iconify/json
Copy the code
Once installed, we configure vite.config.ts to add the following
// vite.config.ts
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import Components from 'unplugin-vue-components/vite'
export default {
plugins: [
Components({
resolvers: IconsResolver(),
}),
Icons({
compiler: 'vue3',
autoInstall: true,
}),
],
}
Copy the code
Use the sample
To start, go to icones.net lilify. app/ and choose an icon
And I’m gonna hit Copy
Going back to our code, just a short sentence is enough to use:
<template>
<i-mdi-account-reactivate style="font-size: 2em; color: red" />
</template>
Copy the code
ElementPlus
I don’t have to say much about The Element UI. There are already a lot of people using Vue2 to build projects, and Element Plus is their component library based on Vue3. Although there are still some problems in use, the official website message says: stable version released on February 7, still worth looking forward to and use;
Install the configuration
Let’s start by installing Element-Plus
npm install element-plus --save
Copy the code
We then configure the AutoImport and Components and styleImport configured above in vite.config.ts
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import styleImport, { ElementPlusResolve } from 'vite-plugin-style-import';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
styleImport({
resolves: [ElementPlusResolve()],
}),
],
}
Copy the code
After configuration, it will automatically import the components we use in our code on demand
Set Chinese theme
Element Plus is in English by default, so if we want to use a Chinese theme, we can set it in app.vue
<script setup lang="ts">
import zhCn from 'element-plus/lib/locale/lang/zh-cn';
const locale = zhCn;
</script>
<template>
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
</template>
Copy the code
Remaining component libraries
If you want to use other component libraries such as Ant-Design-Vue or Naive UI, you can also refer to the configuration. It is worth mentioning that they all support automatic import on demand configuration
Ant Design of Vue
Naive UI
Automatic import on demand, you can refer to the configuration here: github.com/antfu/unplu…
Pinia
Pinia. Js is a new generation of state management tools, can be considered as the next generation of Vuex, namely vex5.x; It has several obvious changes compared to Vuex:
- better
typescript
support - removed
mutations
Leaving onlyactions
;actions
Support synchronous and asynchronous - No need to manually add
store
Install the configuration
npm install pinia --save
Copy the code
Create index.ts in the SRC /store folder and configure it as follows:
import { createPinia } from 'pinia';
const store = createPinia();
export default store;
Copy the code
Then we use the exported store under main.ts
Pinia usage
We can create a new theme. Ts file in the store directory and write it as follows:
import { defineStore } from 'pinia'; Const theme = defineStore({// Where id must be a unique ID ID: 'theme', state: () => {return {themeType: 'bright blue ', themeColor: '#2080F0FF', }; }, // Equivalent to vuex's getter getters: {getThemeType: (state) => state.themeType, getThemeColor: (state) => state.themecolor,}, // Pinia abandons mutations and uses actions only: SetThemeType (type: string) {this.themeType = type; ,}}}); export default theme;Copy the code
Call as follows:
<script setup lang="ts"> import theme from '@/store/theme' const myTheme = theme() mytheme.setthemetype (' dark color ') </script> <template> {{myTheme.themeColor}} </template>Copy the code
SCSS
I don’t have to tell you too much about this, but who hasn’t used sass or less? Let’s go straight to the configuration process:
Install the configuration
npm i sass -D
Copy the code
We will create a variable. SCSS file under SRC/Assets to store our global CSS variables. We will first configure only one theme color:
At the same time, we also create a new index. SCSS in SRC/Assets directory and import the SCSS file we will create in the future. And introduce it in main.ts
$theme-color: #2080F0FF
Copy the code
Then open the vite.config.ts file, plus the introduction of CSS configuration
css: {
preprocessorOptions: {
scss: {
additionalData: `
@import "@/assets/styles/variables.scss";
`,
javascriptEnabled: true,
},
},
},
Copy the code
Usage in components
After the above configuration, we can use the variables we defined in variables.scss directly in the component without any introduction:
<style lang="scss">
.myclass {
color: $theme-color;
}
</style>
Copy the code
Windi CSS
Windi CSS can be seen as a superior alternative to Tailwind CSS, offering faster load times, full compatibility with Tailwind V2.0, and a host of additional cool features.
We can do atomized CSS programming, and the framework automatically does the importing on demand work for us;
Install the configuration
npm i -D vite-plugin-windicss windicss
Copy the code
After installing the dependencies, we installed the plug-in in viet.config.ts
import WindiCSS from 'vite-plugin-windicss'
export default {
plugins: [
WindiCSS(),
],
}
Copy the code
We then introduce it in main.ts
import 'virtual:windi.css'
Copy the code
Axios
Install the configuration
npm i axios -S
Copy the code
The basic package
After the installation, we will create a new http.ts configuration file in the SRC/API directory to encapsulate the AXIos method.
// src/api/http.ts import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'; import { ElMessage } from 'element-plus'; import showCodeMessage from '@/api/code'; const BASE_PREFIX = '/api'; Const service: AxiosInstance = axios.create({baseURL: BASE_PREFIX, // timeout: Headers: {' content-type ': 'application ',},}); / / request interceptor service. Interceptors. Request. Use ((config: AxiosRequestConfig) => {// TODO = // TODO = // TODO = // TODO = // }, (error: AxiosError) => { return Promise.reject(error); }); / / response interceptor service. Interceptors. Response. Use ((the response: AxiosResponse) => { if (response.status === 200) { return response; } ElMessage.info(JSON.stringify(response.status)); return response; }, (error: AxiosError) => { const { response } = error; if (response) { ElMessage.error(showCodeMessage(response.status)); return Promise.reject(response.data); } elmessage. warning(' Network connection is down, please try again later! '); return Promise.reject(error); }); export default service;Copy the code
Let’s create a new code.ts to store the processing logic for the status code we receive after the HTTP request
// src/api/code.ts declare interface codeMessageMapTypes { 400: string; 401: string; 403: string; 404: string; 405: string; 500: string; [key: string]: string; } const codeMessageMap: codeMessageMapTypes = {400: '[400]: request parameter error ', 401: '[401]: account not logged in ', 403: '[403]: access denied ', 404: '[404] : request path error, 405:' [405] : request method error, 500: '[500] : server error'}; const showCodeMessage = (code: number | string): String = > {return codeMessageMap [JSON stringify (code)] | | 'abnormal network connection, please try again later. '; }; export default showCodeMessage;Copy the code
VueUse
VueUse is a collection of reactive Vue utilities that allow us to make all sorts of things reactive without having to write the hooks manually
Install the configuration
npm i npm i @vueuse/core -D
Copy the code
After installing dependencies, we also need to configure automatic import on demand in viet.config. ts
import { VueUseComponentsResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig({
plugins: [
AutoImport({
imports: ['@vueuse/core'],
}),
Components({
resolvers: [VueUseComponentsResolver()],
}),
],
});
Copy the code
Once configured, we don’t need to import methods ourselves and can use them directly
NProgress
This plugin, which I’m sure most of you have used, helps us add a page loading hint at the top: a loading progress bar and a turning circle
Install the configuration
npm i --save nprogress
Copy the code
We also need to install typescript types because we use typescript
npm i @types/nprogress -D
Copy the code
After the installation, we went back to SRC /router/index.ts to configure our route guard
import NProgress from 'nprogress';
router.beforeEach((to, from) => {
if (!NProgress.isStarted()) {
NProgress.start();
}
});
router.afterEach((to, from) => {
NProgress.done();
});
Copy the code
Create a new nprogress. SCSS file in SRC /assets/styles and configure it as follows:
/* Make clicks pass-through */ #nprogress { pointer-events: none; } #nprogress .bar { background: $theme-color; position: fixed; z-index: 1031; top: 0; left: 0; width: 100%; height: 2px; } /* Fancy blur effect */ #nprogress .peg { display: block; position: absolute; right: 0px; width: 100px; height: 100%; box-shadow: 0 0 10px $theme-color, 0 0 5px $theme-color; Opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px); } /* Remove these to get rid of the spinner */ #nprogress .spinner { display: block; position: fixed; z-index: 1031; top: 15px; right: 15px; } #nprogress .spinner-icon { width: 18px; height: 18px; box-sizing: border-box; border: solid 2px transparent; border-top-color: $theme-color; border-left-color: $theme-color; border-radius: 50%; -webkit-animation: nprogress-spinner 400ms linear infinite; animation: nprogress-spinner 400ms linear infinite; } .nprogress-custom-parent { overflow: hidden; position: relative; } .nprogress-custom-parent #nprogress .spinner, .nprogress-custom-parent #nprogress .bar { position: absolute; } @-webkit-keyframes nprogress-spinner { 0% { -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes nprogress-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }}Copy the code