Public account: wechat search front end tool person; Take more dry goods
Introduce a,
I used to build projects with Webpack, but the frustration of running, packing, and hot update slowly as the project got bigger and bigger…
Vite2.0 is used in new project development. Compared with Webpack, other advantages are not very intuitive, but there is a multiple gap in operation, packaging and hot update. I can only say that VITe2.0 is very comfortable.
Of course, vite as a popular build advantages or a lot of details can go to the official website to see the vite official website address
Second, the problem of
/ / the problem code () = > import (/ * @ vite - ignore * / ` ${fileSrc} `) routerList. Push ({path: ` / ${routerPath} `, name: `${routerName}`, component: () => import( /* @vite-ignore */ `${fileSrc}`) })Copy the code
Before building projects using Webpack, we used the require.context API to automatically register components and routes.
When you move to Vite, your development habits don’t change; Import. Meta. GlobEager is used to dynamically import.
Local development process is very comfortable no problem, packaged deployment to the server error can not find the dynamic import of the file; Break ~ ~ ~
After several days of continuous attempts to solve the final, summarized the following schemes
3, requirements,
Main project structure
├─ ├─ // ├─ // ├─ // ├─ // └─ // // // // // // // // // // // // // // // // // // // // / ├ ─ imp (// Home) ├ ─ imp (// Home) ├ ─ imp (// Home) ├ ─ imp (// Home ├ ─ 082 // LoginHeader // LoginHeader // logimp // LoginHeader // logimp // logimp // LoginHeader // logimp // logimp // logimp // logimp // logimp // logimp // logimp // logimp // .Copy the code
Inside the file
export default defineComponent({ name: 'home', isRouter: true, isComponents: false, setup() { ... }})Copy the code
Components are defined internally
name
: Indicates the name of the routing componentisRouter
: Indicates whether the route is automatically configured.isComponents
: Whether to automatically register as a public component
Iv. Solution (Recommended Scheme 2)
There are two ways to import vite dynamically
-
Import.meta. glob: By dynamically importing the default lazy load, you can get the details of the corresponding module file by traversing and then method
-
Import.meta. globEager: Import all modules directly, that is, static import; Mine is using this package deployment error
The following schemes need to be selected by yourself
Scheme 4.1 a
Using the import. Meta. Glob
Disadvantages:
- Do not use
then
Method can not get module information, can not determine whether automatic registration of components or routes; - Using the
then
Method becomes asynchronous, route rendering time file has not been successfully registered
But you can have separate folders, which I think are too restrictive and not elegant;
// global.ts export const vueRouters = function (): Array<RouteRecordRaw> { let routerList: Array<RouteRecordRaw> = []; const modules = import.meta.glob('.. /views/**/*.vue') Object.keys(modules).forEach(key => { const nameMatch = key.match(/^\.\.\/views\/(.+)\.vue/) if(! nameMatch) return const indexMatch = nameMatch[1].match(/(.*)\/Index$/i) let name = indexMatch ? indexMatch[1] : nameMatch[1]; RouterList. Push ({path: '/${letterToLowerCase(name)}', name: `${letterToUpperCase(name)}`, component: modules[key] }); }) return routerList };Copy the code
The use of the router. Ts
import { vueRouters } from '.. /services/global' const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Login', component: () => import('@/views/Login/index.vue') }, ...vueRouters() ]Copy the code
4.2 Solution 2 Recommendation
Use import.meta. Glob and import.meta
import.meta.glob
Because:import.meta.glob
The obtained files are lazily loaded to avoid useimport
Statement, so no errors are reported after packaging and there is no dynamic introduction anymoreimport.meta.globEager
: do not usethen
It can also obtain the global context of the file for necessary judgment
// global.ts function getModules() { const components = import.meta.glob('.. /views/**/*.vue') return components } function getComponents() { const components = import.meta.globEager('.. /views/**/*.vue') return components} // export const asyncComponent = function (app: app <Element>): void { const modules = getModules(); const components = getComponents(); Object.keys(modules).forEach((key: string) => { const viewSrc = components[key]; const file = viewSrc.default; if (! file.isComponents) return const AsyncComponent = defineAsyncComponent(modules[key]) app.component(letterToUpperCase(file.name), AsyncComponent) }); // console.log(app._component.components) }; Export const vueRouters = function (): Array<RouteRecordRaw> {let routerList: Array<RouteRecordRaw> = []; const modules = getModules(); const components = getComponents(); Object.keys(modules).forEach(key => { const viewSrc = components[key]; const file = viewSrc.default; if (! File.isrouter) return // change the initial letterToLowerCase letterToLowerCase change the initial letterToUpperCase letterToUpperCase routerlist.push ({path: `/${letterToLowerCase(file.name)}`, name: `${letterToUpperCase(file.name)}`, component: modules[key] }); }) return routerList }Copy the code
Using router.ts (Route registration)
import { vueRouters } from '.. /services/global' const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Login', component: () => import('@/views/Login/index.vue') }, ...vueRouters() ]Copy the code
Using Main.ts (component registration)
import { asyncComponent } from './services/global';
export const app = createApp(App)
asyncComponent(app)
Copy the code
4.3 plan three
Use the then method of import.meta.glob with the built-in addRoute () method.
- Due to lazy file loading fetch, page loading has obvious lag
- Does not apply to registered components
- The addRoute() method is used to register authentication routes based on the route permission returned by the background interface
// global.ts export const vueRouters = function (router: Router): void { let routerList: Array<RouteRecordRaw> = []; const modules = import.meta.glob('.. /views/**/*.vue') for (const path in modules) { modules[path]().then((mod) => { const file = mod.default; if (! File. isRouter) return // Uppercase to Lowercase letterToLowerCase to uppercase letterToUpperCase Route. addRoute({path: `/${letterToLowerCase(file.name)}`, name: `${letterToUpperCase(file.name)}`, component: file }) }) } };Copy the code
The use of the router. Ts
import { vueRouters } from '.. /services/global' const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Login', component: () => import('@/views/Login/index.vue') } ] const router = createRouter({ history: createWebHashHistory(), routes }) vueRouters(router)Copy the code