Vue compilation has changed

Vite is used as the scaffolding development and construction tool of Vue

Vite, a development server based on browser native ES Imports. Parsing the imports in the browser, compiling and returning them on the server side on demand, bypassing the concept of packaging entirely, and making the server available on demand. Not only does it have Vue file support, it also handles hot updates, and the speed of hot updates does not slow down with the increase of modules. For production environments, the same code can be rollup. Although it is still rough, I think this direction has potential. If done well, it can completely solve the problem of changing a line of code and waiting for hot updates for half a day

Install global scaffolding dependenciesScaffolding making

cnpm install -g create-vite-app
Copy the code

Creating a scaffold project

CNPM cannot be used here

npm create vite-app <project-name> 
Copy the code

Integration of Ts

cnpm i --dev typescript
Copy the code

Tsconfig. json:

{
  "compilerOptions": {
    /* Specify ECMAScript target version directory "ES3","ES5","ES6","ES2015","ES2016", "ES2017","ES2018","ES2019","ES2020","ESNext" */
    "target": "esnext"./ * to use the specified template standard "CommonJS", "AMD", "System", "UMD," "ES6", "ES2015", "ES2020", "ESNext", "None" * /
    "module": "esnext"./* Enable all strict type checking options. Boolean */ requires TypeScript version 2.3 or later
    "strict": true./* JSX code for the development environment 'preserve', 'react', or 'react-native' */
    "jsx": "preserve"./* Specifies whether to generate phase d.ts declaration files at compile time. If true, each ts file generates a js file and a declaration file, but declaration and allowJs cannot be set to true at the same time
    "declaration": true./* Specifies whether a.map file is generated at compile time
    "declarationMap": false./* Specifies whether a.map file is generated at compile time
    "sourceMap": false./* Specifies whether to introduce tslib copy tool functions. Default is false */
    "importHelpers": true.Import xx from 'xx' */
    "moduleResolution": "node"./* Enable experimental support for ES7 decorators */
    "experimentalDecorators": true."esModuleInterop": true./* Do not report unexecutable code errors */
    "allowSyntheticDefaultImports": true.// You must flag the Null type to assign to Null
    /* When set to true, null and undefined cannot be assigned to values other than those two types, nor can they be assigned to values of other types, except any, where undefined can be assigned to void */
    "strictNullChecks": true./* Parse json extensions */
    "resolveJsonModule": true."baseUrl": "."."paths": {
      "@ / *": ["src/*"]},/* Specifies the library file to be included in the compilation */
    "lib": ["esnext"."dom"."dom.iterable"."scripthost"]},"include": [
    "src/**/*"."src/**/*.ts"."src/**/*.tsx"."src/**/*.vue"."tests/**/*.ts"."tests/**/*.tsx"]."exclude": ["node_modules"."dist"]}Copy the code

Integrated eslint

cnpm i -D eslint eslint-plugin-vue
Copy the code

Project root directory to create configuration file.eslintrc.js:

module.exports = {
  parser: "vue-eslint-parser".parserOptions: {
    parser: "@typescript-eslint/parser".// Specify ESLint to parse Specifies the ESLint parser
    ecmaVersion: 2020.// Allows parsing of modern ECMAScript features that Allows for the parsing of modern ECMAScript features
    sourceType: "module".// Imports can be used for the use of imports
    ecmaFeatures: {
      tsx: true.// TSX Allows for the parsing of JSX
      jsx: true}},// settings: {
  // tsx: {
  // version: "detect" // Tells eslint-plugin-react to automatically detect the version of React to use
  / /}
  // },
  extends: [
    "plugin:vue/vue3-recommended"."plugin:@typescript-eslint/recommended".// Uses the recommended rules from the @typescript-eslint/eslint-plugin
    "prettier/@typescript-eslint".// Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
    "plugin:prettier/recommended" // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.].rules: {
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off"."no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"."comma-dangle": "off".// Fix an issue with eslint-plugin-vue
    // allow async-await
    "generator-star-spacing": "off"."no-undef": "off".camelcase: "off"}};Copy the code

Integrated pritter

cnpm i -D prettier eslint-config-prettier eslint-plugin-prettier
Copy the code

