@poveste/plugin-nuxt 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +39 -10
- package/package.json +37 -10
- package/runtime/tolerant-plugins.mjs +28 -0
- package/src/global.d.ts +0 -5
- package/src/index.ts +0 -230
- package/src/runtime/app-setup.ts +0 -72
- package/tsconfig.json +0 -40
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Guillaume Chau (original "histoire" project)
|
|
4
|
+
Copyright (c) 2026 Sorin Gitlan (poveste fork)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export interface HstNuxtOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
excludePlugins?: (string | RegExp)[];
|
|
9
9
|
}
|
|
10
|
+
export declare function isPluginExcluded(src: string, patterns: (string | RegExp)[]): boolean;
|
|
11
|
+
export declare function wrapPluginsForTolerantBoot(source: string): string;
|
|
10
12
|
export declare function HstNuxt(options?: HstNuxtOptions): Plugin;
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,30 @@ const ignorePlugins = [
|
|
|
10
10
|
'nuxt:import-protection',
|
|
11
11
|
];
|
|
12
12
|
// Some Nuxt modules register client plugins that assume a full Nuxt runtime the
|
|
13
|
-
// headless story sandbox can't provide
|
|
14
|
-
//
|
|
15
|
-
//
|
|
13
|
+
// headless story sandbox can't provide. The general net is `wrapPluginsForTolerantBoot`
|
|
14
|
+
// below, which skips one that throws rather than 500-ing the iframe; this list drops
|
|
15
|
+
// known offenders before they run at all — @nuxtjs/i18n by default (#65), plus whatever
|
|
16
|
+
// `excludePlugins` adds (#277), which is also the only lever for a plugin that throws at
|
|
17
|
+
// import, before the tolerant wrapper can catch it.
|
|
16
18
|
const DEFAULT_EXCLUDED_PLUGINS = [/[\\/]@nuxtjs[\\/]i18n[\\/].*[\\/]plugins[\\/]/];
|
|
19
|
+
// Whether a resolved plugin `src` matches any exclusion pattern. `match`, not
|
|
20
|
+
// `test`: it doesn't advance a caller's /g regex `lastIndex`, so matching stays
|
|
21
|
+
// stateless without mutating an input we don't own.
|
|
22
|
+
export function isPluginExcluded(src, patterns) {
|
|
23
|
+
return patterns.some(pattern => typeof pattern === 'string' ? src.includes(pattern) : src.match(pattern) !== null);
|
|
24
|
+
}
|
|
25
|
+
// Wrap Nuxt's generated client-plugin list so each plugin boots tolerantly
|
|
26
|
+
// (#277): map the exported array through `__povesteTolerant`. Reuses Nuxt's own
|
|
27
|
+
// ordering by transforming its output rather than reimplementing it. Returns the
|
|
28
|
+
// source untouched if the `export default [...]` shape is not found, so an
|
|
29
|
+
// upstream format change degrades to today's behaviour instead of breaking.
|
|
30
|
+
export function wrapPluginsForTolerantBoot(source) {
|
|
31
|
+
const wrapped = source.replace(/export default (\[[\s\S]*?\])/, 'export default $1.map(__povesteTolerant)');
|
|
32
|
+
if (wrapped === source) {
|
|
33
|
+
return source;
|
|
34
|
+
}
|
|
35
|
+
return `import { __povesteTolerant } from '#build/poveste/tolerant-plugins.mjs'\n${wrapped}`;
|
|
36
|
+
}
|
|
17
37
|
export function HstNuxt(options = {}) {
|
|
18
38
|
let nuxt;
|
|
19
39
|
return {
|
|
@@ -132,20 +152,29 @@ async function useNuxtViteConfig(excludePlugins) {
|
|
|
132
152
|
throw new Error(`Poveste only supports Vite bundler, but Nuxt builder is currently set to '${nuxt.options.builder}'.`);
|
|
133
153
|
}
|
|
134
154
|
const runtimeDir = fileURLToPath(new URL('../runtime', import.meta.url));
|
|
135
|
-
nuxt.options.build.templates.push({ src: join(runtimeDir, 'composables.mjs'), filename: 'poveste/composables.mjs' }, { src: join(runtimeDir, 'components.mjs'), filename: 'poveste/components.mjs' });
|
|
155
|
+
nuxt.options.build.templates.push({ src: join(runtimeDir, 'composables.mjs'), filename: 'poveste/composables.mjs' }, { src: join(runtimeDir, 'components.mjs'), filename: 'poveste/components.mjs' }, { src: join(runtimeDir, 'tolerant-plugins.mjs'), filename: 'poveste/tolerant-plugins.mjs' });
|
|
136
156
|
// Drop the sandbox-incompatible client plugins named by `excludePlugins`, so
|
|
137
157
|
// they don't 500 the story iframe on entry boot. See DEFAULT_EXCLUDED_PLUGINS.
|
|
138
158
|
nuxt.hook('app:resolve', (app) => {
|
|
139
|
-
app.plugins = app.plugins.filter(
|
|
140
|
-
const src = p.src ?? '';
|
|
141
|
-
// `match`, not `test`: it doesn't advance a caller's /g regex `lastIndex`, so
|
|
142
|
-
// matching stays stateless without mutating an input we don't own.
|
|
143
|
-
return !excludePlugins.some(pattern => typeof pattern === 'string' ? src.includes(pattern) : src.match(pattern) !== null);
|
|
144
|
-
});
|
|
159
|
+
app.plugins = app.plugins.filter(p => !isPluginExcluded(p.src ?? '', excludePlugins));
|
|
145
160
|
});
|
|
146
161
|
nuxt.hook('app:templates', (app) => {
|
|
147
162
|
app.templates = app.templates.filter(template => template.filename !== 'app-component.mjs');
|
|
148
163
|
app.templates.push({ src: join(runtimeDir, 'app-component.mjs'), filename: 'app-component.mjs' });
|
|
164
|
+
// Tolerant boot (#277): wrap each generated client plugin so one that throws
|
|
165
|
+
// while setting up in the sandbox is logged and skipped, not fatal to the
|
|
166
|
+
// whole iframe. `excludePlugins` drops what we know can't run; this catches
|
|
167
|
+
// the rest.
|
|
168
|
+
for (const template of app.templates) {
|
|
169
|
+
if (template.filename !== 'plugins.client.mjs' && template.filename !== 'plugins.server.mjs') {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const original = template.getContents;
|
|
173
|
+
if (!original) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
template.getContents = async (ctx) => wrapPluginsForTolerantBoot(await original(ctx));
|
|
177
|
+
}
|
|
149
178
|
});
|
|
150
179
|
nuxt.hook('imports:sources', (presets) => {
|
|
151
180
|
const polyfills = ['requestIdleCallback', 'cancelIdleCallback'];
|
package/package.json
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poveste/plugin-nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"description": "Poveste plugin to integrate with Nuxt 4",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"homepage": "https://poveste.dev",
|
|
10
11
|
"repository": {
|
|
11
12
|
"url": "https://github.com/poveste-dev/poveste.git",
|
|
12
13
|
"type": "git",
|
|
13
14
|
"directory": "packages/poveste-plugin-nuxt"
|
|
14
15
|
},
|
|
16
|
+
"bugs": "https://github.com/poveste-dev/poveste/issues",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"poveste",
|
|
19
|
+
"histoire",
|
|
20
|
+
"storybook",
|
|
21
|
+
"component-playground",
|
|
22
|
+
"component-explorer",
|
|
23
|
+
"stories",
|
|
24
|
+
"styleguide",
|
|
25
|
+
"design-system",
|
|
26
|
+
"vite",
|
|
27
|
+
"nuxt",
|
|
28
|
+
"nuxt4",
|
|
29
|
+
"vue",
|
|
30
|
+
"plugin",
|
|
31
|
+
"module"
|
|
32
|
+
],
|
|
15
33
|
"publishConfig": {
|
|
16
34
|
"access": "public"
|
|
17
35
|
},
|
|
@@ -22,14 +40,17 @@
|
|
|
22
40
|
"main": "./dist/index.js",
|
|
23
41
|
"module": "./dist/index.js",
|
|
24
42
|
"types": "./dist/index.d.ts",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"runtime"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
28
49
|
},
|
|
29
50
|
"peerDependencies": {
|
|
30
|
-
"@poveste/plugin-vue": "workspace:^",
|
|
31
51
|
"nuxt": "^4.5.0",
|
|
32
|
-
"poveste": "
|
|
52
|
+
"poveste": "^0.7.0",
|
|
53
|
+
"@poveste/plugin-vue": "^0.7.0"
|
|
33
54
|
},
|
|
34
55
|
"dependencies": {
|
|
35
56
|
"@nuxt/kit": "^4.5.2",
|
|
@@ -41,8 +62,14 @@
|
|
|
41
62
|
"devDependencies": {
|
|
42
63
|
"@nuxt/schema": "^4.5.2",
|
|
43
64
|
"@types/node": "^22.10.1",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
65
|
+
"typescript": "5.6.3",
|
|
66
|
+
"vite": "^8.2.0",
|
|
67
|
+
"vitest": "^4.1.10",
|
|
68
|
+
"poveste": "0.7.0"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "rimraf dist && tsc -d",
|
|
72
|
+
"watch": "tsc -d -w --sourceMap",
|
|
73
|
+
"test": "vitest run"
|
|
47
74
|
}
|
|
48
|
-
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Wrap a resolved Nuxt client plugin so a throw while it sets up in the headless
|
|
2
|
+
// story sandbox is logged and skipped, instead of aborting the rest of the boot
|
|
3
|
+
// and painting an error into the iframe (#277). Nuxt's `applyPlugins` stops at
|
|
4
|
+
// the first plugin that throws, so without this one sandbox-hostile module takes
|
|
5
|
+
// down every plugin after it. Metadata (`_name`, `order`, `dependsOn`, ...) is
|
|
6
|
+
// copied over so ordering and dependency resolution are unchanged.
|
|
7
|
+
//
|
|
8
|
+
// This catches setup-time failures only. A plugin that throws at module import
|
|
9
|
+
// fails before this runs — drop those with HstNuxt({ excludePlugins }).
|
|
10
|
+
export function __povesteTolerant(plugin) {
|
|
11
|
+
if (typeof plugin !== 'function') {
|
|
12
|
+
return plugin
|
|
13
|
+
}
|
|
14
|
+
const wrapped = async (nuxtApp) => {
|
|
15
|
+
try {
|
|
16
|
+
return await plugin(nuxtApp)
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.warn(
|
|
20
|
+
`[poveste] Nuxt client plugin ${plugin._name ?? plugin.name ?? '(anonymous)'} `
|
|
21
|
+
+ 'threw while setting up in the story sandbox; skipping it. Drop it with '
|
|
22
|
+
+ 'HstNuxt({ excludePlugins }) if it can never run headless.',
|
|
23
|
+
error,
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return Object.assign(wrapped, plugin)
|
|
28
|
+
}
|
package/src/global.d.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import type { Nuxt } from '@nuxt/schema'
|
|
2
|
-
import type { Plugin } from 'poveste'
|
|
3
|
-
import type { UserConfig as ViteConfig } from 'vite'
|
|
4
|
-
import { join } from 'node:path'
|
|
5
|
-
import { fileURLToPath } from 'node:url'
|
|
6
|
-
import replace from '@rollup/plugin-replace'
|
|
7
|
-
|
|
8
|
-
const ignorePlugins = [
|
|
9
|
-
'nuxt:vite-node-server',
|
|
10
|
-
'nuxt:dev-style-ssr',
|
|
11
|
-
'nuxt:vite-relative-asset',
|
|
12
|
-
'nuxt:cache-dir',
|
|
13
|
-
'nuxt:dynamic-base-path',
|
|
14
|
-
'nuxt:import-protection',
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
export interface HstNuxtOptions {
|
|
18
|
-
/**
|
|
19
|
-
* Client plugins to drop from the story sandbox, matched against each
|
|
20
|
-
* plugin's resolved `src` (string `includes` or `RegExp`). Added on top of
|
|
21
|
-
* the built-in defaults, not replacing them.
|
|
22
|
-
*/
|
|
23
|
-
excludePlugins?: (string | RegExp)[]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Some Nuxt modules register client plugins that assume a full Nuxt runtime the
|
|
27
|
-
// headless story sandbox can't provide, so they 500 the iframe on entry boot;
|
|
28
|
-
// @nuxtjs/i18n's are dropped by default (#65), and `excludePlugins` drops more
|
|
29
|
-
// without patching this package (#277).
|
|
30
|
-
const DEFAULT_EXCLUDED_PLUGINS: (string | RegExp)[] = [/[\\/]@nuxtjs[\\/]i18n[\\/].*[\\/]plugins[\\/]/]
|
|
31
|
-
|
|
32
|
-
export function HstNuxt(options: HstNuxtOptions = {}): Plugin {
|
|
33
|
-
let nuxt: Nuxt
|
|
34
|
-
return {
|
|
35
|
-
name: '@poveste/plugin-nuxt',
|
|
36
|
-
|
|
37
|
-
async defaultConfig() {
|
|
38
|
-
const nuxtViteConfig = await useNuxtViteConfig([...DEFAULT_EXCLUDED_PLUGINS, ...(options.excludePlugins ?? [])])
|
|
39
|
-
const { viteConfig } = nuxtViteConfig
|
|
40
|
-
|
|
41
|
-
nuxt = nuxtViteConfig.nuxt // We save it to close it later
|
|
42
|
-
const plugins = viteConfig.plugins.filter((p: any) => !ignorePlugins.includes(p?.name))
|
|
43
|
-
return {
|
|
44
|
-
vite: {
|
|
45
|
-
server: {
|
|
46
|
-
watch: viteConfig.server.watch,
|
|
47
|
-
fs: {
|
|
48
|
-
allow: viteConfig.server.fs.allow,
|
|
49
|
-
},
|
|
50
|
-
middlewareMode: false,
|
|
51
|
-
},
|
|
52
|
-
define: {
|
|
53
|
-
...viteConfig.define,
|
|
54
|
-
'process.server': false,
|
|
55
|
-
'process.client': true,
|
|
56
|
-
'process.browser': true,
|
|
57
|
-
'process.nitro': false,
|
|
58
|
-
'process.prerender': false,
|
|
59
|
-
},
|
|
60
|
-
resolve: {
|
|
61
|
-
alias: viteConfig.resolve.alias,
|
|
62
|
-
extensions: viteConfig.resolve.extensions,
|
|
63
|
-
dedupe: viteConfig.resolve.dedupe,
|
|
64
|
-
},
|
|
65
|
-
plugins: [
|
|
66
|
-
...plugins,
|
|
67
|
-
replace({
|
|
68
|
-
values: {
|
|
69
|
-
'import.meta.server': 'false',
|
|
70
|
-
'import.meta.client': 'true',
|
|
71
|
-
},
|
|
72
|
-
preventAssignment: true,
|
|
73
|
-
}),
|
|
74
|
-
],
|
|
75
|
-
css: viteConfig.css,
|
|
76
|
-
publicDir: viteConfig.publicDir,
|
|
77
|
-
optimizeDeps: {
|
|
78
|
-
...viteConfig.optimizeDeps,
|
|
79
|
-
exclude: [
|
|
80
|
-
...viteConfig.optimizeDeps.exclude,
|
|
81
|
-
'@poveste/plugin-nuxt',
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
// @ts-expect-error Vue-specific config
|
|
85
|
-
vue: viteConfig.vue,
|
|
86
|
-
logLevel: 'info',
|
|
87
|
-
},
|
|
88
|
-
setupCode: [
|
|
89
|
-
`${nuxt.options.css.map(file => `import '${file}'`).join('\n')}`,
|
|
90
|
-
`import { setupNuxtApp } from '@poveste/plugin-nuxt/dist/runtime/app-setup.js'
|
|
91
|
-
export async function setupVue3 () {
|
|
92
|
-
await setupNuxtApp(${JSON.stringify(nuxt.options.runtimeConfig.public)})
|
|
93
|
-
}`,
|
|
94
|
-
],
|
|
95
|
-
viteNodeInlineDeps: [
|
|
96
|
-
/\/(nuxt|nuxt3)\//,
|
|
97
|
-
/^#/,
|
|
98
|
-
/\.nuxt/,
|
|
99
|
-
...(nuxt.options.build.transpile.filter(
|
|
100
|
-
r => typeof r === 'string' || r instanceof RegExp,
|
|
101
|
-
) as Array<string | RegExp>),
|
|
102
|
-
],
|
|
103
|
-
build: {
|
|
104
|
-
excludeFromVendorsChunk: [
|
|
105
|
-
/nuxt\/dist\/app/,
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
onDev(api, onCleanup) {
|
|
112
|
-
onCleanup(async () => {
|
|
113
|
-
nuxt?.close()
|
|
114
|
-
})
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
onBuild(api) {
|
|
118
|
-
api.onBuildEnd(() => {
|
|
119
|
-
nuxt?.close()
|
|
120
|
-
})
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
onPreview() {
|
|
124
|
-
nuxt?.close()
|
|
125
|
-
},
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async function useNuxtViteConfig(excludePlugins: (string | RegExp)[]) {
|
|
130
|
-
const { loadNuxt, buildNuxt } = await import('@nuxt/kit')
|
|
131
|
-
const nuxt = await loadNuxt({
|
|
132
|
-
// cwd: process.cwd(),
|
|
133
|
-
ready: false,
|
|
134
|
-
dev: true,
|
|
135
|
-
overrides: {
|
|
136
|
-
// Keep the auxiliary instance out of the host's `.nuxt`: it regenerates
|
|
137
|
-
// `imports.d.ts` and friends, which any later type-aware lint or vue-tsc
|
|
138
|
-
// run would then read instead of the application's own (#223).
|
|
139
|
-
buildDir: '.nuxt/poveste',
|
|
140
|
-
devtools: { enabled: false },
|
|
141
|
-
ssr: false,
|
|
142
|
-
experimental: {
|
|
143
|
-
appManifest: false,
|
|
144
|
-
},
|
|
145
|
-
app: {
|
|
146
|
-
rootId: 'nuxt-test',
|
|
147
|
-
},
|
|
148
|
-
pages: false,
|
|
149
|
-
typescript: {
|
|
150
|
-
typeCheck: false,
|
|
151
|
-
},
|
|
152
|
-
},
|
|
153
|
-
})
|
|
154
|
-
if (nuxt.options.builder as string !== '@nuxt/vite-builder') {
|
|
155
|
-
throw new Error(`Poveste only supports Vite bundler, but Nuxt builder is currently set to '${nuxt.options.builder}'.`)
|
|
156
|
-
}
|
|
157
|
-
const runtimeDir = fileURLToPath(new URL('../runtime', import.meta.url))
|
|
158
|
-
nuxt.options.build.templates.push(
|
|
159
|
-
{ src: join(runtimeDir, 'composables.mjs'), filename: 'poveste/composables.mjs' },
|
|
160
|
-
{ src: join(runtimeDir, 'components.mjs'), filename: 'poveste/components.mjs' },
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
// Drop the sandbox-incompatible client plugins named by `excludePlugins`, so
|
|
164
|
-
// they don't 500 the story iframe on entry boot. See DEFAULT_EXCLUDED_PLUGINS.
|
|
165
|
-
nuxt.hook('app:resolve', (app) => {
|
|
166
|
-
app.plugins = app.plugins.filter((p) => {
|
|
167
|
-
const src = p.src ?? ''
|
|
168
|
-
// `match`, not `test`: it doesn't advance a caller's /g regex `lastIndex`, so
|
|
169
|
-
// matching stays stateless without mutating an input we don't own.
|
|
170
|
-
return !excludePlugins.some(pattern =>
|
|
171
|
-
typeof pattern === 'string' ? src.includes(pattern) : src.match(pattern) !== null)
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
nuxt.hook('app:templates', (app) => {
|
|
176
|
-
app.templates = app.templates.filter(template => template.filename !== 'app-component.mjs')
|
|
177
|
-
app.templates.push({ src: join(runtimeDir, 'app-component.mjs'), filename: 'app-component.mjs' })
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
nuxt.hook('imports:sources', (presets) => {
|
|
181
|
-
const polyfills = ['requestIdleCallback', 'cancelIdleCallback']
|
|
182
|
-
const stubbedComposables = ['useNuxtApp']
|
|
183
|
-
for (const appPreset of presets.filter(p => p && typeof p === 'object' && 'from' in p && p.from?.startsWith('#app'))) {
|
|
184
|
-
if ('imports' in appPreset && Array.isArray(appPreset.imports)) {
|
|
185
|
-
appPreset.imports = appPreset.imports.filter(i => typeof i !== 'string' || (!stubbedComposables.includes(i) && !polyfills.includes(i)))
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
presets.push({
|
|
189
|
-
from: '#build/poveste/composables.mjs',
|
|
190
|
-
imports: stubbedComposables,
|
|
191
|
-
})
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
viteConfig: await new Promise<ViteConfig>((resolve, reject) => {
|
|
196
|
-
nuxt.hook('modules:done', () => {
|
|
197
|
-
nuxt.hook('components:extend', (components) => {
|
|
198
|
-
for (const name of ['NuxtLink']) {
|
|
199
|
-
Object.assign(components.find(c => c.pascalName === name) || {}, {
|
|
200
|
-
export: name,
|
|
201
|
-
filePath: '#build/poveste/components.mjs',
|
|
202
|
-
})
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
nuxt.hook('vite:configResolved', (config, { isClient }) => {
|
|
207
|
-
if (isClient) {
|
|
208
|
-
resolve(config as any)
|
|
209
|
-
// The resolved config is all this instance is for. Left running,
|
|
210
|
-
// `buildNuxt` goes on to build the Nuxt client, start Nitro and
|
|
211
|
-
// open Nuxt's own dev server — seconds of work on every `poveste
|
|
212
|
-
// dev` and `poveste build`, a `NUXT_B7005` warning for the entry
|
|
213
|
-
// it does not have, and an HMR socket on 24678 that collides with
|
|
214
|
-
// any other Nuxt dev server on the machine (#220, #221). The catch
|
|
215
|
-
// below has always known this sentinel; nothing threw it.
|
|
216
|
-
throw new Error('_stop_')
|
|
217
|
-
}
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
nuxt.ready()
|
|
221
|
-
.then(() => buildNuxt(nuxt))
|
|
222
|
-
.catch((err) => {
|
|
223
|
-
if (!err.toString().includes('_stop_')) {
|
|
224
|
-
reject(err)
|
|
225
|
-
}
|
|
226
|
-
})
|
|
227
|
-
}),
|
|
228
|
-
nuxt,
|
|
229
|
-
}
|
|
230
|
-
}
|
package/src/runtime/app-setup.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { PublicRuntimeConfig } from '@nuxt/schema'
|
|
2
|
-
import type { App } from 'h3'
|
|
3
|
-
import { createApp } from 'h3'
|
|
4
|
-
import { createFetch } from 'ofetch'
|
|
5
|
-
|
|
6
|
-
export async function setupNuxtApp(publicConfig: PublicRuntimeConfig) {
|
|
7
|
-
const win = window as unknown as Window & {
|
|
8
|
-
__app: App
|
|
9
|
-
__registry: Set<string>
|
|
10
|
-
__NUXT__: any
|
|
11
|
-
$fetch: any
|
|
12
|
-
fetch: any
|
|
13
|
-
IntersectionObserver: any
|
|
14
|
-
Headers: any
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
win.__NUXT__ = {
|
|
18
|
-
serverRendered: false,
|
|
19
|
-
config: {
|
|
20
|
-
public: { ...publicConfig },
|
|
21
|
-
app: { baseURL: '/' },
|
|
22
|
-
},
|
|
23
|
-
data: {},
|
|
24
|
-
state: {},
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const app = win.document.createElement('div')
|
|
28
|
-
// this is a workaround for a happy-dom bug with ids beginning with _
|
|
29
|
-
app.id = 'nuxt-test'
|
|
30
|
-
win.document.body.appendChild(app)
|
|
31
|
-
|
|
32
|
-
win.IntersectionObserver
|
|
33
|
-
= win.IntersectionObserver
|
|
34
|
-
|| class IntersectionObserver {
|
|
35
|
-
observe() {
|
|
36
|
-
// noop
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const h3App = createApp()
|
|
41
|
-
|
|
42
|
-
const registry = new Set<string>()
|
|
43
|
-
|
|
44
|
-
if (__HST_COLLECT__) {
|
|
45
|
-
const {
|
|
46
|
-
toNodeListener,
|
|
47
|
-
} = await import('h3')
|
|
48
|
-
const {
|
|
49
|
-
createCall,
|
|
50
|
-
createFetch: createLocalFetch,
|
|
51
|
-
} = await import('unenv/runtime/fetch/index')
|
|
52
|
-
// @ts-expect-error TODO: fix in h3
|
|
53
|
-
const localCall = createCall(toNodeListener(h3App))
|
|
54
|
-
const localFetch = createLocalFetch(localCall, globalThis.fetch)
|
|
55
|
-
|
|
56
|
-
win.fetch = (init: string, options?: any) => {
|
|
57
|
-
if (typeof init === 'string' && registry.has(init)) {
|
|
58
|
-
init = `/_${init}`
|
|
59
|
-
}
|
|
60
|
-
return localFetch(init, options)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
win.$fetch = createFetch({ fetch: win.fetch, Headers: win.Headers as any })
|
|
65
|
-
|
|
66
|
-
win.__registry = registry
|
|
67
|
-
win.__app = h3App
|
|
68
|
-
|
|
69
|
-
// @ts-expect-error no types
|
|
70
|
-
const result = await import('#app/entry')
|
|
71
|
-
await result.default()
|
|
72
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
// Volar
|
|
5
|
-
"jsx": "preserve",
|
|
6
|
-
"lib": [
|
|
7
|
-
"ESNext",
|
|
8
|
-
"DOM"
|
|
9
|
-
],
|
|
10
|
-
"rootDir": "src",
|
|
11
|
-
"module": "ESNext",
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"types": [
|
|
15
|
-
"node"
|
|
16
|
-
],
|
|
17
|
-
"strictBindCallApply": true,
|
|
18
|
-
"strictFunctionTypes": true,
|
|
19
|
-
"alwaysStrict": true,
|
|
20
|
-
// Strict
|
|
21
|
-
"noImplicitAny": false,
|
|
22
|
-
"noImplicitThis": true,
|
|
23
|
-
"outDir": "dist",
|
|
24
|
-
"removeComments": false,
|
|
25
|
-
"sourceMap": false,
|
|
26
|
-
"allowSyntheticDefaultImports": true,
|
|
27
|
-
"esModuleInterop": true,
|
|
28
|
-
"skipLibCheck": true,
|
|
29
|
-
"preserveWatchOutput": true
|
|
30
|
-
},
|
|
31
|
-
"include": [
|
|
32
|
-
"src"
|
|
33
|
-
],
|
|
34
|
-
"exclude": [
|
|
35
|
-
"node_modules",
|
|
36
|
-
"generated/**/*",
|
|
37
|
-
"dist/**/*",
|
|
38
|
-
"src/**/*.spec.ts"
|
|
39
|
-
]
|
|
40
|
-
}
|