-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathnuxt.config.ts
More file actions
230 lines (222 loc) · 7.85 KB
/
Copy pathnuxt.config.ts
File metadata and controls
230 lines (222 loc) · 7.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import { fileURLToPath } from "node:url";
import { createRequire } from "node:module";
import { dirname, join } from "node:path";
// Docus enables its AI assistant whenever AI_GATEWAY_API_KEY / VERCEL_OIDC_TOKEN
// exist at build time. Vercel always injects VERCEL_OIDC_TOKEN and offers no way to
// turn it off (only a Team/Global toggle) — https://vercel.com/docs/oidc
delete process.env.AI_GATEWAY_API_KEY;
delete process.env.VERCEL_OIDC_TOKEN;
// Absolute path to vue's ESM server-renderer shim (vue/server-renderer/index.mjs).
// Used by the nitro.alias below to fix an ERR_MODULE_NOT_FOUND on Vercel — see
// the comment there.
const vueServerRendererEntry = join(
dirname(createRequire(import.meta.url).resolve("vue/package.json")),
"server-renderer/index.mjs",
);
// The meteor components import vue-i18n@9 (their nested copy) and call
// useI18n() at setup. The docs app must install an i18n instance from the
// SAME copy, so alias vue-i18n to the component library's version for both
// the app plugin and the bundled components.
const vueI18nPath = fileURLToPath(
new URL(
"../../packages/component-library/node_modules/vue-i18n",
import.meta.url,
),
);
// vue-i18n@9 (aliased above) imports @intlify internals. Alias those to the
// SAME nested v9 copies, otherwise the docs build mixes them with the root v11
// @intlify (which removed `compileToFunction`) → SyntaxError at runtime on Vercel.
const meteorIntlifyPath = (pkg: string) =>
fileURLToPath(
new URL(
`../../packages/component-library/node_modules/@intlify/${pkg}`,
import.meta.url,
),
);
// The meteor component library barrel (its index.js) imports a global CSS
// reset (dist/index.css) that retargets bare elements (*, body, button,
// h1-h6) and leaks onto the docs typography. The docs deliberately do not
// load it (see app/assets/css/main.css). Some examples must import from the
// barrel (e.g. the action-menu dropdown primitives have no subpath), so drop
// that one stylesheet by redirecting it to an empty file.
const meteorResetNoopPath = fileURLToPath(
new URL("./app/assets/css/meteor-reset-noop.css", import.meta.url),
);
const dropMeteorGlobalReset = {
name: "drop-meteor-global-reset",
enforce: "pre" as const,
resolveId(source: string, importer?: string) {
if (
source.endsWith("index.css") &&
importer &&
importer.replace(/\\/g, "/").includes("component-library/dist/")
) {
return meteorResetNoopPath;
}
return null;
},
};
const shikiTheme = {
light: "github-light",
default: "github-dark-default",
dark: "github-dark-default",
} as const;
export default defineNuxtConfig({
extends: ["docus"],
// Drives the page-title suffix (Docus' default titleTemplate `%s - <site.name>`),
// the OG site name, and the sitemap. Without this it falls back to the
// package.json name ("meteor-docs").
site: {
name: "Shopware Meteor",
// Absolute base for generated og:image URLs (and sitemap entries). Override
// per environment with NUXT_SITE_URL.
url: "https://meteor.shopware.com",
},
// modules/ is auto-scanned, so meteor-components and component-examples load
// automatically. meteor-components registers its work via the
// `component-meta:extend` hook (fired during the build), so module order
// relative to nuxt-component-meta does not matter; only the third-party
// module needs listing here.
modules: ["nuxt-component-meta"],
// Token dictionaries (the source of truth for the foundation token tables).
// A Nuxt alias is added to both Vite and the tsconfig paths.
alias: {
"@tokens-dict": fileURLToPath(
new URL("../../packages/tokens/dictionaries", import.meta.url),
),
"@icon-kit": fileURLToPath(
new URL("../../packages/icon-kit", import.meta.url),
),
},
componentMeta: {
// Only analyze the meteor component library, not docus/Nuxt UI internals.
exclude: [
(component: { filePath?: string }) =>
!component.filePath?.includes("packages/component-library"),
],
metaFields: {
type: false,
props: true,
slots: true,
events: true,
exposed: true,
},
},
app: {
head: {
link: [
{
rel: "icon",
type: "image/svg+xml",
href: "/shopware-signet.svg",
},
],
},
},
css: [
"@shopware-ag/meteor-component-library/font.css",
"~/assets/css/main.css",
],
fonts: {
families: [
// Inter is already self-hosted via @shopware-ag/meteor-component-library/font.css
// (loaded above). Stop @nuxt/fonts (inherited from the docus layer) from
// re-resolving it from a remote provider, which otherwise fetches
// fonts.bunny.net at dev/build/test time and injects a duplicate @font-face.
{ name: "Inter", provider: "none" },
],
},
colorMode: {
dataValue: "theme",
},
llms: {
domain: "https://meteor.shopware.com",
// Disable @nuxt/content's built-in /raw/*.md route so our own route in
// server/routes/raw takes over (it converts dynamic MDC components like
// :component-props into plain markdown). Link rewriting to /raw/*.md is
// re-added in server/plugins/llms.ts.
contentRawMarkdown: false,
},
content: {
renderer: {
alias: {
tabs: "ResponsiveTabs",
},
},
build: {
markdown: {
highlight: {
theme: shikiTheme,
},
},
},
},
mdc: {
highlight: {
noApiRoute: false,
shikiEngine: "javascript",
theme: shikiTheme,
},
},
nitro: {
// Nitro inlines `vue` but leaves a bare `import "vue/server-renderer"` in the
// server bundle that resolves to a non-existent node_modules/vue on Vercel
// → ERR_MODULE_NOT_FOUND. Alias the subpath to vue's real ESM shim so Nitro
// resolves and inlines it instead of emitting a dangling external import.
alias: {
"vue/server-renderer": vueServerRendererEntry,
},
},
vite: {
plugins: [dropMeteorGlobalReset],
css: {
// The component library's built mt-datepicker.css carries a stale
// `/*# sourceMappingURL=main.css.map */` comment (inherited from the
// bundled @vuepic/vue-datepicker vendor CSS), but no .css.map files are
// emitted to its dist. The dev server otherwise chases that dangling
// reference and logs an ENOENT "Failed to load source map" warning.
devSourcemap: false,
},
resolve: {
alias: {
"vue-i18n": vueI18nPath,
"@intlify/core-base": meteorIntlifyPath("core-base"),
"@intlify/message-compiler": meteorIntlifyPath("message-compiler"),
"@intlify/shared": meteorIntlifyPath("shared"),
},
},
optimizeDeps: {
// Exclude the component library so its barrel import is processed by
// Vite (and the dropMeteorGlobalReset plugin) rather than esbuild's dep
// pre-bundler, which would inline the global reset and bypass the plugin.
exclude: ["@shopware-ag/meteor-component-library"],
include: [
// vue-i18n (aliased above to the component library's nested copy) and
// apexcharts (pulled in by mt-chart) are otherwise discovered at
// runtime, which triggers a re-optimize and full page reload.
"vue-i18n",
"apexcharts",
"@vueuse/core",
"remark-emoji",
"remark-mdc",
"@shikijs/core",
"@shikijs/engine-javascript",
"@shikijs/transformers",
"@shikijs/langs/css",
"@shikijs/langs/diff",
"@shikijs/langs/html",
"@shikijs/langs/javascript",
"@shikijs/langs/json",
"@shikijs/langs/markdown",
"@shikijs/langs/mdc",
"@shikijs/langs/shellscript",
"@shikijs/langs/typescript",
"@shikijs/langs/vue",
"@shikijs/langs/yaml",
"@shikijs/themes/github-dark-default",
"@shikijs/themes/github-light",
],
},
},
devtools: { enabled: false },
});