Closed samuveth closed 11 months ago
I get the same issue using any of the available icon libraries, which are:
It is enough to add them to the modules list of the nuxt.config to get the At least one <template> or <script> is required in a single file component
error.
It can be reproduced by any setup with histoire 0.17.1 and nuxt 3.16.x and using the nuxt and vue plugins. I also added an example component for testing.
My current workaround is to disable the icon module for histoire, which is messy but okay for a short period.
package.json scripts
"story:dev": "cross-env NUXT_APP_DISABLE_ICON_MODULE=true histoire dev",
"story:build": "cross-env NUXT_APP_DISABLE_ICON_MODULE=true histoire build",
"story:preview": "histoire preview
nuxt.config
const modules = [
'@pinia/nuxt',
]
if (process.env['NUXT_APP_DISABLE_ICON_MODULE'] !== 'true') {
modules.push('nuxt-icons')
}
export default defineNuxtConfig({
devtools: { enabled: false },
modules,
})
Here is a minimal example to reproduce the issue:
@Akryum I investigated a bit on this issue and it seems like histoire does not work with the async components exposed by nuxt-icons and svg-sprite libraries.
I have added the nuxt-icon component from library "nuxt-icons" manually to my project and even though there was no build error anymore, it does not display the icons (in nuxt itself it works though) and it does not matter what I render in the component. As long as it is async setup (it is using await in the setup function) nothing is being rendered in histoire (eg. a hardcoded span element with text).
I ensured that that the icons, which I tried to load, exist and were found in the component logic.
I also got this in the browser console
[Vue warn]: Component <Anonymous>: setup function returned a promise, but no <Suspense> boundary was found in the parent component tree. A component with async setup() must be nested in a <Suspense> in order to be rendered.
at <NuxtIcon name="search" fill="" >
at <DemoComponent icon-name="search" text="DemoComponent" onAwesomeClick=fn ... >
at <RenderStorySubApp>
maybe it would work if histoire puts a suspense tag around the rendered component.
This is my current workaround when working with nuxt-icons:
<template>
<Story title="App/DemoComponent">
<Suspense>
<DemoComponent
icon-name="search"
/>
</Suspense>
</Story>
</template>
It is not enough to just add suspense and keep the module as the error would still occure
From what I saw histoire simply does not work with global components from nuxt which are treated as async components. So is not really about nuxt-icon, it's about async components.
To get this error simply initiate a nuxt project and create a component in components/global
then start histoire.
Can confirm that it is still happening in the latest Version and isn't fixed together with this issue: https://github.com/histoire-dev/histoire/issues/587#issuecomment-1751680486
Happening with me as well, using Nuxt 3.7.4
and Histoire 0.17.2
.
is also not working with several other modules D: !
This seems to happen too with vue-material-design-icons
.
Try disabling the "@nuxt/content" module, in my case it helped.
@alex-lit: nuxt/content isn't installed in the repro @anoack93 provided. Any globally loaded module seems to trigger this issue, not this one specifically.
I have tried to investigate this issue and identify where in the vite transform pipeline this error seems to come from. This error seems to come from the fact that vite is transforming the .vue
files which are registered as global components twice.
The following output is from running histoire dev
on a Nuxt project with some global components registered.
As you can see in the traces below the first POST TRANSFORM END
line shows a global component passing through the vite:vue
transform hook within vite.
The second log of POST TRANSFORM ERROR
shows the vite:vue
hook being run on the already transformed output. In Daniel Roe's answer on Storybook where a similar error seems to be occuring he suggests plugin vue is being loaded multiple times. This would appear to add up with something similar happening here. It doesn't appear to be multiple vite:vue hooks registered though as checking the transform plugins list in the logs below you can see no duplicates.
I'm going to keep looking...
POST TRANSFORM END vite:vue import { defineComponent as _defineComponent } from "vue";
const _sfc_main = /* @__PURE__ */ _defineComponent({
__name: "JourneyButtons",
props: {
buttons: { type: Array, required: true },
topLevelClass: { type: String, required: true },
containerDivClass: { type: String, required: true },
buttonWrapperDivClass: { type: String, required: true }
},
emits: ["nextClick", "previousClick"],
setup(__props, { expose: __expose, emit: __emit }) {
__expose();
const emit = __emit;
function handleClick(button) {
if (button.type === "next")
return emit("nextClick");
if (button.type === "previous")
return emit("previousClick");
}
const __returned__ = { emit, handleClick };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, createElementVNode as _createElementVNode } from "vue";
const _hoisted_1 = ["onClick"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return _openBlock(), _createElementBlock(
"section",
{
class: _normalizeClass($props.topLevelClass)
},
[
_createElementVNode(
"div",
{
class: _normalizeClass($props.containerDivClass)
},
[
_createElementVNode(
"div",
{
class: _normalizeClass($props.buttonWrapperDivClass)
},
[
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList($props.buttons, (b, i) => {
return _openBlock(), _createElementBlock("button", {
key: i,
class: _normalizeClass(b.text),
onClick: ($event) => $setup.handleClick(b)
}, _toDisplayString(b.text), 11, _hoisted_1);
}),
128
/* KEYED_FRAGMENT */
))
],
2
/* CLASS */
)
],
2
/* CLASS */
)
],
2
/* CLASS */
);
}
_sfc_main.__hmrId = "1bdbbfa7";
typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main);
import.meta.hot.accept((mod) => {
if (!mod)
return;
const { default: updated, _rerender_only } = mod;
if (_rerender_only) {
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render);
} else {
__VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated);
}
});
import _export_sfc from "\0plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "C:/Users/i33672/source/repos/customer-portal/components/content/JourneyButtons.vue"]]);
[
'unplugin-formkit',
'nuxt:layer-aliasing',
'content-slot',
'unplugin-vue-i18n',
'nuxt:client-fallback-auto-id',
'vite:css',
'vite:esbuild',
'vite:json',
'vite:worker',
'vite:vue',
'vite:vue-jsx',
'replace',
'nuxt:remove-plugin-metadata',
'nuxt:chunk-error',
'nuxt:components:imports',
'replace',
'vite:define',
'vite:css-post',
'vite:worker-import-meta-url',
'vite:asset-import-meta-url',
'vite:dynamic-import-vars',
'vite:import-glob',
'nuxt:composable-keys',
'nuxtjs:i18n-macros-transform',
'nuxtjs:i18n-resource',
'nuxt:imports-transform',
'unctx:transform',
'nuxt:dev-style-ssr',
'nuxt:runtime-paths-dep',
'nuxt:components-loader',
'nuxt:tree-shake-composables:transform',
'vite:client-inject',
'vite:import-analysis'
] Error: why have you done this
at Object.transform (file:///C:/Users/i33672/source/repos/customer-portal/node_modules/.pnpm/vite@4.5.0/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:44380:95)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async loadAndTransform (file:///C:/Users/i33672/source/repos/customer-portal/node_modules/.pnpm/vite@4.5.0/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55034:29)
ℹ ✨ optimized dependencies changed. reloading 16:27:16
ℹ Vite client warmed up in 1935ms 16:27:16
Failed to resolve dependency: vscode-oniguruma, present in 'optimizeDeps.include'
Failed to resolve dependency: vscode-textmate, present in 'optimizeDeps.include'
Using 8 threads for story collection
Collect stories start all
➜ Local: http://localhost:6006/
➜ Network: use --host to expose
✔ Nitro built in 4241 ms nitro 16:27:20
At least one <template> or <script> is required in a single file component.
POST TRANSFORM ERROR vite:vue import { defineAsyncComponent } from "vue"
export default defineAsyncComponent(() => import("C:/Users/i33672/source/repos/customer-portal/components/content/JourneyButtons.vue").then(r => r.default)) [
'unplugin-formkit',
'nuxt:layer-aliasing',
'content-slot',
'unplugin-vue-i18n',
'nuxt:client-fallback-auto-id',
'histoire:flags',
'vite:css',
'vite:esbuild',
'vite:json',
'vite:worker',
'replace',
'nuxt:remove-plugin-metadata',
'nuxt:chunk-error',
'nuxt:components:imports',
'vite:vue',
'vite:vue-jsx',
'replace',
'histoire-vue-docs-block',
'vite:define',
'vite:css-post',
'vite:worker-import-meta-url',
'vite:asset-import-meta-url',
'vite:dynamic-import-vars',
'vite:import-glob',
'nuxt:composable-keys',
'nuxtjs:i18n-macros-transform',
'nuxtjs:i18n-resource',
'nuxt:imports-transform',
'unctx:transform',
'nuxt:runtime-paths-dep',
'nuxt:components-loader',
'histoire-plugin-vue',
'vite:client-inject',
'vite:import-analysis'
]
At least one <template> or <script> is required in a single file component. (x2)
At least one <template> or <script> is required in a single file component. (x3)
At least one <template> or <script> is required in a single file component. (x4)
At least one <template> or <script> is required in a single file component. (x5)
At least one <template> or <script> is required in a single file component. (x6)
At least one <template> or <script> is required in a single file component. (x7)
At least one <template> or <script> is required in a single file component. (x8)
At least one <template> or <script> is required in a single file component. (x9)
At least one <template> or <script> is required in a single file component. (x10)
At least one <template> or <script> is required in a single file component. (x11)
At least one <template> or <script> is required in a single file component. (x12)
At least one <template> or <script> is required in a single file component. (x13)
At least one <template> or <script> is required in a single file component. (x14)
At least one <template> or <script> is required in a single file component. (x15)
At least one <template> or <script> is required in a single file component. (x16)
At least one <template> or <script> is required in a single file component. (x17)
At least one <template> or <script> is required in a single file component. (x18)
At least one <template> or <script> is required in a single file component. (x19)
At least one <template> or <script> is required in a single file component. (x20)
At least one <template> or <script> is required in a single file component. (x21)
At least one <template> or <script> is required in a single file component. (x22)
At least one <template> or <script> is required in a single file component. (x23)
At least one <template> or <script> is required in a single file component. (x24)
At least one <template> or <script> is required in a single file component. (x25)
At least one <template> or <script> is required in a single file component. (x26)
At least one <template> or <script> is required in a single file component. (x27)
At least one <template> or <script> is required in a single file component. (x28)
At least one <template> or <script> is required in a single file component. (x29)
At least one <template> or <script> is required in a single file component. (x30)
At least one <template> or <script> is required in a single file component. (x31)
At least one <template> or <script> is required in a single file component. (x32)
At least one <template> or <script> is required in a single file component. (x33)
At least one <template> or <script> is required in a single file component. (x34)
At least one <template> or <script> is required in a single file component. (x35)
At least one <template> or <script> is required in a single file component. (x36)
At least one <template> or <script> is required in a single file component. (x37)
At least one <template> or <script> is required in a single file component. (x38)
At least one <template> or <script> is required in a single file component. (x39)
At least one <template> or <script> is required in a single file component. (x40)
At least one <template> or <script> is required in a single file component. (x41)
At least one <template> or <script> is required in a single file component. (x42)
At least one <template> or <script> is required in a single file component. (x43)
At least one <template> or <script> is required in a single file component. (x44)
POST TRANSFORM ERROR vite:vue import { defineAsyncComponent } from "vue"
export default defineAsyncComponent(() => import("C:/Users/i33672/source/repos/customer-portal/components/content/JourneyButtons.vue").then(r => r.default)) [
'unplugin-formkit',
'nuxt:layer-aliasing',
'content-slot',
'unplugin-vue-i18n',
'nuxt:client-fallback-auto-id',
'histoire:flags',
'vite:css',
'vite:esbuild',
'vite:json',
'vite:worker',
'replace',
'nuxt:remove-plugin-metadata',
'nuxt:chunk-error',
'nuxt:components:imports',
'vite:vue',
'vite:vue-jsx',
'replace',
'histoire-vue-docs-block',
'vite:define',
'vite:css-post',
'vite:worker-import-meta-url',
'vite:asset-import-meta-url',
'vite:dynamic-import-vars',
'vite:import-glob',
'nuxt:composable-keys',
'nuxtjs:i18n-macros-transform',
'nuxtjs:i18n-resource',
'nuxt:imports-transform',
'unctx:transform',
'nuxt:runtime-paths-dep',
'nuxt:components-loader',
'histoire-plugin-vue',
'vite:client-inject',
'vite:import-analysis'
]
Error while collecting story C:/Users/i33672/source/repos/customer-portal/stories/Woof.story.vue:
SyntaxError: At least one <template> or <script> is required in a single file component.
at Object.parse$2 [as parse] (C:\Users\i33672\source\repos\customer-portal\node_modules\.pnpm\@vue+compiler-sfc@3.3.8\node_modules\@vue\compiler-sfc\dist\compiler-sfc.cjs.js:1904:7)
at createDescriptor (C:\Users\i33672\source\repos\customer-portal\node_modules\.pnpm\@vitejs+plugin-vue@4.5.0_vite@4.5.0_vue@3.3.8\node_modules\@vitejs\plugin-vue\dist\index.cjs:86:43)
at transformMain (C:\Users\i33672\source\repos\customer-portal\node_modules\.pnpm\@vitejs+plugin-vue@4.5.0_vite@4.5.0_vue@3.3.8\node_modules\@vitejs\plugin-vue\dist\index.cjs:2302:34)
at TransformContext.transform (C:\Users\i33672\source\repos\customer-portal\node_modules\.pnpm\@vitejs+plugin-vue@4.5.0_vite@4.5.0_vue@3.3.8\node_modules\@vitejs\plugin-vue\dist\index.cjs:2848:16)
at Object.transform (file:///C:/Users/i33672/source/repos/customer-portal/node_modules/.pnpm/vite@4.5.0/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:44353:62)
at async loadAndTransform (file:///C:/Users/i33672/source/repos/customer-portal/node_modules/.pnpm/vite@4.5.0/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55034:29)
Collect stories end 2440ms
I believe I have found a potential fix. But I'm a little confused by it...
Changing the hook that @histoire/plugin-nuxt
uses to check for the presence of the vue plugins to vite:configResolved
and everything starts working fine.
(sorry for the rubbish screenshot not sure why its turned out like that)
Very strange. I'm not confortable raising a PR with this just yet as I dont understand why just listening to configResolved
but doing nothing seems to make histoire work again. Something for Monday 😄 if anyone notices anything that might explain let me know!
can confirm this is tsill there with latest historie v 0.17.6 and latest nuxt 3.8.2
This is there in the vue plugin too
This is there in the vue plugin too
Most likely this is because your Vue plugin is loaded twice and your code is being transformed twice. I believe following the vanilla histoire setup for a standard Vue 3 project does work. Try setting up a vanilla one and adding some of your vite config piece by piece and see what seems to break it.
Related to https://github.com/histoire-dev/histoire/issues/527
I'm still getting this error for 'nuxt-icon' and 'nuxt-icons' plugins. These are both very popular plugins
Originally posted by @samuveth in https://github.com/histoire-dev/histoire/issues/527#issuecomment-1713213570