@grafana/create-plugin 6.7.1-canary.2370.20798217827.0 → 6.8.0-canary.2356.20813241719.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/dist/codemods/additions/additions.js +3 -3
- package/dist/codemods/additions/scripts/bundle-grafana-ui/index.js +319 -0
- package/dist/codemods/utils.externals.js +116 -0
- package/dist/codemods/utils.js +2 -2
- package/dist/constants.js +0 -1
- package/dist/utils/utils.templates.js +1 -4
- package/package.json +2 -2
- package/src/codemods/additions/additions.ts +3 -3
- package/src/codemods/additions/scripts/bundle-grafana-ui/README.md +68 -0
- package/src/codemods/additions/scripts/bundle-grafana-ui/index.test.ts +511 -0
- package/src/codemods/additions/scripts/bundle-grafana-ui/index.ts +488 -0
- package/src/codemods/utils.externals.test.ts +87 -0
- package/src/codemods/utils.externals.ts +181 -0
- package/src/constants.ts +0 -1
- package/src/types.ts +0 -1
- package/src/utils/tests/utils.config.test.ts +3 -25
- package/src/utils/utils.config.ts +0 -1
- package/src/utils/utils.templates.ts +1 -10
- package/templates/common/.config/webpack/BuildModeWebpackPlugin.ts +1 -1
- package/templates/common/.cprc.json +4 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import * as recast from 'recast';
|
|
2
|
+
import * as typeScriptParser from 'recast/parsers/typescript.js';
|
|
3
|
+
|
|
4
|
+
import type { Context } from './context.js';
|
|
5
|
+
import { additionsDebug } from './utils.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Utility for updating externals arrays in plugin bundler configurations.
|
|
9
|
+
*
|
|
10
|
+
* This utility is needed because the location of externals configuration has changed over time:
|
|
11
|
+
* - **New plugins** (created with recent versions of @grafana/create-plugin): Externals are defined
|
|
12
|
+
* in a separate file at `.config/bundler/externals.ts`
|
|
13
|
+
* - **Older plugins** (created with earlier versions): Externals are defined inline within
|
|
14
|
+
* `.config/webpack/webpack.config.ts` as part of the webpack Configuration object
|
|
15
|
+
*
|
|
16
|
+
* This utility handles both cases automatically, preferring the modern structure when both exist,
|
|
17
|
+
* to ensure additions and migrations work correctly regardless of when the plugin was created.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Type for a function that modifies an externals array
|
|
22
|
+
* @param externalsArray - The AST node representing the externals array
|
|
23
|
+
* @returns true if changes were made, false otherwise
|
|
24
|
+
*/
|
|
25
|
+
export type ExternalsArrayModifier = (externalsArray: recast.types.namedTypes.ArrayExpression) => boolean;
|
|
26
|
+
|
|
27
|
+
const EXTERNALS_PATH = '.config/bundler/externals.ts';
|
|
28
|
+
const WEBPACK_CONFIG_PATH = '.config/webpack/webpack.config.ts';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Updates the externals array in either .config/bundler/externals.ts (preferred) or
|
|
32
|
+
* .config/webpack/webpack.config.ts (legacy fallback).
|
|
33
|
+
*
|
|
34
|
+
* @param context - The codemod context
|
|
35
|
+
* @param modifier - A function that modifies the externals array and returns true if changes were made
|
|
36
|
+
* @returns true if changes were made to any file, false otherwise
|
|
37
|
+
*/
|
|
38
|
+
export function updateExternalsArray(context: Context, modifier: ExternalsArrayModifier): boolean {
|
|
39
|
+
// Try new structure first: .config/bundler/externals.ts
|
|
40
|
+
if (context.doesFileExist(EXTERNALS_PATH)) {
|
|
41
|
+
additionsDebug(`Found ${EXTERNALS_PATH}, updating externals array...`);
|
|
42
|
+
const externalsContent = context.getFile(EXTERNALS_PATH);
|
|
43
|
+
if (externalsContent) {
|
|
44
|
+
try {
|
|
45
|
+
const ast = recast.parse(externalsContent, {
|
|
46
|
+
parser: typeScriptParser,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
let hasChanges = false;
|
|
50
|
+
|
|
51
|
+
recast.visit(ast, {
|
|
52
|
+
visitVariableDeclarator(path) {
|
|
53
|
+
const { node } = path;
|
|
54
|
+
|
|
55
|
+
if (
|
|
56
|
+
node.id.type === 'Identifier' &&
|
|
57
|
+
node.id.name === 'externals' &&
|
|
58
|
+
node.init &&
|
|
59
|
+
node.init.type === 'ArrayExpression'
|
|
60
|
+
) {
|
|
61
|
+
additionsDebug('Found externals array in externals.ts');
|
|
62
|
+
if (modifier(node.init)) {
|
|
63
|
+
hasChanges = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this.traverse(path);
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (hasChanges) {
|
|
72
|
+
const output = recast.print(ast, {
|
|
73
|
+
tabWidth: 2,
|
|
74
|
+
trailingComma: true,
|
|
75
|
+
lineTerminator: '\n',
|
|
76
|
+
});
|
|
77
|
+
context.updateFile(EXTERNALS_PATH, output.code);
|
|
78
|
+
additionsDebug(`Updated ${EXTERNALS_PATH}`);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
additionsDebug(`Error updating ${EXTERNALS_PATH}:`, error);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Fall back to legacy structure: .config/webpack/webpack.config.ts with inline externals
|
|
90
|
+
additionsDebug(`Checking for ${WEBPACK_CONFIG_PATH}...`);
|
|
91
|
+
if (context.doesFileExist(WEBPACK_CONFIG_PATH)) {
|
|
92
|
+
additionsDebug(`Found ${WEBPACK_CONFIG_PATH}, checking for inline externals...`);
|
|
93
|
+
const webpackContent = context.getFile(WEBPACK_CONFIG_PATH);
|
|
94
|
+
if (webpackContent) {
|
|
95
|
+
try {
|
|
96
|
+
const ast = recast.parse(webpackContent, {
|
|
97
|
+
parser: typeScriptParser,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
let hasChanges = false;
|
|
101
|
+
let foundExternals = false;
|
|
102
|
+
|
|
103
|
+
recast.visit(ast, {
|
|
104
|
+
visitObjectExpression(path) {
|
|
105
|
+
const { node } = path;
|
|
106
|
+
const properties = node.properties;
|
|
107
|
+
|
|
108
|
+
if (properties) {
|
|
109
|
+
for (const prop of properties) {
|
|
110
|
+
if (prop && (prop.type === 'Property' || prop.type === 'ObjectProperty')) {
|
|
111
|
+
const key = 'key' in prop ? prop.key : null;
|
|
112
|
+
const value = 'value' in prop ? prop.value : null;
|
|
113
|
+
|
|
114
|
+
if (
|
|
115
|
+
key &&
|
|
116
|
+
key.type === 'Identifier' &&
|
|
117
|
+
key.name === 'externals' &&
|
|
118
|
+
value &&
|
|
119
|
+
value.type === 'ArrayExpression'
|
|
120
|
+
) {
|
|
121
|
+
foundExternals = true;
|
|
122
|
+
additionsDebug('Found externals property in webpack.config.ts');
|
|
123
|
+
if (modifier(value)) {
|
|
124
|
+
hasChanges = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return this.traverse(path);
|
|
132
|
+
},
|
|
133
|
+
visitProperty(path) {
|
|
134
|
+
const { node } = path;
|
|
135
|
+
|
|
136
|
+
// Also check properties directly (fallback)
|
|
137
|
+
if (
|
|
138
|
+
node.key &&
|
|
139
|
+
node.key.type === 'Identifier' &&
|
|
140
|
+
node.key.name === 'externals' &&
|
|
141
|
+
node.value &&
|
|
142
|
+
node.value.type === 'ArrayExpression'
|
|
143
|
+
) {
|
|
144
|
+
if (!foundExternals) {
|
|
145
|
+
foundExternals = true;
|
|
146
|
+
additionsDebug('Found externals property in webpack.config.ts (via visitProperty)');
|
|
147
|
+
}
|
|
148
|
+
if (modifier(node.value)) {
|
|
149
|
+
hasChanges = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return this.traverse(path);
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
if (!foundExternals) {
|
|
158
|
+
additionsDebug('No externals property found in webpack.config.ts');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (hasChanges) {
|
|
162
|
+
const output = recast.print(ast, {
|
|
163
|
+
tabWidth: 2,
|
|
164
|
+
trailingComma: true,
|
|
165
|
+
lineTerminator: '\n',
|
|
166
|
+
});
|
|
167
|
+
context.updateFile(WEBPACK_CONFIG_PATH, output.code);
|
|
168
|
+
additionsDebug(`Updated ${WEBPACK_CONFIG_PATH}`);
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
additionsDebug(`Error updating ${WEBPACK_CONFIG_PATH}:`, error);
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
additionsDebug('No externals configuration found');
|
|
180
|
+
return false;
|
|
181
|
+
}
|
package/src/constants.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -46,13 +46,13 @@ describe('getConfig', () => {
|
|
|
46
46
|
|
|
47
47
|
it('should override default feature flags via cli args', async () => {
|
|
48
48
|
mocks.argv = {
|
|
49
|
-
'feature-flags': '
|
|
49
|
+
'feature-flags': 'useExperimentalRspack',
|
|
50
50
|
};
|
|
51
51
|
const config = getConfig(tmpDir);
|
|
52
52
|
|
|
53
53
|
expect(config).toEqual({
|
|
54
54
|
version: CURRENT_APP_VERSION,
|
|
55
|
-
features: { ...DEFAULT_FEATURE_FLAGS,
|
|
55
|
+
features: { ...DEFAULT_FEATURE_FLAGS, useExperimentalRspack: true },
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
});
|
|
@@ -94,7 +94,7 @@ describe('getConfig', () => {
|
|
|
94
94
|
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
95
95
|
const userConfig: UserConfig = {
|
|
96
96
|
features: {
|
|
97
|
-
|
|
97
|
+
useExperimentalRspack: true,
|
|
98
98
|
},
|
|
99
99
|
};
|
|
100
100
|
|
|
@@ -107,27 +107,5 @@ describe('getConfig', () => {
|
|
|
107
107
|
features: userConfig.features,
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
|
-
|
|
111
|
-
it('should give back the correct config when config files exist', async () => {
|
|
112
|
-
const rootConfigPath = path.join(tmpDir, '.config', '.cprc.json');
|
|
113
|
-
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
114
|
-
const rootConfig: CreatePluginConfig = {
|
|
115
|
-
version: '1.0.0',
|
|
116
|
-
features: {},
|
|
117
|
-
};
|
|
118
|
-
const userConfig: UserConfig = {
|
|
119
|
-
features: {
|
|
120
|
-
bundleGrafanaUI: false,
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
await fs.mkdir(path.dirname(rootConfigPath), { recursive: true });
|
|
125
|
-
await fs.writeFile(rootConfigPath, JSON.stringify(rootConfig));
|
|
126
|
-
await fs.writeFile(userConfigPath, JSON.stringify(userConfig));
|
|
127
|
-
|
|
128
|
-
const config = getConfig(tmpDir);
|
|
129
|
-
|
|
130
|
-
expect(config).toEqual({ ...rootConfig, ...userConfig });
|
|
131
|
-
});
|
|
132
110
|
});
|
|
133
111
|
});
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DEFAULT_FEATURE_FLAGS,
|
|
3
|
-
EXPORT_PATH_PREFIX,
|
|
4
|
-
EXTRA_TEMPLATE_VARIABLES,
|
|
5
|
-
PLUGIN_TYPES,
|
|
6
|
-
TEMPLATE_PATHS,
|
|
7
|
-
} from '../constants.js';
|
|
1
|
+
import { EXPORT_PATH_PREFIX, EXTRA_TEMPLATE_VARIABLES, PLUGIN_TYPES, TEMPLATE_PATHS } from '../constants.js';
|
|
8
2
|
import { GenerateCliArgs, TemplateData } from '../types.js';
|
|
9
3
|
import { filterOutCommonFiles, isFile, isFileStartingWith } from './utils.files.js';
|
|
10
4
|
import {
|
|
@@ -95,7 +89,6 @@ export function renderTemplateFromFile(templateFile: string, data?: any) {
|
|
|
95
89
|
export function getTemplateData(cliArgs?: GenerateCliArgs): TemplateData {
|
|
96
90
|
const { features } = getConfig();
|
|
97
91
|
const currentVersion = CURRENT_APP_VERSION;
|
|
98
|
-
const bundleGrafanaUI = features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI;
|
|
99
92
|
const isAppType = (pluginType: string) => pluginType === PLUGIN_TYPES.app || pluginType === PLUGIN_TYPES.scenes;
|
|
100
93
|
const isNPM = (packageManagerName: string) => packageManagerName === 'npm';
|
|
101
94
|
const frontendBundler = features.useExperimentalRspack ? 'rspack' : 'webpack';
|
|
@@ -120,7 +113,6 @@ export function getTemplateData(cliArgs?: GenerateCliArgs): TemplateData {
|
|
|
120
113
|
isAppType: isAppType(cliArgs.pluginType),
|
|
121
114
|
isNPM: isNPM(packageManagerName),
|
|
122
115
|
version: currentVersion,
|
|
123
|
-
bundleGrafanaUI,
|
|
124
116
|
scenesVersion: '^6.10.4',
|
|
125
117
|
useExperimentalRspack: Boolean(features.useExperimentalRspack),
|
|
126
118
|
frontendBundler,
|
|
@@ -144,7 +136,6 @@ export function getTemplateData(cliArgs?: GenerateCliArgs): TemplateData {
|
|
|
144
136
|
isAppType: isAppType(pluginJson.type),
|
|
145
137
|
isNPM: isNPM(packageManagerName),
|
|
146
138
|
version: currentVersion,
|
|
147
|
-
bundleGrafanaUI,
|
|
148
139
|
scenesVersion: '^6.10.4',
|
|
149
140
|
pluginExecutable: pluginJson.executable,
|
|
150
141
|
useExperimentalRspack: Boolean(features.useExperimentalRspack),
|