@analogjs/vite-plugin-angular
Advanced tools
Comparing version 2.0.0-alpha.1 to 2.0.0-alpha.2
{ | ||
"name": "@analogjs/vite-plugin-angular", | ||
"version": "2.0.0-alpha.1", | ||
"version": "2.0.0-alpha.2", | ||
"description": "Vite Plugin for Angular", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -32,2 +32,3 @@ import { NgtscProgram } from '@angular/compiler-cli'; | ||
additionalContentDirs?: string[]; | ||
liveReload?: boolean; | ||
} | ||
@@ -41,6 +42,7 @@ interface EmitFileResult { | ||
warnings: (string | ts.DiagnosticMessageChain)[]; | ||
hmrUpdateCode?: string | null; | ||
} | ||
type FileEmitter = (file: string) => Promise<EmitFileResult | undefined>; | ||
export declare function angular(options?: PluginOptions): Plugin[]; | ||
export declare function createFileEmitter(program: ts.BuilderProgram, transformers?: ts.CustomTransformers, onAfterEmit?: (sourceFile: ts.SourceFile) => void, angularCompiler?: NgtscProgram['compiler']): FileEmitter; | ||
export declare function createFileEmitter(program: ts.BuilderProgram, transformers?: ts.CustomTransformers, onAfterEmit?: (sourceFile: ts.SourceFile) => void, angularCompiler?: NgtscProgram['compiler'], liveReload?: boolean): FileEmitter; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
import { dirname, resolve } from 'node:path'; | ||
import { dirname, relative, resolve } from 'node:path'; | ||
import * as compilerCli from '@angular/compiler-cli'; | ||
@@ -11,3 +11,3 @@ import * as ts from 'typescript'; | ||
import { buildOptimizerPlugin } from './angular-build-optimizer-plugin.js'; | ||
import { createJitResourceTransformer, SourceFileCache, } from './utils/devkit.js'; | ||
import { createJitResourceTransformer, SourceFileCache, angularMajor, } from './utils/devkit.js'; | ||
import { angularVitestPlugins } from './angular-vitest-plugin.js'; | ||
@@ -26,2 +26,4 @@ import { angularStorybookPlugin } from './angular-storybook-plugin.js'; | ||
const TS_EXT_REGEX = /\.[cm]?(ts|analog|ag)[^x]?\??/; | ||
const ANGULAR_COMPONENT_PREFIX = '/@ng/component'; | ||
const classNames = new Map(); | ||
export function angular(options) { | ||
@@ -55,2 +57,3 @@ /** | ||
additionalContentDirs: options?.additionalContentDirs ?? [], | ||
liveReload: options?.liveReload ?? false, | ||
}; | ||
@@ -83,2 +86,5 @@ // The file emitter created during `onStart` that will be used during the build in `onLoad` callbacks for TS files | ||
let isProd = false; | ||
if (angularMajor < 19 || isTest) { | ||
pluginOptions.liveReload = false; | ||
} | ||
return { | ||
@@ -148,2 +154,26 @@ name: '@analogjs/vite-plugin-angular', | ||
}); | ||
if (pluginOptions.liveReload) { | ||
const angularComponentMiddleware = async (req, res, next) => { | ||
if (req.url === undefined || res.writableEnded) { | ||
return; | ||
} | ||
if (!req.url.startsWith(ANGULAR_COMPONENT_PREFIX)) { | ||
next(); | ||
return; | ||
} | ||
const requestUrl = new URL(req.url, 'http://localhost'); | ||
const componentId = requestUrl.searchParams.get('c'); | ||
if (!componentId) { | ||
res.statusCode = 400; | ||
res.end(); | ||
return; | ||
} | ||
const [fileId] = decodeURIComponent(componentId).split('@'); | ||
const result = await fileEmitter?.(resolve(process.cwd(), fileId)); | ||
res.setHeader('Content-Type', 'text/javascript'); | ||
res.setHeader('Cache-Control', 'no-cache'); | ||
res.end(`${result?.hmrUpdateCode || ''}`); | ||
}; | ||
viteServer.middlewares.use(angularComponentMiddleware); | ||
} | ||
}, | ||
@@ -167,4 +197,11 @@ async buildStart() { | ||
if (TS_EXT_REGEX.test(ctx.file)) { | ||
sourceFileCache.invalidate([ctx.file.replace(/\?(.*)/, '')]); | ||
const fileId = ctx.file.split('?')[0] + | ||
(pluginOptions.supportAnalogFormat ? '.ts' : ''); | ||
sourceFileCache.invalidate([fileId]); | ||
await buildAndAnalyze(); | ||
if (pluginOptions.liveReload && classNames.get(fileId)) { | ||
const relativeFileId = `${relative(process.cwd(), fileId)}@${classNames.get(fileId)}`; | ||
sendHMRComponentUpdate(ctx.server, relativeFileId); | ||
return []; | ||
} | ||
} | ||
@@ -181,2 +218,3 @@ if (/\.(html|htm|css|less|sass|scss)$/.test(ctx.file)) { | ||
const mods = []; | ||
const updates = []; | ||
ctx.modules.forEach((mod) => { | ||
@@ -186,6 +224,18 @@ mod.importers.forEach((imp) => { | ||
ctx.server.moduleGraph.invalidateModule(imp); | ||
mods.push(imp); | ||
if (pluginOptions.liveReload && classNames.get(imp.id)) { | ||
updates.push(imp.id); | ||
} | ||
else { | ||
mods.push(imp); | ||
} | ||
}); | ||
}); | ||
await buildAndAnalyze(); | ||
if (updates.length > 0) { | ||
updates.forEach((updateId) => { | ||
const impRelativeFileId = `${relative(process.cwd(), updateId)}@${classNames.get(updateId)}`; | ||
sendHMRComponentUpdate(ctx.server, impRelativeFileId); | ||
}); | ||
return ctx.modules; | ||
} | ||
return mods; | ||
@@ -202,2 +252,16 @@ } | ||
}, | ||
async load(id, options) { | ||
if (pluginOptions.liveReload && | ||
options?.ssr && | ||
id.startsWith(ANGULAR_COMPONENT_PREFIX)) { | ||
const requestUrl = new URL(id.slice(1), 'http://localhost'); | ||
const componentId = requestUrl.searchParams.get('c'); | ||
if (!componentId) { | ||
return; | ||
} | ||
const result = await fileEmitter?.(resolve(process.cwd(), decodeURIComponent(componentId).split('@')[0])); | ||
return result?.hmrUpdateCode || ''; | ||
} | ||
return; | ||
}, | ||
async transform(code, id) { | ||
@@ -389,2 +453,5 @@ // Skip transforming node_modules | ||
} | ||
if (pluginOptions.liveReload) { | ||
tsCompilerOptions['_enableHmr'] = true; | ||
} | ||
rootNames = rn.concat(analogFiles, includeFiles); | ||
@@ -447,6 +514,13 @@ compilerOptions = tsCompilerOptions; | ||
afterDeclarations: pluginOptions.advanced.tsTransformers.afterDeclarations, | ||
}, jit ? {} : angularCompiler.prepareEmit().transformers), () => [], angularCompiler); | ||
}, jit ? {} : angularCompiler.prepareEmit().transformers), () => [], angularCompiler, pluginOptions.liveReload); | ||
} | ||
} | ||
export function createFileEmitter(program, transformers = {}, onAfterEmit, angularCompiler) { | ||
function sendHMRComponentUpdate(server, id) { | ||
server.ws.send('angular:component-update', { | ||
id: encodeURIComponent(id), | ||
timestamp: Date.now(), | ||
}); | ||
classNames.delete(id); | ||
} | ||
export function createFileEmitter(program, transformers = {}, onAfterEmit, angularCompiler, liveReload) { | ||
return async (file) => { | ||
@@ -466,2 +540,11 @@ const sourceFile = program.getSourceFile(file); | ||
.map((d) => d.messageText); | ||
let hmrUpdateCode = undefined; | ||
if (liveReload) { | ||
for (const node of sourceFile.statements) { | ||
if (ts.isClassDeclaration(node) && node.name != null) { | ||
hmrUpdateCode = angularCompiler?.emitHmrUpdateModule(node); | ||
classNames.set(file, node.name.getText()); | ||
} | ||
} | ||
} | ||
let content; | ||
@@ -474,5 +557,5 @@ program.emit(sourceFile, (filename, data) => { | ||
onAfterEmit?.(sourceFile); | ||
return { content, dependencies: [], errors, warnings }; | ||
return { content, dependencies: [], errors, warnings, hmrUpdateCode }; | ||
}; | ||
} | ||
//# sourceMappingURL=angular-vite-plugin.js.map |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
175331
2374