DEV Community

ziping
ziping

Posted on

A Vite plugin, unified team norms, do not do repetitive things

Since the team has been using Nuxt.js, I like many of its features, especially the convention-style directory structure. Vite really feels great after being exposed to it. Although it still lacks many features, most of them can make up for it by themselves. Taking advantage of the New Year holiday, I wrote a Vite plugin with a contracted directory structure. Access address: Document | GitHub

Get started

  1. Install convue.
yarn add convue -D
Enter fullscreen mode Exit fullscreen mode
  1. Use in the project

Use in vite.config.js

import convue from'convue';

export default defineConfig({
  plugins: [
    ...convue({}),
  ],
});
Enter fullscreen mode Exit fullscreen mode
  1. Introduce the required packages in main.js, if you don’t need them, you don’t need to introduce them
import {createApp} from'vue';
import App from'./src/App.vue';
import router from'pages-generated';
import globalComponent from'components-generated';
import store from'store-generated';
import plugin from'plugin-generated';
import i18n from'locale-generated';

const app = createApp(App);
window.__APP__ = app; // In order for the middleware to get the component instance, you can remove this line if you don’t need to use it

app.use(router);
app.use(globalComponent);
app.use(store);
app.use(plugin);
app.use(i18n);
app.mount('#app');
Enter fullscreen mode Exit fullscreen mode

Use cli

Convue provides a set of scaffolding tools for initializing projects. Currently, it supports two development modes: sfc (vue single file) and tsx.

# step 1
yarn global add convue-cli
# step 2-Enter convue in the command line, and you will be prompted for operation later
convue
# step 3-Enter project file
npm run dev
Enter fullscreen mode Exit fullscreen mode

Project Directory

Convue uses a convention-style catalog form, so we need to abide by this set of development methods. It is often an effective measure to achieve a unified standard in the project and improve efficiency.

If you need to change the directory structure, you can refer to configuration items.

Take the tsx form as an example:

.
├── public
├── src
    ├── components
    ├── layouts
        ├── default.tsx
    ├── locales
        ├── en-US.ts
        ├── zh-CN.ts
    ├── middleware
    ├── pages
        └── index.tsx
    ├── plugins
    ├── store
    └── App.tsx
├── .babelrc
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── .stylelintrc.json
├── index.html
├── package.json
├── shims.d.ts
├── tsconfig.json
├── vite.config.ts
├── yarn.lock
Enter fullscreen mode Exit fullscreen mode

Router

By default, convue will automatically load the .vue|.js|.jsx|.ts|.tsx file in the /src/pages directory and generate a route corresponding to the file name.

For example, the router address corresponding to the index.tsx file in the /src/pages directory is /, and the routing address corresponding to the user.tsx file is /user.

Dynamic router

The naming rule for dynamic router is: param[.vue|.js|.jsx|.ts|.tsx]

Add router information

Add a route tag in the /src/pages/index.tsx file.

{
  /* <route>
  name:'test'
  meta:
    title: 111
</route> */
}

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => <div></div>;
  },
});
Enter fullscreen mode Exit fullscreen mode

If it is sfc (vue single file), no comment is required.

The syntax supported by the route tag is'json5' |'json' |'yaml', the default is yaml, if it is json syntax, just specify the lang of the route.

{
  /* <route lang="json">
  {
    name:'test',
    meta: {
      title: 111
    }
  }
</route> */
}

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => <div></div>;
  },
});
Enter fullscreen mode Exit fullscreen mode

Router 404 redirect

When the address of the website is not in the routing registry, if there is a 404 page under /src/pages, it will be redirected to the /404 address, otherwise it will be redirected to the / address.

Layout

Layout refers to a container component in a public area of ​​a website.

By default, convue will load the .vue|.js|.jsx|.ts|.tsx file in the /src/layouts directory and import it into the routing table. The default loaded is default[.vue|.js|.jsx|. ts|.tsx].

The router-view component must be included in the file.

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => (
      <div>
        <span>default layout</span>
        <router-view></router-view>
      </div>
    );
  },
});
Enter fullscreen mode Exit fullscreen mode

Change the layout of the current page

Add a route tag to the file and specify the layout in meta. The value of layout corresponds to the file name under /src/layouts.

{
  /* <route>
  name:'test'
  meta:
    title: 111
    layout: empty
</route> */
}

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => <div></div>;
  },
});
Enter fullscreen mode Exit fullscreen mode

For other rules, please refer to layout configuration items.

Middleware

By default, convue will load the .ts | .js file in the /src/middleware directory and execute it in the pre-hook of the routing global.

For example, write an auth middleware

export default ({ redirect, store }) => {
  if (!store.state.isLogined) {
    redirect('/login');
  }
};
Enter fullscreen mode Exit fullscreen mode

Parameters

These parameters are provided to facilitate development:

-query: query parameter of the current route
-params: params parameters of the current route
-route: current route information
-redirect: redirect function, accept a url as a parameter
-store: access to global status
-app: current vue instance
-env: list of environment variables

For other rules, please refer to page configuration items.

loading

