版博士V2.0程序
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

128 rader
3.2 KiB

  1. import { posix } from 'path';
  2. import { getPackageInfo } from 'local-pkg';
  3. const normalizePath = (path) => {
  4. path = path.startsWith("/") ? path : "/" + path;
  5. return posix.normalize(path);
  6. };
  7. const isVite2 = async () => {
  8. const info = await getPackageInfo("vite");
  9. if (info) {
  10. return /.?2/.test(info.version);
  11. }
  12. return false;
  13. };
  14. const createPluginName = (reusable = false) => {
  15. let i = 0;
  16. return (name) => {
  17. const base = `vite-plugin-${name}`;
  18. return reusable ? `${base}:${i++}` : base;
  19. };
  20. };
  21. const createVirtualModuleID = (name) => {
  22. const virtualModuleId = `virtual:${name}`;
  23. const resolvedVirtualModuleId = "\0" + virtualModuleId;
  24. return {
  25. virtualModuleId,
  26. resolvedVirtualModuleId
  27. };
  28. };
  29. const createVirtualGlob = async (target, isSync) => {
  30. const g = `"${target}/**/*.vue"`;
  31. if (await isVite2()) {
  32. return isSync ? `import.meta.globEager(${g})` : `import.meta.glob(${g})`;
  33. }
  34. return `import.meta.glob(${g}, { eager: ${isSync} })`;
  35. };
  36. const createVirtualModuleCode = async (options) => {
  37. const { target, defaultLayout, importMode } = options;
  38. const normalizedTarget = normalizePath(target);
  39. const isSync = importMode === "sync";
  40. return `
  41. export const createGetRoutes = (router, withLayout = false) => {
  42. const routes = router.getRoutes()
  43. if (withLayout) {
  44. return routes
  45. }
  46. return () => routes.filter(route => !route.meta.isLayout)
  47. }
  48. export const setupLayouts = routes => {
  49. const layouts = {}
  50. const modules = ${await createVirtualGlob(
  51. normalizedTarget,
  52. isSync
  53. )}
  54. Object.entries(modules).forEach(([name, module]) => {
  55. let key = name.replace("${normalizedTarget}/", '').replace('.vue', '')
  56. layouts[key] = ${isSync ? "module.default" : "module"}
  57. })
  58. function deepSetupLayout(routes, top = true) {
  59. return routes.map(route => {
  60. if (route.children?.length > 0) {
  61. route.children = deepSetupLayout(route.children, false)
  62. }
  63. if (top) {
  64. return {
  65. path: route.path,
  66. component: layouts[route.meta?.layout || '${defaultLayout}'],
  67. children: [ {...route, path: ''} ],
  68. meta: {
  69. isLayout: true
  70. }
  71. }
  72. }
  73. if (route.meta?.layout) {
  74. return {
  75. path: route.path,
  76. component: layouts[route.meta?.layout],
  77. children: [ {...route, path: ''} ],
  78. meta: {
  79. isLayout: true
  80. }
  81. }
  82. }
  83. return route
  84. })
  85. }
  86. return deepSetupLayout(routes)
  87. }`;
  88. };
  89. const useName = createPluginName(false);
  90. const usePlugin = (options) => {
  91. const {
  92. target = "src/layouts",
  93. defaultLayout = "default",
  94. importMode = process.env.VITE_SSG ? "sync" : "async"
  95. } = options || {};
  96. const { virtualModuleId, resolvedVirtualModuleId } = createVirtualModuleID("meta-layouts");
  97. return {
  98. name: useName("vue-meta-layouts"),
  99. resolveId(id) {
  100. if (id === virtualModuleId) {
  101. return resolvedVirtualModuleId;
  102. }
  103. },
  104. load(id) {
  105. if (id === resolvedVirtualModuleId) {
  106. return createVirtualModuleCode({
  107. target,
  108. importMode,
  109. defaultLayout
  110. });
  111. }
  112. }
  113. };
  114. };
  115. export { usePlugin as default };