Skip to content

Commit

Permalink
fix(vite-plugin-angular): fix SSG and HMR of external component style…
Browse files Browse the repository at this point in the history
…sheets (#1548)
  • Loading branch information
mattlewis92 authored Jan 7, 2025
1 parent c8bb811 commit e6de3d7
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 6 deletions.
33 changes: 28 additions & 5 deletions packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export function angular(options?: PluginOptions): Plugin[] {
let watchMode = false;
let testWatchMode = false;
let inlineComponentStyles: Map<string, string> | undefined;
let externalComponentStyles: Map<string, string> | undefined;
const sourceFileCache = new SourceFileCache();
const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];
const isStackBlitz = !!process.versions['webcontainer'];
Expand Down Expand Up @@ -387,7 +388,7 @@ export function angular(options?: PluginOptions): Plugin[] {
{
type: 'css-update',
timestamp: Date.now(),
path: isDirect.id,
path: isDirect.url,
acceptedPath: isDirect.file,
},
],
Expand Down Expand Up @@ -460,15 +461,24 @@ export function angular(options?: PluginOptions): Plugin[] {
)}?raw`;
}

// Map angular external styleUrls to the source file
if (isComponentStyleSheet(id)) {
const componentStyles = externalComponentStyles?.get(
getFilenameFromPath(id)
);
if (componentStyles) {
return componentStyles + new URL(id, 'http://localhost').search;
}
}

return undefined;
},
async load(id, options) {
// Map angular inline styles to the source text
if (isComponentStyleSheet(id)) {
const filename = new URL(id, 'http://localhost').pathname.replace(
/^\//,
''
const componentStyles = inlineComponentStyles?.get(
getFilenameFromPath(id)
);
const componentStyles = inlineComponentStyles?.get(filename);
if (componentStyles) {
return componentStyles;
}
Expand Down Expand Up @@ -781,12 +791,16 @@ export function angular(options?: PluginOptions): Plugin[] {
inlineComponentStyles = tsCompilerOptions['externalRuntimeStyles']
? new Map()
: undefined;
externalComponentStyles = tsCompilerOptions['externalRuntimeStyles']
? new Map()
: undefined;
augmentHostWithResources(host, styleTransform, {
inlineStylesExtension: pluginOptions.inlineStylesExtension,
supportAnalogFormat: pluginOptions.supportAnalogFormat,
isProd,
markdownTemplateTransforms: pluginOptions.markdownTemplateTransforms,
inlineComponentStyles,
externalComponentStyles,
});
}
}
Expand Down Expand Up @@ -1009,3 +1023,12 @@ function getComponentStyleSheetMeta(id: string): {
] as 'emulated' | 'shadow' | 'none',
};
}

/**
* Removes leading / and query string from a url path
* e.g. /foo.scss?direct&ngcomp=ng-c3153525609&e=0 returns foo.scss
* @param id
*/
function getFilenameFromPath(id: string): string {
return new URL(id, 'http://localhost').pathname.replace(/^\//, '');
}
43 changes: 42 additions & 1 deletion packages/vite-plugin-angular/src/lib/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MarkdownTemplateTransform } from './authoring/markdown-transform.js';

import { createRequire } from 'node:module';
import { createHash } from 'node:crypto';
import path from 'node:path';

const require = createRequire(import.meta.url);

Expand All @@ -33,14 +34,14 @@ export function augmentHostWithResources(
isProd?: boolean;
markdownTemplateTransforms?: MarkdownTemplateTransform[];
inlineComponentStyles?: Map<string, string>;
externalComponentStyles?: Map<string, string>;
}
) {
const ts = require('typescript');
const resourceHost = host as CompilerHost;
const baseGetSourceFile = (
resourceHost as ts.CompilerHost
).getSourceFile.bind(resourceHost);
const externalStylesheets = new Map<string, string>();

if (options.supportAnalogFormat) {
(resourceHost as ts.CompilerHost).getSourceFile = (
Expand Down Expand Up @@ -187,6 +188,33 @@ export function augmentHostWithResources(

return null;
};

resourceHost.resourceNameToFileName = function (
resourceName,
containingFile
) {
const resolvedPath = path.join(path.dirname(containingFile), resourceName);

// All resource names that have template file extensions are assumed to be templates
if (
!options.externalComponentStyles ||
hasTemplateExtension(resolvedPath)
) {
return resolvedPath;
}

// For external stylesheets, create a unique identifier and store the mapping
let externalId = options.externalComponentStyles.get(resolvedPath);
if (externalId === undefined) {
externalId = createHash('sha256').update(resolvedPath).digest('hex');
}

const filename = externalId + path.extname(resolvedPath);

options.externalComponentStyles.set(filename, resolvedPath);

return filename;
};
}

export function augmentProgramWithVersioning(program: ts.Program): void {
Expand Down Expand Up @@ -261,3 +289,16 @@ export function mergeTransformers(

return result;
}

function hasTemplateExtension(file: string): boolean {
const extension = path.extname(file).toLowerCase();

switch (extension) {
case '.htm':
case '.html':
case '.svg':
return true;
}

return false;
}

0 comments on commit e6de3d7

Please sign in to comment.