-Type: string
-Default: undefined

The loading color setting before the vue instance of the page is created

For the usage guide, please refer to head.

progress

-Type: boolean | Progress
-Default: true

Progress bar setting during route switching

If set to false, it will not be displayed and the code will not be introduced.

Progress type

export interface Progress {
  color?: string;
  size?: string;
}
Enter fullscreen mode Exit fullscreen mode

If you pass in an object, you can set the color and size of the progress bar.

Global store

By default, convue will load the .js|.ts file in the /src/store directory and configure it automatically in vuex.

The content structure of the file is unified with vuex, as follows

export default {
  state: () => (()),
  mutations: {},
  actions: {},
  getters: {},
};
Enter fullscreen mode Exit fullscreen mode

Description

The index[.js|.ts] under /src/store will load the vuex item directly, and other files will be configured in the form of modules.

For example, there are two files index.js and user.js.

index.js

export default {
  state: () => ({
    text:'hello',
  }),
};
Enter fullscreen mode Exit fullscreen mode

user.js

export default {
  state: () => ({
    name:'convue',
  }),
};
Enter fullscreen mode Exit fullscreen mode

Then the vuex store is actually this structure

export default {
  state: () => ({
    text:'hello',
  }),
  modules: {
    user: {
      state: () => ({
        text:'convue',
      }),
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

For other rules, please refer to store configuration items.

Global components

By default, convue will register the .vue|.js|.jsx|.ts|.tsx file in the /src/components directory as a global component.

For example, there is a Hello.tsx component under /src/components

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => <div>Hello Convue!</div>;
  },
});
Enter fullscreen mode Exit fullscreen mode

Use in the page

import {defineComponent} from'vue';
// import Hello from'/src/components/hello'; no need to load registration

export default defineComponent({
  setup() {
    return () => <hello></hello>;
  },
});
Enter fullscreen mode Exit fullscreen mode

It is recommended to use lowercase for global components, and big hump for custom components.

Multi-level directory

If there are multiple levels of directories under /src/components, then the naming of the components will be connected in the form of folder-file.

For example, src/components/app/navbar.tsx, then you need to add the app prefix (app-navbar) to use this component, and so on for more levels.

For other rules, please refer to component configuration items.

Plugin

By default, convue will automatically load the .js|.ts file in the /src/plugins directory.

For example, write a plugin file

import Antd from'ant-design-vue';
import'ant-design-vue/dist/antd.css';

export default ({ app }, inject) => {
  app.use(Antd);

  inject('sayHello', (obj) => {
    console.log('Hello Convue!');
  });
};
Enter fullscreen mode Exit fullscreen mode

Access the sayHello function

const instance = getCurrentInstance();
const toString = instance?.appContext.config.globalProperties.$toString;
Enter fullscreen mode Exit fullscreen mode

Parameters

The function has two parameters, the first is the information about the component instance, and the second is the inject function (functions registered through the inject function will be automatically loaded into app.config.global.properties).

The first parameter description:

-app: current vue instance
-store: access to global status
-router: current routing object
-route: current route information
-env: list of environment variables

For other rules, please refer to plugin configuration item.

Set the content of the head tag

Under normal circumstances, the head tag contains title, meta and link tags, and the srcript tag is usually written at the end of the body.

Placeholder

-Pass <!-- TITLE --> placeholder title tag content
-The meta and link tags that need to be loaded through the <!-- HEAD --> placeholder head tag
-Via <!-- APP --> placeholder elements mounted by the vue instance and loading

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><!-- TITLE --></title>
    <!-- HEAD -->
  </head>
  <body>
    <!-- APP -->
    <script type="module">
      // ...
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Global Settings

Passed in in the convue configuration item in vite.config.js is the global configuration

import {defineConfig} from'vite';
import convue from'convue';

export default defineConfig({
  plugins: [
    ...convue({
      head: {
        title:'Convue',
        meta: [
          {name:'language', content:'en-US' },
          {name:'author', content:'ziping' },
        ],
        link: [
          {
            rel:'dns-prefetch',
            href:'https://www.googletagmanager.com',
            crossorigin:'crossorigin',
          },
          {
            rel:'dns-prefetch',
            href:'https://www.google-analytics.com/analytics.js',
            crossorigin:'crossorigin',
          },
        ],
      },
    }),
  ],
});
Enter fullscreen mode Exit fullscreen mode

If the title is not passed, the name field in packgae.json will be taken by default.

Page individually set

We can also set the head separately for a page, and finally the head of the page will contain the content of the global settings plus the individual settings of the page.

The meta object is also used in the route tag.

{
  /* <route>
  name:'test'
  meta:
    head:
      title: Convue
      meta:
        -
          name: language
          content: en-US
        -
          name: author
          content: ziping
</route> */
}

import {defineComponent} from'vue';

export default defineComponent({
  setup() {
    return () => <div></div>;
  },
});
Enter fullscreen mode Exit fullscreen mode

For other rules, please refer to head configuration item.

Reference

-vite-plugin-pages
-vite-plugin-vue-layouts

Top comments (0)