@grafana/create-plugin 6.8.0-canary.2356.20815895884.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +101 -0
- package/dist/codemods/additions/additions.js +3 -3
- package/dist/codemods/utils.js +2 -2
- package/dist/constants.js +1 -0
- package/dist/utils/utils.templates.js +4 -1
- package/package.json +3 -3
- package/src/codemods/additions/additions.ts +3 -3
- package/src/constants.ts +1 -0
- package/src/types.ts +1 -0
- package/src/utils/tests/utils.config.test.ts +25 -3
- package/src/utils/utils.config.ts +1 -0
- package/src/utils/utils.templates.ts +10 -1
- package/templates/backend/go.mod +30 -29
- package/templates/backend/go.sum +62 -62
- package/templates/backend-app/go.mod +30 -29
- package/templates/backend-app/go.sum +62 -62
- package/templates/common/.config/bundler/copyFiles.ts +23 -0
- package/templates/common/.config/docker-compose-base.yaml +1 -1
- package/templates/common/.config/rspack/BuildModeRspackPlugin.ts +4 -4
- package/templates/common/.config/rspack/{liveReloadPlugin.js → liveReloadPlugin.ts} +34 -11
- package/templates/common/.config/rspack/rspack.config.ts +8 -22
- package/templates/common/.config/webpack/BuildModeWebpackPlugin.ts +1 -1
- package/templates/common/.config/webpack/webpack.config.ts +4 -17
- package/templates/common/.cprc.json +1 -0
- package/templates/common/_package.json +46 -44
- package/templates/github/workflows/bundle-stats.yml +1 -1
- package/templates/github/workflows/ci.yml +17 -10
- package/templates/github/workflows/is-compatible.yml +2 -2
- package/templates/github/workflows/release.yml +1 -1
- package/dist/codemods/additions/scripts/bundle-grafana-ui/index.js +0 -174
- package/dist/codemods/utils.bundler-config.js +0 -19
- package/dist/codemods/utils.externals.js +0 -116
- package/src/codemods/additions/scripts/bundle-grafana-ui/README.md +0 -68
- package/src/codemods/additions/scripts/bundle-grafana-ui/index.test.ts +0 -511
- package/src/codemods/additions/scripts/bundle-grafana-ui/index.ts +0 -259
- package/src/codemods/utils.bundler-config.ts +0 -203
- package/src/codemods/utils.externals.test.ts +0 -87
- package/src/codemods/utils.externals.ts +0 -181
- package/templates/common/.config/rspack/utils.ts +0 -63
- package/templates/common/.config/webpack/constants.ts +0 -2
- /package/templates/common/.config/{rspack → bundler}/constants.ts +0 -0
- /package/templates/common/.config/{webpack → bundler}/utils.ts +0 -0
|
@@ -17,65 +17,67 @@
|
|
|
17
17
|
"license": "Apache-2.0",
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@grafana/eslint-config": "^9.0.0",
|
|
20
|
-
"@grafana/plugin-e2e": "^3.1.
|
|
20
|
+
"@grafana/plugin-e2e": "^3.1.4",
|
|
21
21
|
"@grafana/tsconfig": "^2.0.1",
|
|
22
|
-
"@playwright/test": "^1.
|
|
23
|
-
"@rspack/core": "^1.
|
|
24
|
-
"@rspack/cli": "^1.
|
|
25
|
-
"@stylistic/eslint-plugin-ts": "^
|
|
26
|
-
"@swc/core": "^1.
|
|
22
|
+
"@playwright/test": "^1.57.0",{{#if useExperimentalRspack}}
|
|
23
|
+
"@rspack/core": "^1.6.0",
|
|
24
|
+
"@rspack/cli": "^1.6.0",{{/if}}
|
|
25
|
+
"@stylistic/eslint-plugin-ts": "^4.4.0",
|
|
26
|
+
"@swc/core": "^1.15.0",
|
|
27
27
|
"@swc/helpers": "^0.5.0",
|
|
28
|
-
"@swc/jest": "^0.2.
|
|
29
|
-
"@testing-library/jest-dom": "6.
|
|
30
|
-
"@testing-library/react": "
|
|
28
|
+
"@swc/jest": "^0.2.0",
|
|
29
|
+
"@testing-library/jest-dom": "^6.6.0",
|
|
30
|
+
"@testing-library/react": "^16.3.0",
|
|
31
31
|
"@types/jest": "^29.5.0",
|
|
32
|
-
"@types/node": "^
|
|
32
|
+
"@types/node": "^24.0.0",
|
|
33
33
|
"@types/react": "^18.3.0",
|
|
34
|
-
"@types/react-dom": "^18.3.0",
|
|
35
|
-
"@
|
|
36
|
-
"@typescript-eslint/
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"eslint
|
|
41
|
-
"eslint-
|
|
42
|
-
"eslint-plugin-
|
|
34
|
+
"@types/react-dom": "^18.3.0",{{#if useExperimentalRspack}}
|
|
35
|
+
"@types/ws": "^8.18.1",{{/if}}
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
|
37
|
+
"@typescript-eslint/parser": "^8.38.0",{{#unless useExperimentalRspack}}
|
|
38
|
+
"copy-webpack-plugin": "^13.0.0",{{/unless}}
|
|
39
|
+
"css-loader": "^7.1.0",
|
|
40
|
+
"eslint": "^9.32.0",
|
|
41
|
+
"eslint-config-prettier": "^10.1.0",
|
|
42
|
+
"eslint-plugin-jsdoc": "^52.0.0",
|
|
43
|
+
"eslint-plugin-react": "^7.37.0",
|
|
43
44
|
"eslint-plugin-react-hooks": "^7.0.0",
|
|
44
45
|
"eslint-webpack-plugin": "^5.0.0",{{#unless useExperimentalRspack}}
|
|
45
|
-
"fork-ts-checker-webpack-plugin": "^
|
|
46
|
-
"glob": "^
|
|
47
|
-
"identity-obj-proxy": "3.0.0",
|
|
46
|
+
"fork-ts-checker-webpack-plugin": "^9.1.0",{{/unless}}
|
|
47
|
+
"glob": "^11.1.0",
|
|
48
|
+
"identity-obj-proxy": "^3.0.0",
|
|
48
49
|
"imports-loader": "^5.0.0",
|
|
49
|
-
"jest": "^29.
|
|
50
|
-
"jest-environment-jsdom": "^29.
|
|
51
|
-
"prettier": "^
|
|
52
|
-
"replace-in-file-webpack-plugin": "^1.0.
|
|
53
|
-
"rspack-plugin-virtual-module": "^0.
|
|
54
|
-
"sass": "1.
|
|
55
|
-
"sass-loader": "
|
|
56
|
-
"semver": "^7.
|
|
57
|
-
"style-loader": "
|
|
58
|
-
"swc-loader": "^0.2.
|
|
59
|
-
"terser-webpack-plugin": "^5.3.
|
|
60
|
-
"ts-node": "^10.9.
|
|
61
|
-
"ts-checker-rspack-plugin": "^1.
|
|
62
|
-
"typescript": "5.
|
|
63
|
-
"webpack": "^5.
|
|
64
|
-
"webpack-cli": "^
|
|
50
|
+
"jest": "^29.7.0",
|
|
51
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
52
|
+
"prettier": "^3.6.0",
|
|
53
|
+
"replace-in-file-webpack-plugin": "^1.0.0",{{#if useExperimentalRspack}}
|
|
54
|
+
"rspack-plugin-virtual-module": "^1.0.0",{{/if}}
|
|
55
|
+
"sass": "^1.89.0",
|
|
56
|
+
"sass-loader": "^16.0.0",
|
|
57
|
+
"semver": "^7.7.0",
|
|
58
|
+
"style-loader": "^4.0.0",{{#unless useExperimentalRspack}}
|
|
59
|
+
"swc-loader": "^0.2.0",{{/unless}}
|
|
60
|
+
"terser-webpack-plugin": "^5.3.0",
|
|
61
|
+
"ts-node": "^10.9.0",{{#if useExperimentalRspack}}
|
|
62
|
+
"ts-checker-rspack-plugin": "^1.2.0",{{/if}}
|
|
63
|
+
"typescript": "5.9.2",
|
|
64
|
+
"webpack": "^5.101.0"{{#unless useExperimentalRspack}},
|
|
65
|
+
"webpack-cli": "^6.0.0",
|
|
65
66
|
"webpack-livereload-plugin": "^3.0.2",
|
|
66
67
|
"webpack-subresource-integrity": "^5.1.0",
|
|
67
|
-
"webpack-virtual-modules": "^0.6.2"{{/unless}}
|
|
68
|
+
"webpack-virtual-modules": "^0.6.2"{{/unless}}{{#if useExperimentalRspack}},
|
|
69
|
+
"ws": "^8.13.0"{{/if}}
|
|
68
70
|
},
|
|
69
71
|
"engines": {
|
|
70
72
|
"node": ">=22"
|
|
71
73
|
},
|
|
72
74
|
"dependencies": {
|
|
73
75
|
"@emotion/css": "11.10.6",
|
|
74
|
-
"@grafana/data": "^12.3.
|
|
75
|
-
"@grafana/i18n": "^12.3.
|
|
76
|
-
"@grafana/runtime": "^12.3.
|
|
77
|
-
"@grafana/ui": "^12.3.
|
|
78
|
-
"@grafana/schema": "^12.3.
|
|
76
|
+
"@grafana/data": "^12.3.2",
|
|
77
|
+
"@grafana/i18n": "^12.3.2",
|
|
78
|
+
"@grafana/runtime": "^12.3.2",
|
|
79
|
+
"@grafana/ui": "^12.3.2",
|
|
80
|
+
"@grafana/schema": "^12.3.2",{{#if_eq pluginType "scenesapp" }}
|
|
79
81
|
"@grafana/scenes": "{{ scenesVersion }}",{{/if_eq}}
|
|
80
82
|
"react": "^18.3.0",
|
|
81
83
|
"react-dom": "^18.3.0"{{#if isAppType}},
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
env:
|
|
26
26
|
GRAFANA_ACCESS_POLICY_TOKEN: $\{{ secrets.GRAFANA_ACCESS_POLICY_TOKEN }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v6
|
|
29
29
|
with:
|
|
30
30
|
persist-credentials: false
|
|
31
31
|
{{#if_eq packageManagerName "pnpm"}}
|
|
@@ -63,14 +63,14 @@ jobs:
|
|
|
63
63
|
if: steps.check-for-backend.outputs.has-backend == 'true'
|
|
64
64
|
uses: actions/setup-go@v6
|
|
65
65
|
with:
|
|
66
|
-
go-version:
|
|
66
|
+
go-version-file: go.mod
|
|
67
67
|
|
|
68
|
-
- name:
|
|
68
|
+
- name: Lint backend
|
|
69
69
|
if: steps.check-for-backend.outputs.has-backend == 'true'
|
|
70
|
-
uses:
|
|
70
|
+
uses: golangci/golangci-lint-action@9fae48acfc02a90574d7c304a1758ef9895495fa # v7.0.1
|
|
71
71
|
with:
|
|
72
72
|
version: latest
|
|
73
|
-
args:
|
|
73
|
+
args: ./...
|
|
74
74
|
|
|
75
75
|
- name: Build backend
|
|
76
76
|
if: steps.check-for-backend.outputs.has-backend == 'true'
|
|
@@ -79,6 +79,13 @@ jobs:
|
|
|
79
79
|
version: latest
|
|
80
80
|
args: buildAll
|
|
81
81
|
|
|
82
|
+
- name: Test backend
|
|
83
|
+
if: steps.check-for-backend.outputs.has-backend == 'true'
|
|
84
|
+
uses: magefile/mage-action@6f50bbb8ea47d56e62dee92392788acbc8192d0b # v3.1.0
|
|
85
|
+
with:
|
|
86
|
+
version: latest
|
|
87
|
+
args: test
|
|
88
|
+
|
|
82
89
|
- name: Check for E2E
|
|
83
90
|
id: check-for-e2e
|
|
84
91
|
run: |
|
|
@@ -122,7 +129,7 @@ jobs:
|
|
|
122
129
|
ARCHIVE: $\{{ steps.metadata.outputs.archive }}
|
|
123
130
|
|
|
124
131
|
- name: Archive Build
|
|
125
|
-
uses: actions/upload-artifact@
|
|
132
|
+
uses: actions/upload-artifact@v6
|
|
126
133
|
with:
|
|
127
134
|
name: $\{{ steps.metadata.outputs.plugin-id }}-$\{{ steps.metadata.outputs.plugin-version }}
|
|
128
135
|
path: $\{{ steps.metadata.outputs.plugin-id }}
|
|
@@ -140,7 +147,7 @@ jobs:
|
|
|
140
147
|
matrix: $\{{ steps.resolve-versions.outputs.matrix }}
|
|
141
148
|
steps:
|
|
142
149
|
- name: Checkout
|
|
143
|
-
uses: actions/checkout@
|
|
150
|
+
uses: actions/checkout@v6
|
|
144
151
|
with:
|
|
145
152
|
persist-credentials: false
|
|
146
153
|
|
|
@@ -162,12 +169,12 @@ jobs:
|
|
|
162
169
|
name: e2e test $\{{ matrix.GRAFANA_IMAGE.name }}@$\{{ matrix.GRAFANA_IMAGE.VERSION }}
|
|
163
170
|
runs-on: ubuntu-latest
|
|
164
171
|
steps:
|
|
165
|
-
- uses: actions/checkout@
|
|
172
|
+
- uses: actions/checkout@v6
|
|
166
173
|
with:
|
|
167
174
|
persist-credentials: false
|
|
168
175
|
|
|
169
176
|
- name: Download plugin
|
|
170
|
-
uses: actions/download-artifact@
|
|
177
|
+
uses: actions/download-artifact@v7
|
|
171
178
|
with:
|
|
172
179
|
path: dist
|
|
173
180
|
name: $\{{ needs.build.outputs.plugin-id }}-$\{{ needs.build.outputs.plugin-version }}
|
|
@@ -242,7 +249,7 @@ jobs:
|
|
|
242
249
|
needs: [playwright-tests]
|
|
243
250
|
runs-on: ubuntu-latest
|
|
244
251
|
steps:
|
|
245
|
-
- uses: actions/checkout@
|
|
252
|
+
- uses: actions/checkout@v6
|
|
246
253
|
with:
|
|
247
254
|
# required for playwright-gh-pages
|
|
248
255
|
persist-credentials: true
|
|
@@ -7,7 +7,7 @@ jobs:
|
|
|
7
7
|
permissions:
|
|
8
8
|
contents: read
|
|
9
9
|
steps:
|
|
10
|
-
- uses: actions/checkout@
|
|
10
|
+
- uses: actions/checkout@v6
|
|
11
11
|
with:
|
|
12
12
|
persist-credentials: false
|
|
13
13
|
|
|
@@ -18,7 +18,7 @@ jobs:
|
|
|
18
18
|
{{/if_eq}}
|
|
19
19
|
|
|
20
20
|
- name: Setup Node.js environment
|
|
21
|
-
uses: actions/setup-node@
|
|
21
|
+
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
|
22
22
|
with:
|
|
23
23
|
node-version: '22'
|
|
24
24
|
cache: '{{ packageManagerName }}'
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import * as v from 'valibot';
|
|
2
|
-
import * as recast from 'recast';
|
|
3
|
-
import { coerce, gte } from 'semver';
|
|
4
|
-
import { additionsDebug } from '../../../utils.js';
|
|
5
|
-
import { getBundlerConfig } from '../../../utils.bundler-config.js';
|
|
6
|
-
import { updateExternalsArray } from '../../../utils.externals.js';
|
|
7
|
-
|
|
8
|
-
const { builders } = recast.types;
|
|
9
|
-
const PLUGIN_JSON_PATH = "src/plugin.json";
|
|
10
|
-
const MIN_GRAFANA_VERSION = "10.2.0";
|
|
11
|
-
const schema = v.object({});
|
|
12
|
-
function bundleGrafanaUI(context, _options) {
|
|
13
|
-
additionsDebug("Running bundle-grafana-ui addition...");
|
|
14
|
-
ensureMinGrafanaVersion(context);
|
|
15
|
-
updateExternalsArray(context, createBundleGrafanaUIModifier());
|
|
16
|
-
updateResolveExtensions(context);
|
|
17
|
-
updateModuleRules(context);
|
|
18
|
-
return context;
|
|
19
|
-
}
|
|
20
|
-
function isGrafanaRegex(element, pattern) {
|
|
21
|
-
if (element.type === "RegExpLiteral") {
|
|
22
|
-
const regexNode = element;
|
|
23
|
-
return regexNode.pattern === pattern && regexNode.flags === "i";
|
|
24
|
-
}
|
|
25
|
-
if (element.type === "Literal" && "regex" in element && element.regex) {
|
|
26
|
-
const regex = element.regex;
|
|
27
|
-
return regex.pattern === pattern && regex.flags === "i";
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
function removeGrafanaUiAndAddReactInlineSvg(externalsArray) {
|
|
32
|
-
let hasChanges = false;
|
|
33
|
-
let hasGrafanaUiExternal = false;
|
|
34
|
-
let hasReactInlineSvg = false;
|
|
35
|
-
for (const element of externalsArray.elements) {
|
|
36
|
-
if (!element) {
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (isGrafanaRegex(element, "^@grafana\\/ui")) {
|
|
40
|
-
hasGrafanaUiExternal = true;
|
|
41
|
-
}
|
|
42
|
-
if ((element.type === "Literal" || element.type === "StringLiteral") && "value" in element && typeof element.value === "string" && element.value === "react-inlinesvg") {
|
|
43
|
-
hasReactInlineSvg = true;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (hasGrafanaUiExternal) {
|
|
47
|
-
externalsArray.elements = externalsArray.elements.filter((element) => {
|
|
48
|
-
if (!element) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
return !isGrafanaRegex(element, "^@grafana\\/ui");
|
|
52
|
-
});
|
|
53
|
-
hasChanges = true;
|
|
54
|
-
additionsDebug("Removed /^@grafana\\/ui/i from externals array");
|
|
55
|
-
}
|
|
56
|
-
if (!hasReactInlineSvg) {
|
|
57
|
-
let insertIndex = -1;
|
|
58
|
-
for (let i = 0; i < externalsArray.elements.length; i++) {
|
|
59
|
-
const element = externalsArray.elements[i];
|
|
60
|
-
if (element && isGrafanaRegex(element, "^@grafana\\/data")) {
|
|
61
|
-
insertIndex = i + 1;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (insertIndex >= 0) {
|
|
66
|
-
externalsArray.elements.splice(insertIndex, 0, builders.literal("react-inlinesvg"));
|
|
67
|
-
} else {
|
|
68
|
-
externalsArray.elements.push(builders.literal("react-inlinesvg"));
|
|
69
|
-
}
|
|
70
|
-
hasChanges = true;
|
|
71
|
-
additionsDebug("Added 'react-inlinesvg' to externals array");
|
|
72
|
-
}
|
|
73
|
-
return hasChanges;
|
|
74
|
-
}
|
|
75
|
-
function createBundleGrafanaUIModifier() {
|
|
76
|
-
return (externalsArray) => {
|
|
77
|
-
return removeGrafanaUiAndAddReactInlineSvg(externalsArray);
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
function updateResolveExtensions(context) {
|
|
81
|
-
const config = getBundlerConfig(context);
|
|
82
|
-
if (!config) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const { path: configPath, content } = config;
|
|
86
|
-
if (content.includes("'.mjs'") || content.includes('".mjs"')) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const updated = content.replace(/(extensions:\s*\[)([^\]]+)(\])/, (match, prefix, extensions, suffix) => {
|
|
90
|
-
if (extensions.includes(".mjs")) {
|
|
91
|
-
return match;
|
|
92
|
-
}
|
|
93
|
-
return `${prefix}${extensions}, '.mjs'${suffix}`;
|
|
94
|
-
});
|
|
95
|
-
if (updated !== content) {
|
|
96
|
-
context.updateFile(configPath, updated);
|
|
97
|
-
additionsDebug("Added '.mjs' to resolve.extensions");
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function updateModuleRules(context) {
|
|
101
|
-
const config = getBundlerConfig(context);
|
|
102
|
-
if (!config) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const { path: configPath, content } = config;
|
|
106
|
-
if (content.includes("test: /\\.mjs$") || content.includes("test: /\\\\.mjs$")) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const mjsRule = `{
|
|
110
|
-
test: /\\.mjs$/,
|
|
111
|
-
include: /node_modules/,
|
|
112
|
-
resolve: {
|
|
113
|
-
fullySpecified: false,
|
|
114
|
-
},
|
|
115
|
-
type: 'javascript/auto',
|
|
116
|
-
},`;
|
|
117
|
-
let updated = content;
|
|
118
|
-
if (content.match(/rules:\s*\[\s*\]/)) {
|
|
119
|
-
updated = content.replace(/(rules:\s*\[\s*)(\])/, `$1${mjsRule}
|
|
120
|
-
$2`);
|
|
121
|
-
} else {
|
|
122
|
-
updated = content.replace(/(rules:\s*\[\s*)(\{[\s\S]*?\}),(\s*)/, (match, prefix, firstRule, suffix) => {
|
|
123
|
-
if (match.includes("test: /\\.mjs$")) {
|
|
124
|
-
return match;
|
|
125
|
-
}
|
|
126
|
-
return `${prefix}${firstRule},
|
|
127
|
-
${mjsRule}${suffix}`;
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
if (updated !== content) {
|
|
131
|
-
context.updateFile(configPath, updated);
|
|
132
|
-
additionsDebug("Added module rule for .mjs files in node_modules with resolve.fullySpecified: false");
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function ensureMinGrafanaVersion(context) {
|
|
136
|
-
if (!context.doesFileExist(PLUGIN_JSON_PATH)) {
|
|
137
|
-
additionsDebug(`${PLUGIN_JSON_PATH} not found, skipping version check`);
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const pluginJsonRaw = context.getFile(PLUGIN_JSON_PATH);
|
|
141
|
-
if (!pluginJsonRaw) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
const pluginJson = JSON.parse(pluginJsonRaw);
|
|
146
|
-
if (!pluginJson.dependencies) {
|
|
147
|
-
pluginJson.dependencies = {};
|
|
148
|
-
}
|
|
149
|
-
const currentGrafanaDep = pluginJson.dependencies.grafanaDependency || ">=9.0.0";
|
|
150
|
-
const currentVersion = coerce(currentGrafanaDep.replace(/^[><=]+/, ""));
|
|
151
|
-
const minVersion = coerce(MIN_GRAFANA_VERSION);
|
|
152
|
-
if (!currentVersion || !minVersion || !gte(currentVersion, minVersion)) {
|
|
153
|
-
const oldVersion = pluginJson.dependencies.grafanaDependency || "not set";
|
|
154
|
-
pluginJson.dependencies.grafanaDependency = `>=${MIN_GRAFANA_VERSION}`;
|
|
155
|
-
context.updateFile(PLUGIN_JSON_PATH, JSON.stringify(pluginJson, null, 2));
|
|
156
|
-
additionsDebug(
|
|
157
|
-
`Updated grafanaDependency from "${oldVersion}" to ">=${MIN_GRAFANA_VERSION}" - bundling @grafana/ui requires Grafana ${MIN_GRAFANA_VERSION} or higher`
|
|
158
|
-
);
|
|
159
|
-
console.log(
|
|
160
|
-
`
|
|
161
|
-
\u26A0\uFE0F Updated grafanaDependency to ">=${MIN_GRAFANA_VERSION}" because bundling @grafana/ui is only supported from Grafana ${MIN_GRAFANA_VERSION} onwards.
|
|
162
|
-
`
|
|
163
|
-
);
|
|
164
|
-
} else {
|
|
165
|
-
additionsDebug(
|
|
166
|
-
`grafanaDependency "${currentGrafanaDep}" already meets minimum requirement of ${MIN_GRAFANA_VERSION}`
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
} catch (error) {
|
|
170
|
-
additionsDebug(`Error updating ${PLUGIN_JSON_PATH}:`, error);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export { bundleGrafanaUI as default, schema };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import 'recast';
|
|
2
|
-
import 'recast/parsers/typescript.js';
|
|
3
|
-
import './utils.js';
|
|
4
|
-
|
|
5
|
-
const WEBPACK_CONFIG_PATH = ".config/webpack/webpack.config.ts";
|
|
6
|
-
const RSPACK_CONFIG_PATH = ".config/rspack/rspack.config.ts";
|
|
7
|
-
function getBundlerConfig(context) {
|
|
8
|
-
const configPath = context.doesFileExist(RSPACK_CONFIG_PATH) ? RSPACK_CONFIG_PATH : context.doesFileExist(WEBPACK_CONFIG_PATH) ? WEBPACK_CONFIG_PATH : null;
|
|
9
|
-
if (!configPath) {
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
const content = context.getFile(configPath);
|
|
13
|
-
if (!content) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
return { path: configPath, content };
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { getBundlerConfig };
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as recast from 'recast';
|
|
2
|
-
import * as typeScriptParser from 'recast/parsers/typescript.js';
|
|
3
|
-
import { additionsDebug } from './utils.js';
|
|
4
|
-
|
|
5
|
-
const EXTERNALS_PATH = ".config/bundler/externals.ts";
|
|
6
|
-
const WEBPACK_CONFIG_PATH = ".config/webpack/webpack.config.ts";
|
|
7
|
-
function updateExternalsArray(context, modifier) {
|
|
8
|
-
if (context.doesFileExist(EXTERNALS_PATH)) {
|
|
9
|
-
additionsDebug(`Found ${EXTERNALS_PATH}, updating externals array...`);
|
|
10
|
-
const externalsContent = context.getFile(EXTERNALS_PATH);
|
|
11
|
-
if (externalsContent) {
|
|
12
|
-
try {
|
|
13
|
-
const ast = recast.parse(externalsContent, {
|
|
14
|
-
parser: typeScriptParser
|
|
15
|
-
});
|
|
16
|
-
let hasChanges = false;
|
|
17
|
-
recast.visit(ast, {
|
|
18
|
-
visitVariableDeclarator(path) {
|
|
19
|
-
const { node } = path;
|
|
20
|
-
if (node.id.type === "Identifier" && node.id.name === "externals" && node.init && node.init.type === "ArrayExpression") {
|
|
21
|
-
additionsDebug("Found externals array in externals.ts");
|
|
22
|
-
if (modifier(node.init)) {
|
|
23
|
-
hasChanges = true;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return this.traverse(path);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
if (hasChanges) {
|
|
30
|
-
const output = recast.print(ast, {
|
|
31
|
-
tabWidth: 2,
|
|
32
|
-
trailingComma: true,
|
|
33
|
-
lineTerminator: "\n"
|
|
34
|
-
});
|
|
35
|
-
context.updateFile(EXTERNALS_PATH, output.code);
|
|
36
|
-
additionsDebug(`Updated ${EXTERNALS_PATH}`);
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
return false;
|
|
40
|
-
} catch (error) {
|
|
41
|
-
additionsDebug(`Error updating ${EXTERNALS_PATH}:`, error);
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
additionsDebug(`Checking for ${WEBPACK_CONFIG_PATH}...`);
|
|
47
|
-
if (context.doesFileExist(WEBPACK_CONFIG_PATH)) {
|
|
48
|
-
additionsDebug(`Found ${WEBPACK_CONFIG_PATH}, checking for inline externals...`);
|
|
49
|
-
const webpackContent = context.getFile(WEBPACK_CONFIG_PATH);
|
|
50
|
-
if (webpackContent) {
|
|
51
|
-
try {
|
|
52
|
-
const ast = recast.parse(webpackContent, {
|
|
53
|
-
parser: typeScriptParser
|
|
54
|
-
});
|
|
55
|
-
let hasChanges = false;
|
|
56
|
-
let foundExternals = false;
|
|
57
|
-
recast.visit(ast, {
|
|
58
|
-
visitObjectExpression(path) {
|
|
59
|
-
const { node } = path;
|
|
60
|
-
const properties = node.properties;
|
|
61
|
-
if (properties) {
|
|
62
|
-
for (const prop of properties) {
|
|
63
|
-
if (prop && (prop.type === "Property" || prop.type === "ObjectProperty")) {
|
|
64
|
-
const key = "key" in prop ? prop.key : null;
|
|
65
|
-
const value = "value" in prop ? prop.value : null;
|
|
66
|
-
if (key && key.type === "Identifier" && key.name === "externals" && value && value.type === "ArrayExpression") {
|
|
67
|
-
foundExternals = true;
|
|
68
|
-
additionsDebug("Found externals property in webpack.config.ts");
|
|
69
|
-
if (modifier(value)) {
|
|
70
|
-
hasChanges = true;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return this.traverse(path);
|
|
77
|
-
},
|
|
78
|
-
visitProperty(path) {
|
|
79
|
-
const { node } = path;
|
|
80
|
-
if (node.key && node.key.type === "Identifier" && node.key.name === "externals" && node.value && node.value.type === "ArrayExpression") {
|
|
81
|
-
if (!foundExternals) {
|
|
82
|
-
foundExternals = true;
|
|
83
|
-
additionsDebug("Found externals property in webpack.config.ts (via visitProperty)");
|
|
84
|
-
}
|
|
85
|
-
if (modifier(node.value)) {
|
|
86
|
-
hasChanges = true;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return this.traverse(path);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
if (!foundExternals) {
|
|
93
|
-
additionsDebug("No externals property found in webpack.config.ts");
|
|
94
|
-
}
|
|
95
|
-
if (hasChanges) {
|
|
96
|
-
const output = recast.print(ast, {
|
|
97
|
-
tabWidth: 2,
|
|
98
|
-
trailingComma: true,
|
|
99
|
-
lineTerminator: "\n"
|
|
100
|
-
});
|
|
101
|
-
context.updateFile(WEBPACK_CONFIG_PATH, output.code);
|
|
102
|
-
additionsDebug(`Updated ${WEBPACK_CONFIG_PATH}`);
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
return false;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
additionsDebug(`Error updating ${WEBPACK_CONFIG_PATH}:`, error);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
additionsDebug("No externals configuration found");
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export { updateExternalsArray };
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Bundle Grafana UI Addition
|
|
2
|
-
|
|
3
|
-
Configures a Grafana plugin to bundle `@grafana/ui` instead of using the version of `@grafana/ui` provided by the Grafana runtime environment.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npx @grafana/create-plugin add bundle-grafana-ui
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Requirements
|
|
12
|
-
|
|
13
|
-
- **Grafana >= 10.2.0**: Bundling `@grafana/ui` is only supported from Grafana 10.2.0 onwards. If your plugin's `grafanaDependency` is set to a version lower than 10.2.0, the script will automatically update it to `>=10.2.0` and display a warning message.
|
|
14
|
-
|
|
15
|
-
## What This Addition Does
|
|
16
|
-
|
|
17
|
-
By default, Grafana plugins use `@grafana/ui` as an external dependency provided by Grafana at runtime. This addition modifies your plugin's bundler configuration to include `@grafana/ui` in your plugin bundle instead.
|
|
18
|
-
|
|
19
|
-
This addition:
|
|
20
|
-
|
|
21
|
-
1. **Updates `src/plugin.json`** - Ensures `grafanaDependency` is set to `>=10.2.0` or higher
|
|
22
|
-
2. **Removes `/^@grafana\/ui/i` from externals** - This tells the bundler to include `@grafana/ui` in your plugin bundle rather than expecting Grafana to provide it
|
|
23
|
-
3. **Adds `'react-inlinesvg'` to externals** - Since `@grafana/ui` uses `react-inlinesvg` internally and Grafana provides it at runtime, we add it to externals to avoid bundling it twice
|
|
24
|
-
4. **Updates bundler resolve configuration** - Adds `.mjs` to `resolve.extensions` and sets `resolve.fullySpecified: false` to handle ESM imports from `@grafana/ui` and its dependencies (e.g., `rc-picker`, `ol/format/WKT`)
|
|
25
|
-
|
|
26
|
-
## When to Use This
|
|
27
|
-
|
|
28
|
-
Consider bundling `@grafana/ui` when:
|
|
29
|
-
|
|
30
|
-
- You want to ensure consistent behavior across different Grafana versions
|
|
31
|
-
- You're experiencing compatibility issues with the Grafana-provided `@grafana/ui`
|
|
32
|
-
|
|
33
|
-
## Trade-offs
|
|
34
|
-
|
|
35
|
-
**Pros:**
|
|
36
|
-
|
|
37
|
-
- Full control over the `@grafana/ui` version your plugin uses
|
|
38
|
-
- Consistent behavior regardless of Grafana version
|
|
39
|
-
|
|
40
|
-
**Cons:**
|
|
41
|
-
|
|
42
|
-
- Larger plugin bundle size
|
|
43
|
-
- Potential visual inconsistencies if your bundled version differs significantly from Grafana's version
|
|
44
|
-
- You'll need to manually update `@grafana/ui` in your plugin dependencies
|
|
45
|
-
|
|
46
|
-
## Files Modified
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
your-plugin/
|
|
50
|
-
├── src/
|
|
51
|
-
│ └── plugin.json # Modified: grafanaDependency updated if needed
|
|
52
|
-
├── .config/
|
|
53
|
-
│ ├── bundler/
|
|
54
|
-
│ │ └── externals.ts # Modified: removes @grafana/ui, adds react-inlinesvg
|
|
55
|
-
│ └── rspack/
|
|
56
|
-
│ └── rspack.config.ts # Modified: resolve.extensions and resolve.fullySpecified updated
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Or for legacy structure:
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
your-plugin/
|
|
63
|
-
├── src/
|
|
64
|
-
│ └── plugin.json # Modified: grafanaDependency updated if needed
|
|
65
|
-
├── .config/
|
|
66
|
-
│ └── webpack/
|
|
67
|
-
│ └── webpack.config.ts # Modified: externals array and resolve configuration updated
|
|
68
|
-
```
|