UNPKG

@bitrix24/b24ui-nuxt

Version:

Bitrix24 UI-Kit for developing web applications REST API for NUXT & VUE

250 lines (241 loc) 9.39 kB
import { fileURLToPath } from 'node:url'; import { join, normalize } from 'pathe'; import { createUnplugin } from 'unplugin'; import { defu } from 'defu'; import tailwind from '@tailwindcss/vite'; import { g as getTemplates, d as defaultOptions, a as getDefaultUiConfig } from './shared/b24ui-nuxt.COkgCO-x.mjs'; import { globSync } from 'tinyglobby'; import { genSafeVariableName } from 'knitwork'; import MagicString from 'magic-string'; import { resolvePathSync } from 'mlly'; import AutoImportComponents from 'unplugin-vue-components'; import AutoImport from 'unplugin-auto-import'; import 'scule'; import '@nuxt/kit'; function TemplatePlugin(options) { const templates = getTemplates(options); const templateKeys = new Set(templates.map((t) => `#build/${t.filename}`)); return { name: "bitrix24:b24ui:templates", enforce: "pre", resolveId(id) { if (templateKeys.has(id + ".ts")) { return id.replace("#build/", "virtual:bitrix24-ui-templates/") + ".ts"; } }, loadInclude: (id) => templateKeys.has(id.replace("virtual:bitrix24-ui-templates/", "#build/")), load(id) { id = id.replace("virtual:bitrix24-ui-templates/", "#build/"); return templates.find((t) => `#build/${t.filename}` === id).getContents({}); } }; } function PluginsPlugin(options) { const plugins = globSync(["**/*", "!*.d.ts"], { cwd: join(runtimeDir, "plugins"), absolute: true }); plugins.unshift(resolvePathSync("../runtime/vue/plugins/head", { extensions: [".ts", ".mjs", ".js"], url: import.meta.url })); if (options.colorMode) { plugins.push(resolvePathSync("../runtime/vue/plugins/color-mode", { extensions: [".ts", ".mjs", ".js"], url: import.meta.url })); } return { name: "bitrix24:b24ui:plugins", enforce: "pre", resolveId(id) { if (id === "@bitrix24/b24ui-nuxt/vue-plugin") { return "virtual:bitrix24-ui-plugins"; } }, transform(code, id) { if (plugins.some((p) => id.startsWith(p)) && code.includes("import.meta.client")) { const s = new MagicString(code); s.replaceAll("import.meta.client", "true"); if (s.hasChanged()) { return { code: s.toString(), map: s.generateMap({ hires: true }) }; } } }, loadInclude: (id) => id === "virtual:bitrix24-ui-plugins", load() { return ` ${plugins.map((p) => `import ${genSafeVariableName(p)} from "${p}"`).join("\n")} export default { install (app) { ${plugins.map((p) => ` app.use(${genSafeVariableName(p)})`).join("\n")} } } `; }, // Argument Vite specific configuration vite: { config() { return { // Opt-out Bitrix24 UI from Vite's pre-bundling, // as we need Vite's pipeline to resolve imports like `#imports` optimizeDeps: { exclude: ["@bitrix24/b24ui-nuxt"] } }; } } }; } function AppConfigPlugin(options, appConfig) { return { name: "bitrix24:b24ui:app-config", enforce: "pre", resolveId(id) { if (id === "#build/app.config") { return "virtual:bitrix24-ui-app-config"; } }, loadInclude: (id) => id === "virtual:bitrix24-ui-app-config", load() { return ` export default ${JSON.stringify(appConfig)} `; }, vite: { config() { return { test: { server: { deps: { inline: ["@bitrix24/b24ui"] } } } }; } } }; } function ComponentImportPlugin(options, meta) { const components = globSync("**/*.vue", { cwd: join(runtimeDir, "components") }); const componentNames = new Set(components.map((c) => `B24${c.replace(/\.vue$/, "")}`)); const componentsContent = globSync("**/*.vue", { cwd: join(runtimeDir, "components/content") }); const componentContentNames = new Set(componentsContent.map((c) => `B24${c.replace(/\.vue$/, "")}`)); const inertiaOverrides = globSync("**/*.vue", { cwd: join(runtimeDir, "inertia/components") }); const inertiaOverrideNames = new Set(inertiaOverrides.map((c) => `B24${c.replace(/\.vue$/, "")}`)); const componentsProse = globSync("**/*.vue", { cwd: join(runtimeDir, "prose") }); const componentProseNames = new Set(componentsProse.map((c) => `Prose${c.replace(/\.vue$/, "")}`)); const overrides = globSync("**/*.vue", { cwd: join(runtimeDir, "vue/components") }); const overrideNames = new Set(overrides.map((c) => `B24${c.replace(/\.vue$/, "")}`)); const pluginOptions = defu(options.components, { dts: options.dts ?? true, exclude: [ /[\\/]node_modules[\\/](?!\.pnpm|@bitrix24\/b24ui-nuxt|@compodium\/examples)/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/ ], resolvers: [ (componentName) => { if (options.inertia && inertiaOverrideNames.has(componentName)) { return { name: "default", from: join(runtimeDir, "inertia/components", `${componentName.slice("B24".length)}.vue`) }; } if (overrideNames.has(componentName)) return { name: "default", from: join(runtimeDir, "vue/components", `${componentName.slice("B24".length)}.vue`) }; if (componentProseNames.has(componentName)) return { name: "default", from: join(runtimeDir, "prose", `${componentName.slice("Prose".length)}.vue`) }; if (componentContentNames.has(componentName)) return { name: "default", from: join(runtimeDir, "components/content", `${componentName.slice("B24".length)}.vue`) }; if (componentNames.has(componentName)) return { name: "default", from: join(runtimeDir, "components", `${componentName.slice("B24".length)}.vue`) }; } ] }); return [ /** * This plugin aims to ensure we override certain components with Vue-compatible versions: * <B24Link> currently. */ { name: "bitrix24:b24ui:components", enforce: "pre", resolveId(id, importer) { if (!importer) { return; } if (!normalize(importer).includes(runtimeDir) && (!options.extraRuntimeDir || !normalize(importer).includes(options.extraRuntimeDir))) { return; } if (!RELATIVE_IMPORT_RE.test(id) && !id.startsWith("@bitrix24/b24ui-nuxt/components/")) { return; } const filename = id.match(/([^/]+)\.vue$/)?.[1]; if (filename && options.inertia && inertiaOverrideNames.has(`B24${filename}`)) { return join(runtimeDir, "inertia/components", `${filename}.vue`); } if (filename && overrideNames.has(`B24${filename}`)) { return join(runtimeDir, "vue/components", `${filename}.vue`); } } }, AutoImportComponents.raw(pluginOptions, meta) ]; } const RELATIVE_IMPORT_RE = /^\.{1,2}\//; function Bitrix24EnvironmentPlugin(options) { const stubPath = resolvePathSync(options.inertia ? "../runtime/inertia/stubs" : "../runtime/vue/stubs", { extensions: [".ts", ".mjs", ".js"], url: import.meta.url }); return { name: "bitrix24:b24ui", enforce: "pre", resolveId(id) { if (id === "#imports") { return stubPath; } }, transformInclude(id) { return normalize(id).includes(runtimeDir); }, transform(code) { if (code.includes("import.meta.client")) { const s = new MagicString(code); s.replaceAll("import.meta.client", "true"); if (s.hasChanged()) { return { code: s.toString(), map: s.generateMap({ hires: true }) }; } } } }; } function AutoImportPlugin(options, meta) { const pluginOptions = defu(options.autoImport, { dts: options.dts ?? true, dirs: [join(runtimeDir, "composables"), join(runtimeDir, "vue/composables")] }); return AutoImport.raw(pluginOptions, meta); } const runtimeDir = normalize(fileURLToPath(new URL("./runtime", import.meta.url))); const Bitrix24UIPlugin = createUnplugin((_options = {}, meta) => { const options = defu(_options, {}, defaultOptions); const appConfig = defu({ b24ui: options.b24ui, colorMode: options.colorMode }, { b24ui: getDefaultUiConfig() }); return [ Bitrix24EnvironmentPlugin(options), ComponentImportPlugin(options, meta), AutoImportPlugin(options, meta), tailwind(), PluginsPlugin(options), TemplatePlugin(options), AppConfigPlugin(options, appConfig), { name: "bitrix24:b24ui:plugins-duplication-detection", vite: { configResolved(config) { const plugins = config.plugins || []; if (plugins.filter((i) => i.name === "unplugin-auto-import").length > 1) { throw new Error("[Bitrix24 UI] Multiple instances of `unplugin-auto-import` detected. Bitrix24 UI includes `unplugin-auto-import` already, and you can configure it using `autoImport` option in Bitrix24 UI module options."); } if (plugins.filter((i) => i.name === "unplugin-vue-components").length > 1) { throw new Error("[Bitrix24 UI] Multiple instances of `unplugin-vue-components` detected. Bitrix24 UI includes `unplugin-vue-components` already, and you can configure it using `components` option in Bitrix24 UI module options."); } } } } ].flat(1); }); export { Bitrix24UIPlugin, runtimeDir };