diff --git a/package.json b/package.json
index 28f10d5d804..eac9e386c45 100644
--- a/package.json
+++ b/package.json
@@ -117,6 +117,7 @@
"@types/google.analytics": "^0.0.46",
"@types/gtag.js": "^0.0.20",
"@types/history": "4.7.11",
+ "@types/html-minifier-terser": "^7",
"@types/ini": "^4",
"@types/jest": "29.5.14",
"@types/jquery": "3.5.32",
@@ -185,6 +186,7 @@
"eslint-scope": "^8.1.0",
"fishery": "^2.2.2",
"glob": "11.0.1",
+ "html-minifier-terser": "^7.2.0",
"http-server": "14.1.1",
"i18next-parser": "9.3.0",
"ini": "^5.0.0",
diff --git a/public/app/angular/index.ts b/public/app/angular/index.ts
index c4d52f43160..3fbf6ae93f2 100644
--- a/public/app/angular/index.ts
+++ b/public/app/angular/index.ts
@@ -1,6 +1,5 @@
import './panel/all';
-// Vite: these partials still aren't working correctly so comment out for now.
-// import './partials';
+import './partials';
import './filters/filters';
import './services/alert_srv';
import './services/dynamic_directive_srv';
diff --git a/public/app/angular/partials.ts b/public/app/angular/partials.ts
index 9a4703ba7e5..523a32ef867 100644
--- a/public/app/angular/partials.ts
+++ b/public/app/angular/partials.ts
@@ -1,10 +1,5 @@
-// TODO: Vite has no require.context support yet. Attempt at a workaround below.
-// let templates = (require as any).context('../', true, /\.html$/);
-// templates.keys().forEach((key: string) => {
-// templates(key);
-// });
-
-// See vite.config.ts angularHtmlImport function for the code that _should_ assist with these templates.
+// TODO: Vite has no require.context support so we're importing them individually here.
+// See the vite.config.ts angularHtmlImport plugin for the code that compiles these templates.
import 'app/angular/panel/partials/query_editor_row.html';
import 'app/angular/partials/http_settings_next.html';
diff --git a/vite.config.ts b/vite.config.ts
index 0b0b10d907f..59acae86edc 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,32 +1,11 @@
import react from '@vitejs/plugin-react-swc';
+import { minify } from 'html-minifier-terser';
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
import { defineConfig } from 'vite';
const require = createRequire(import.meta.url);
-// This is a Vite plugin for handling angular templates.
-// https://vitejs.dev/guide/api-plugin.html#simple-examples
-
-// The webpack output from https://github.com/WearyMonkey/ngtemplate-loader looks like this:
-// var code = "\n
\n";
-// Exports
-// var _module_exports =code;;
-// var path = 'public/app/features/annotations/partials/event_editor.html';
-// window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, _module_exports) }]);
-// module.exports = path;
-function angularHtmlImport() {
- return {
- name: 'transform-angular-html',
- transform(src, id) {
- if (/^.*\.html$/g.test(id)) {
- const result = `let path = '${id}'; angular.module('ng').run(['$templateCache', c => { c.put(path, \`${src}\`) }]); export default path;`;
- return { code: result, map: null };
- }
- },
- };
-}
-
// https://vitejs.dev/config/
export default defineConfig({
root: './public',
@@ -85,3 +64,36 @@ export default defineConfig({
extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.json'],
},
});
+
+// This is a Vite plugin for handling angular templates.
+// https://vitejs.dev/guide/api-plugin.html#simple-examples
+
+// The webpack output from https://github.com/WearyMonkey/ngtemplate-loader looks like this:
+// var code = "\n\n\t\n\n\t
\n
\n";
+// Exports
+// var _module_exports =code;;
+// var path = 'public/app/features/annotations/partials/event_editor.html';
+// window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, _module_exports) }]);
+// module.exports = path;
+function angularHtmlImport() {
+ return {
+ name: 'transform-angular-html',
+ async transform(src, id) {
+ if (/^.*\.html$/g.test(id)) {
+ const minifierOptions = {
+ collapseWhitespace: false,
+ collapseBooleanAttributes: true,
+ conservativeCollapse: true,
+ minifyJS: true,
+ };
+
+ const idParts = id.split('/public/');
+ const path = idParts[idParts.length - 1];
+ const html = await minify(src, minifierOptions);
+ const stringified = JSON.stringify(html);
+ const result = `let path = 'public/${path}'; angular.module('ng').run(['$templateCache', c => { c.put(path, ${stringified}) }]); export default path;`;
+ return { code: result, map: null };
+ }
+ },
+ };
+}
diff --git a/yarn.lock b/yarn.lock
index e819d8a2088..9d7b010164e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10279,6 +10279,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/html-minifier-terser@npm:^7":
+ version: 7.0.2
+ resolution: "@types/html-minifier-terser@npm:7.0.2"
+ checksum: 10/312d9285b034538fc8c851d99b5cc47f83e802f0dccc1be4adf10d4ee881d92d14f97ca1862313a827b844a7f71db6ab80198d7741f1747a9bcf7de77181ce40
+ languageName: node
+ linkType: hard
+
"@types/ini@npm:^4":
version: 4.1.1
resolution: "@types/ini@npm:4.1.1"
@@ -13413,7 +13420,7 @@ __metadata:
languageName: node
linkType: hard
-"clean-css@npm:^5.1.5":
+"clean-css@npm:^5.1.5, clean-css@npm:~5.3.2":
version: 5.3.3
resolution: "clean-css@npm:5.3.3"
dependencies:
@@ -13743,6 +13750,13 @@ __metadata:
languageName: node
linkType: hard
+"commander@npm:^10.0.0":
+ version: 10.0.1
+ resolution: "commander@npm:10.0.1"
+ checksum: 10/8799faa84a30da985802e661cc9856adfaee324d4b138413013ef7f087e8d7924b144c30a1f1405475f0909f467665cd9e1ce13270a2f41b141dab0b7a58f3fb
+ languageName: node
+ linkType: hard
+
"commander@npm:^12.1.0":
version: 12.1.0
resolution: "commander@npm:12.1.0"
@@ -18257,6 +18271,7 @@ __metadata:
"@types/google.analytics": "npm:^0.0.46"
"@types/gtag.js": "npm:^0.0.20"
"@types/history": "npm:4.7.11"
+ "@types/html-minifier-terser": "npm:^7"
"@types/ini": "npm:^4"
"@types/jest": "npm:29.5.14"
"@types/jquery": "npm:3.5.32"
@@ -18355,6 +18370,7 @@ __metadata:
fishery: "npm:^2.2.2"
glob: "npm:11.0.1"
history: "npm:4.10.1"
+ html-minifier-terser: "npm:^7.2.0"
http-server: "npm:14.1.1"
i18next: "npm:^24.0.0"
i18next-browser-languagedetector: "npm:^8.0.0"
@@ -18826,6 +18842,23 @@ __metadata:
languageName: node
linkType: hard
+"html-minifier-terser@npm:^7.2.0":
+ version: 7.2.0
+ resolution: "html-minifier-terser@npm:7.2.0"
+ dependencies:
+ camel-case: "npm:^4.1.2"
+ clean-css: "npm:~5.3.2"
+ commander: "npm:^10.0.0"
+ entities: "npm:^4.4.0"
+ param-case: "npm:^3.0.4"
+ relateurl: "npm:^0.2.7"
+ terser: "npm:^5.15.1"
+ bin:
+ html-minifier-terser: cli.js
+ checksum: 10/7320095dbf08c361b45e855bd840d1d21fe86326afee775503594163532ebaaed9bb1c9dc98232b03c169dc24b56f30c294d559bca0cade59f9c950a1992db82
+ languageName: node
+ linkType: hard
+
"html-parse-stringify@npm:^3.0.1":
version: 3.0.1
resolution: "html-parse-stringify@npm:3.0.1"
@@ -29466,7 +29499,7 @@ __metadata:
languageName: node
linkType: hard
-"terser@npm:^5.17.4, terser@npm:^5.26.0, terser@npm:^5.7.2":
+"terser@npm:^5.15.1, terser@npm:^5.17.4, terser@npm:^5.26.0, terser@npm:^5.7.2":
version: 5.29.2
resolution: "terser@npm:5.29.2"
dependencies: