analog
analog copied to clipboard
`Failed to resolve import "angular:jit:template:file;./app.component.html"` error when plugin is loaded twice and jit is enabled
Please provide the environment you discovered this bug in.
Running vitest while loading the angular plugin twice in jit mode fails.
import angular from '@analogjs/vite-plugin-angular';
export default defineConfig(({ mode }) => {
return {
plugins: [
angular({jit: true}),
angular({jit: true})
],
...
}
});
This is a black swan edge case that should almost never happen but when it happens it is really hard to debug. I just spent few hours due to an issue with Nx vitest executor which extracts the plugins from the vite config and gives it back to vitest causing the plugins to be loaded twice 😅
Which area/package is the issue in?
vitest-angular
Description
When @analogjs/vite-plugin-angular is loaded twice in vite config and jit mode is enabled the following error happens:
Error: Failed to resolve import "angular:jit:template:file;./app.component.html" from "src/app/app.component.ts". Does the file exist?
Please provide the exception or error you saw
No response
Other information
This seems to happen because the templateUrl is extracted from the source code instead of the TS output.
https://github.com/analogjs/analog/blob/7091444b068e964e5f1f2a94f5298ee38d7e2df3/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts#L320
I guess that this could be fixed by extracting the template URLs from the transformed data:
https://github.com/analogjs/analog/blob/7091444b068e964e5f1f2a94f5298ee38d7e2df3/packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts#L347
Please let me know if this fix works for you or do you suggest a better alternative?
I would be willing to submit a PR to fix this issue
- [X] Yes
- [ ] No
If we can reliably extract the template and style URLs from the compiled output, that seems reasonable to me.
got that error when:
angular library has vite.config.mts for vitest
has storybook and try to use it with vite
when run storybook dev got that type of error. When I delete vite.config.mts storybook working properly
Landed a fix. It can be tested in 1.10.2-beta.4
@brandonroberts I try 1.10.2-beta.4 with no luck.
Looks like problem with merging configs from storybook vite final where angular() plugin and vite.config.ts where plugin exist too:
warn - https://tailwindcss.com/docs/content-configuration
10:20:16 PM [vite] Pre-transform error: Failed to resolve import "angular:jit:template:file;./ui-kit.component.html" from "src/lib/ui-kit/ui-kit.component.ts". Does the file exist?
10:20:16 PM [vite] Internal server error: Failed to resolve import "angular:jit:template:file;./ui-kit.component.html" from "src/lib/ui-kit/ui-kit.component.ts". Does the file exist?
Plugin: vite:import-analysis
File: /Users/iam/myorg/my-app/libs/ui-kit/src/lib/ui-kit/ui-kit.component.ts:2:35
1 | import { __decorate } from "tslib";
2 | import __NG_CLI_RESOURCE__0 from "angular:jit:template:file;./ui-kit.component.html";
| ^
3 | import __NG_CLI_RESOURCE__1 from "angular:jit:style:file;./ui-kit.component.css";
4 | import { Component } from '@angular/core';
at TransformPluginContext._formatError (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:49255:41)
at TransformPluginContext.error (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:49250:16)
at normalizeUrl (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:64041:23)
at async file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:64173:39
at async Promise.all (index 1)
at async TransformPluginContext.transform (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:64100:7)
at async PluginContainer.transform (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:49096:18)
at async loadAndTransform (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:51929:27)
at async viteTransformMiddleware (file:///Users/iam/myorg/my-app/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:61881:24)
10:21:24
steps to reproduce:
- create fresh nx integrated project with angular (via nx)
- create angular nx library (buildable) for example "ui-kit" in "libs" folder with unit testing vitest (via nx console)
- create storybook setup for that lib (via nx console)
- update storybook with "vite final" as recommended at analogjs website
run cd libs/ui-kit
run npx storybook dev --port 4400
Thanks @pumano. Storybook isn't supposed to load the config if the viteConfigPath is set to undefined. Will take a look
If you just return the config directly instead of merging, does it work?
@brandonroberts if I just delete angular() in parent vite.config.js - all works properly. But when I want to use vitest for tests and also storybook, merging 2 angular plugins cause that error.
console.log() at vite final function can show that config come to vite final is parent vite.config.mts with "test" section
@pumano what is the viteConfigPath set to in the main.ts for storybook?
@brandonroberts
import type { StorybookConfig } from '@storybook/angular';
import type { StorybookConfigVite } from '@storybook/builder-vite';
import type { UserConfig } from 'vite';
const config: StorybookConfig & StorybookConfigVite = {
stories: ['../**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-mdx-gfm', // mdx-gfm
'@storybook/addon-a11y', // Catch accessibility issues
],
framework: {
name: '@storybook/angular',
options: {},
},
/*
typescript: {
check: true, // type-check stories during Storybook build
},
*/
core: {
disableTelemetry: true, // 👈 Disables telemetry
builder: {
name: '@storybook/builder-vite',
options: {
viteConfigPath: undefined,
},
},
},
staticDirs: ['../assets'],
docs: {
// set to change the name of generated docs entries
defaultName: 'Docs',
},
async viteFinal(config: UserConfig) {
// Merge custom configuration into the default config
const { mergeConfig } = await import('vite');
const { default: angular } = await import('@analogjs/vite-plugin-angular');
return mergeConfig(config, {
// Add dependencies to pre-optimization
optimizeDeps: {
include: [
'react/jsx-dev-runtime',
'@storybook/angular',
'@storybook/angular/dist/client',
'@angular/compiler',
'@storybook/blocks',
'tslib',
],
},
plugins: [angular({ jit: true, tsconfig: './.storybook/tsconfig.json' })],
});
},
};
export default config;
// To customize your webpack configuration you can use the webpackFinal field.
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
// and https://nx.dev/packages/storybook/documents/custom-builder-configs
note: storybook latest 8.4.7
@brandonroberts I'm really sorry) but it fix partially. It's working now, but ruin tailwind styles. I really found workaround, but, what is very interested, if 2 configs merged (parent + vite final with angular plugin), it cost 2 times longer to start storybook due to double processing via plugins. They really not merged properly, I think it's bug or maybe not, but merge config add new items, not update previously added plugins.
Workaround: just rename vite.config.mts in nx library directory to vitest.config.mts it's really working with vitest, and NOT loaded by storybook (where plugins properly loaded and angular plugins under the hood load 1 time only).
Thank you @brandonroberts for your work! Hope some note to config collision is nice to have at analog website at guide to vitest section.
@pumano no problem. 1.10.2-beta.6 contains a proper fix where multiple configurations with plugins don't cause issues with external templates and styles.
Tested with the reproduction instructions in the GitHub repo below
https://github.com/brandonroberts/issue-1288-nx
Good idea with naming the separate files though in that case
@brandonroberts OK I will try beta.6 now, later add results
@brandonroberts beta.6 with no luck. I really debug that: in viteFinal storybook already load vite.config.mts with load angular plugin, nx-copy-assets-plugin (which really harm when try to build storybook, that plugin just copy *.md files not to dist folder but in nx lib folder)
only way to properly handle vitest + storybook in one nx lib now is not use vite.config.mts because viteConfigPath: undefined somehow not processed by storybook at all.
I'm already test it, vitest works good with vitest.config.mts and storybook works great with main.ts viteFinal config where angular plugin added
@pumano are you getting the same error or just the slowdown?
@brandonroberts i don't get error more, only slowdown and wrong tailwindcss processing. (I think that caused because plugins really duplicated.
I try to filter plugins, but they come to viteFinal as in promise. After trying it, I really understand, that trying to filtering something, is not good idea, because looks like monkey patching.
Final thoughts about it: I can solve problem: vitest+ storybook + vite its give me 2 mins less in pipeline time for building storybook. Thank you for being it possible.
Great to hear. I'll consider the bug fixed, and we'll add some notes to the docs about usage of Storybook with Vitest and the configs
@brandonroberts FYI similar issue at storybook: https://github.com/storybookjs/storybook/issues/29777
It also says in their docs to point to a non-existent file if you don't want to load the main config, but that throws an error.