Create a configuration file in the project root directory:.prettierrc.js

module.exports = {
  / * * *@desc Indent with TAB instead of space * @ default false *@params* -false: use TAB * -true: use a space */
  useTabs: false./ * * *@desc Specify the number of Spaces per TAB indent level * @ default 2 *@params Number [object] */
  tabWidth: 2./ * * *@desc Specifies the maximum number of characters per line to wrap * @ default 80 *@params number* /
  printWidth: 100./ * * *@desc Semicolon * is automatically used at the end@default true
   * @params* -true: automatic join. 'semicolon * -false: automatic deletion'; ` semicolon * /
  semi: true./ * * *@desc When multiple lines are forced to wrap, * if possible, print a comma after it. (Tip: Single-line arrays never end with a comma.) *@default es5
   * @params* -ES5: Trailing commas (objects, arrays, etc.) that are valid in ES5 * -none: no trailing commas * -all: trailing commas (including function arguments) whenever possible */
  trailingComma: 'all'./ * * *@desc Use single quotes instead of double quotes *@default  false
   * @notes* - JSX files - can see https://prettier.io/docs/en/options.html#jsx-quotes * - this option is ignored if the number of quotes more than the other quotes, use less quotes a formatted string * = = > example: Letter of letter (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) (letter from letter letter (letter from letter letter)) *@params* -true: use single quotation marks instead of double quotation marks * -false: Use double quotation marks */
  singleQuote: true./ * * *@desc When a property in an object is changed by reference *@default as-needed
   * @param* -as-needed: add quotes around object attributes only when necessary * - consistent: add quotes around object attributes * - preserve: respect the input usage of quotes in object attributes */
  quoteProps: 'consistent'./ * * *@desc Use single quotes instead of double quotes * in JSX@default false
   * @params* -false: use double quotation marks * -true: use single quotation marks */
  jsxSingleQuote: true./ * * *@desc Prints a space * between parentheses in the object text@default true
   * @params
   *  - false:{foo: bar}
   *  - true:{ foo: bar }
   */
  bracketSpacing: true./ * * *@desc JSX label closure position '>' *@default false
   * @params
   *  - false:
   *        <button
              className="prettier-class"
              id="prettier-id"
              onClick={this.handleClick}
            >
              Click Here
            </button>
   *  - true:
   *        <button
              className="prettier-class"
              id="prettier-id"
              onClick={this.handleClick}>
              Click Here
            </button>
   */
  jsxBracketSameLine: true./ * * *@desc Enclose parentheses * around the arrow function argument@default always
   * @params
   *  - always:(x)=>{}
   *  - avoid: x => x
   */
  arrowParens: 'avoid'./ * * *@desc By default, Prettier wraps Markdown text as-is, * because some services use newline-sensitive renderers, * such as GitHub comments and BitBucket. * In some cases, you may want to switch to editor/viewer flexible wrapping, so this option allows you to choose "never". *@default always
   * @params* -always: If the characters are outside the printWidth limit, we should wrap them up prose * -never: do not wrap them up prose * -preserve: Original packaged Prose first available in V1.9.0 */
  proseWrap: 'preserve'./ * * *@desc Specified for an HTML file global space sensitivity, detail can see * https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting *@params* -css: respects the default value of the CSS display property * -strict: Spaces are considered sensitive * - ignore: Spaces are considered insensitive */
  htmlWhitespaceSensitivity: 'ignore'./ * * *@desc Whether to indent code inside <script> and <style> tags in Vue files. * Some people (such as Vue's creators) do not indent to preserve the indentation level, but this can break code folding in the editor. * /
  vueIndentScriptAndStyle: true./ * * *@desc For historical reasons, there are two common line-ending forms in text files. * are \n(or LF for line feed) and \r\n(or CRLF for carriage return + line feed). * The former is common on Linux and macOS, while the latter is common on Windows. *@params* - lf: only a newline (\ n) * - CRLF: enter + a newline character (\ r \ n) * - cr: only a carriage return (\ r) * - auto: maintenance of existing line end * /
  endOfLine: 'auto'};Copy the code

Optimize TS type inference

In the SRC directory

  • Create source.d.ts

    declare module '*.json';
    declare module '*.png';
    declare module '*.gif';
    declare module '*.jpg';
    declare module '*.jpeg';
    declare module '*.svg';
    declare module '*.css';
    declare module '*.less';
    declare module '*.scss';
    declare module '*.sass';
    Copy the code
  • Create a shim. Which s

    declare module '*.vue' {
      import Vue from 'vue';
      export default Vue;
    }
    declare module '*.tsx' {
      import Vue from 'vue';
      export default Vue;
    }
    Copy the code

Install the vue – the router

CNPM [email protected] I - DCopy the code
  • In the SRC directory, create a router folder

    index.ts

    import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router';
    
    const routes: RouteRecordRaw[] = [
    
    ];
    
    const router = createRouter({
      history: createWebHistory(process.env.BASE_URL),
      routes,
    });
    
    export default router;
    Copy the code

Install vuex

CNPM I - D [email protected]Copy the code
  • In the SRC directory, create a store folder

    index.ts

    import { createStore } from 'vuex';
    
    export default createStore({
      state:{},
      mutations: {},
      actions: {},
      modules: {},
    });
    Copy the code

Modify themain.js==>main.ts

import { createApp } from 'vue';
import App from './App';
import router from './router';
import store from './store';

createApp(App).use(router).use(store).mount('#app');
Copy the code

Modify the App. Vue = = > App. TSX

import { defineComponent } from 'vue'; import HelloWorld from './components/HelloWorld'; import img from './assets/logo.png'; export default defineComponent({ name: 'App', setup() { return () => ( <div id='app'> <img alt='Vue logo' src={img} /> <HelloWorld msg='Vue vite' /> </div> ); }});Copy the code

Modify theHelloWorld.vue==>HelloWorld.tsx

import { defineComponent, ref } from 'vue'; export default defineComponent({ name: 'HelloWorld', props: { msg: String, }, setup(props) { const count = ref<number>(0); return () => ( <div class="main"> <h1> {props.msg}</h1> <button>{count.value}</button> </div> ); }});Copy the code

run

npm run dev
Copy the code

Adding Page Routing

view/home/index.vue

<template> <div class="main"> <h1>Home</h1> <h2>{{ title }}</h2> </div> </template> <script lang="ts"> import { ref } from 'vue'; Export default {name: 'home', setup() {const title = ref<string>(' I am the title '); return { title }; }}; </script>Copy the code

view/about/index.tsx

import { defineComponent, ref } from 'vue';

export default defineComponent({
  name: 'about'.setup() {
    const title = ref<string> ('I'm the title, too.');
    return () = > (
      <div class='main'>
        <h1>About</h1>
        <h2>{title.value}</h2>
      </div>); }});Copy the code

Routing changes

import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router';

const routes: RouteRecordRaw[] = [
  {
    path: '/home'.name: 'home'.component: () = > import('.. /views/home/index.vue'),}, {path: '/about'.name: 'about'.component: () = > import('.. /views/about/index.tsx'),},];const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;
Copy the code

Home page app.tsx modified

import { defineComponent } from 'vue';
import HelloWorld from './components/HelloWorld';
import img from './assets/logo.png';
import { RouterView, RouterLink } from 'vue-router';

export default defineComponent({
  name: 'App'.setup() {
    return () = > (
      <div id='app'>{/* Use it directly<h2>Home</h2>Warning * /}<RouterLink to='/home'>{() = ><h2>Home</h2>}</RouterLink>
        <RouterLink to='/about'>{() = ><h2>About</h2>}</RouterLink>
        <img alt='Vue logo' src={img} />
        <HelloWorld msg='Vue vite' />
        <RouterView></RouterView>
      </div>); }});Copy the code

The use of the store

import { createStore } from 'vuex';

export default createStore({
  state: {
    title: 'store the title',},mutations: {},
  actions: {},
  modules: {},});Copy the code

App. The TSX is used

import { useStore } from 'vuex';
setup() {
    const { state } = useStore();

    return () = > (
      <div id='app'>
        <h3>{state.title}</h3>
      </div>
    );
 }
Copy the code