22 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
33 *
44 * In order to extend the configuration follow the steps in
5- * https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations #extend-the-webpack-config
5+ * https://grafana.com/developers/plugin-tools/get-started/set-up-development-environment #extend-the-webpack-config
66 */
77
88import CopyWebpackPlugin from 'copy-webpack-plugin' ;
99import ESLintPlugin from 'eslint-webpack-plugin' ;
1010import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin' ;
11- import LiveReloadPlugin from 'webpack-livereload-plugin' ;
1211import path from 'path' ;
1312import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin' ;
14- import { Configuration } from 'webpack' ;
15- import { GrafanaPluginMetaExtractor } from '@grafana/plugin-meta-extractor' ;
13+ import TerserPlugin from 'terser-webpack-plugin' ;
14+ import { SubresourceIntegrityPlugin } from "webpack-subresource-integrity" ;
15+ import { type Configuration , BannerPlugin } from 'webpack' ;
16+ import LiveReloadPlugin from 'webpack-livereload-plugin' ;
17+ import VirtualModulesPlugin from 'webpack-virtual-modules' ;
1618
17- import { getPackageJson , getPluginJson , hasReadme , getEntries , isWSL } from './utils' ;
18- import { SOURCE_DIR , DIST_DIR } from './constants' ;
19+ import { BuildModeWebpackPlugin } from './BuildModeWebpackPlugin' ;
20+ import { DIST_DIR , SOURCE_DIR } from './constants' ;
21+ import { getCPConfigVersion , getEntries , getPackageJson , getPluginJson , hasReadme , isWSL } from './utils' ;
1922
2023const pluginJson = getPluginJson ( ) ;
24+ const cpVersion = getCPConfigVersion ( ) ;
25+
26+ const virtualPublicPath = new VirtualModulesPlugin ( {
27+ 'node_modules/grafana-public-path.js' : `
28+ import amdMetaModule from 'amd-module';
29+
30+ __webpack_public_path__ =
31+ amdMetaModule && amdMetaModule.uri
32+ ? amdMetaModule.uri.slice(0, amdMetaModule.uri.lastIndexOf('/') + 1)
33+ : 'public/plugins/${ pluginJson . id } /';
34+ ` ,
35+ } ) ;
2136
2237const config = async ( env ) : Promise < Configuration > => {
2338 const baseConfig : Configuration = {
@@ -35,6 +50,8 @@ const config = async (env): Promise<Configuration> => {
3550 entry : await getEntries ( ) ,
3651
3752 externals : [
53+ // Required for dynamic publicPath resolution
54+ { 'amd-module' : 'module' } ,
3855 'lodash' ,
3956 'jquery' ,
4057 'moment' ,
@@ -72,18 +89,35 @@ const config = async (env): Promise<Configuration> => {
7289 } ,
7390 ] ,
7491
92+ // Support WebAssembly according to latest spec - makes WebAssembly module async
93+ experiments : {
94+ asyncWebAssembly : true ,
95+ } ,
96+
7597 mode : env . production ? 'production' : 'development' ,
7698
7799 module : {
78100 rules : [
101+ // This must come first in the rules array otherwise it breaks sourcemaps.
102+ {
103+ test : / s r c \/ (?: .* \/ ) ? m o d u l e \. t s x ? $ / ,
104+ use : [
105+ {
106+ loader : 'imports-loader' ,
107+ options : {
108+ imports : `side-effects grafana-public-path` ,
109+ } ,
110+ } ,
111+ ] ,
112+ } ,
79113 {
80114 exclude : / ( n o d e _ m o d u l e s ) / ,
81115 test : / \. [ t j ] s x ? $ / ,
82116 use : {
83117 loader : 'swc-loader' ,
84118 options : {
85119 jsc : {
86- baseUrl : path . resolve ( __dirname , 'src' ) ,
120+ baseUrl : path . resolve ( process . cwd ( ) , SOURCE_DIR ) ,
87121 target : 'es2015' ,
88122 loose : false ,
89123 parser : {
@@ -108,40 +142,59 @@ const config = async (env): Promise<Configuration> => {
108142 test : / \. ( p n g | j p e ? g | g i f | s v g ) $ / ,
109143 type : 'asset/resource' ,
110144 generator : {
111- // Keep publicPath relative for host.com/grafana/ deployments
112- publicPath : `public/plugins/${ pluginJson . id } /img/` ,
113- outputPath : 'img/' ,
114145 filename : Boolean ( env . production ) ? '[hash][ext]' : '[file]' ,
115146 } ,
116147 } ,
117148 {
118149 test : / \. ( w o f f | w o f f 2 | e o t | t t f | o t f ) ( \? v = \d + \. \d + \. \d + ) ? $ / ,
119150 type : 'asset/resource' ,
120151 generator : {
121- // Keep publicPath relative for host.com/grafana/ deployments
122- publicPath : `public/plugins/${ pluginJson . id } /fonts/` ,
123- outputPath : 'fonts/' ,
124- filename : Boolean ( env . production ) ? '[hash][ext]' : '[name][ext]' ,
152+ filename : Boolean ( env . production ) ? '[hash][ext]' : '[file]' ,
125153 } ,
126154 } ,
127155 ] ,
128156 } ,
129157
158+ optimization : {
159+ minimize : Boolean ( env . production ) ,
160+ minimizer : [
161+ new TerserPlugin ( {
162+ terserOptions : {
163+ format : {
164+ comments : ( _ , { type, value } ) => type === 'comment2' && value . trim ( ) . startsWith ( '[create-plugin]' ) ,
165+ } ,
166+ compress : {
167+ drop_console : [ 'log' , 'info' ]
168+ }
169+ } ,
170+ } ) ,
171+ ] ,
172+ } ,
173+
130174 output : {
131175 clean : {
132176 keep : new RegExp ( `(.*?_(amd64|arm(64)?)(.exe)?|go_plugin_build_manifest)` ) ,
133177 } ,
134178 filename : '[name].js' ,
179+ chunkFilename : env . production ? '[name].js?_cache=[contenthash]' : '[name].js' ,
135180 library : {
136181 type : 'amd' ,
137182 } ,
138183 path : path . resolve ( process . cwd ( ) , DIST_DIR ) ,
139184 publicPath : `public/plugins/${ pluginJson . id } /` ,
140185 uniqueName : pluginJson . id ,
186+ crossOriginLoading : 'anonymous' ,
141187 } ,
142188
143189 plugins : [
144- new GrafanaPluginMetaExtractor ( ) ,
190+ new BuildModeWebpackPlugin ( ) ,
191+ virtualPublicPath ,
192+ // Insert create plugin version information into the bundle
193+ new BannerPlugin ( {
194+ banner : "/* [create-plugin] version: " + cpVersion + " */" ,
195+ raw : true ,
196+ entryOnly : true ,
197+ } ) ,
145198 new CopyWebpackPlugin ( {
146199 patterns : [
147200 // If src/README.md exists use it; otherwise the root README
@@ -150,14 +203,14 @@ const config = async (env): Promise<Configuration> => {
150203 { from : 'plugin.json' , to : '.' } ,
151204 { from : '../LICENSE' , to : '.' } ,
152205 { from : '../CHANGELOG.md' , to : '.' , force : true } ,
153- { from : '**/*.json' , to : '.' } , // TODO<Add an error for checking the basic structure of the repo>
154- { from : '**/*.svg' , to : '.' , noErrorOnMissing : true } , // Optional
155- { from : '**/*.png' , to : '.' , noErrorOnMissing : true } , // Optional
156- { from : '**/*.html' , to : '.' , noErrorOnMissing : true } , // Optional
157- { from : 'img/**/*' , to : '.' , noErrorOnMissing : true } , // Optional
158- { from : 'libs/**/*' , to : '.' , noErrorOnMissing : true } , // Optional
159- { from : 'static/**/*' , to : '.' , noErrorOnMissing : true } , // Optional
160- { from : '**/query_help.md' , to : '.' , noErrorOnMissing : true } , // Optional
206+ { from : '**/*.json' , to : '.' } ,
207+ { from : '**/*.svg' , to : '.' , noErrorOnMissing : true } ,
208+ { from : '**/*.png' , to : '.' , noErrorOnMissing : true } ,
209+ { from : '**/*.html' , to : '.' , noErrorOnMissing : true } ,
210+ { from : 'img/**/*' , to : '.' , noErrorOnMissing : true } ,
211+ { from : 'libs/**/*' , to : '.' , noErrorOnMissing : true } ,
212+ { from : 'static/**/*' , to : '.' , noErrorOnMissing : true } ,
213+ { from : '**/query_help.md' , to : '.' , noErrorOnMissing : true } ,
161214 ] ,
162215 } ) ,
163216 // Replace certain template-variables in the README and plugin.json
@@ -181,22 +234,23 @@ const config = async (env): Promise<Configuration> => {
181234 ] ,
182235 } ,
183236 ] ) ,
184- ...( env . development
185- ? [
186- new LiveReloadPlugin ( ) ,
187- new ForkTsCheckerWebpackPlugin ( {
188- async : Boolean ( env . development ) ,
189- issue : {
190- include : [ { file : '**/*.{ts,tsx}' } ] ,
191- } ,
192- typescript : { configFile : path . join ( process . cwd ( ) , 'tsconfig.json' ) } ,
193- } ) ,
194- new ESLintPlugin ( {
195- extensions : [ '.ts' , '.tsx' ] ,
196- lintDirtyModulesOnly : Boolean ( env . development ) , // don't lint on start, only lint changed files
197- } ) ,
198- ]
199- : [ ] ) ,
237+ new SubresourceIntegrityPlugin ( {
238+ hashFuncNames : [ "sha256" ] ,
239+ } ) ,
240+ ...( env . development ? [
241+ new LiveReloadPlugin ( ) ,
242+ new ForkTsCheckerWebpackPlugin ( {
243+ async : Boolean ( env . development ) ,
244+ issue : {
245+ include : [ { file : '**/*.{ts,tsx}' } ] ,
246+ } ,
247+ typescript : { configFile : path . join ( process . cwd ( ) , 'tsconfig.json' ) } ,
248+ } ) ,
249+ new ESLintPlugin ( {
250+ extensions : [ '.ts' , '.tsx' ] ,
251+ lintDirtyModulesOnly : Boolean ( env . development ) , // don't lint on start, only lint changed files
252+ } ) ,
253+ ] : [ ] ) ,
200254 ] ,
201255
202256 resolve : {
0 commit comments