Create-plugin migration, build script template parsing error

I’m migrating my app plugin from @grafana/toolkit to @grafana/create-plugin. I ran the migration script, which converted build script to use webpack instead of “grafana-toolkit plugin:build”.

Everything works normally except that it tries to parse the @grafana/create-plugin/templates directory, but it seems like it should be excluded in the webpack config.

Here’s an example of the output:

ERROR in …/node_modules/@grafana/create-plugin/templates/app/src/module.ts 5:40
Module parse failed: Unexpected token (5:40)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See Concepts | webpack
| import { AppConfig } from ‘./components/AppConfig’;
|

export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
| title: ‘Configuration’,
| icon: ‘cog’,

ERROR in …/node_modules/@grafana/create-plugin/templates/datasource/src/module.ts 7:55
Module parse failed: Identifier ‘MyQuery’ has already been declared (7:55)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See Concepts | webpack
| import { MyQuery, MyDataSourceOptions } from ‘./types’;
|

export const plugin = new DataSourcePlugin<DataSource, MyQuery, MyDataSourceOptions>(DataSource)
| .setConfigEditor(ConfigEditor)
| .setQueryEditor(QueryEditor);

ERROR in …/node_modules/@grafana/create-plugin/templates/panel/src/components/SimplePanel.tsx 7:0
Module parse failed: The keyword ‘interface’ is reserved (7:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See Concepts | webpack
| import { useStyles2, useTheme2 } from ‘@grafana/ui’;
|

interface Props extends PanelProps {}
|
| const getStyles = () => {
@ …/node_modules/@grafana/create-plugin/templates/panel/src/module.ts 3:0-55 5:52-81

ERROR in …/node_modules/@grafana/create-plugin/templates/panel/src/types.ts 1:5
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See Concepts | webpack

type SeriesSize = ‘sm’ | ‘md’ | ‘lg’;
|
| export interface SimpleOptions {
@ …/node_modules/@grafana/create-plugin/templates/panel/src/module.ts 2:0-40 5:38-51

ERROR in …/node_modules/@grafana/create-plugin/templates/scenes-app/src/module.ts 5:40
Module parse failed: Unexpected token (5:40)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See Concepts | webpack
| import { AppConfig } from ‘./components/AppConfig’;
|

export const plugin = new AppPlugin<{}>().setRootPage(App).addConfigPage({
| title: ‘Configuration’,
| icon: ‘cog’,

I’ve tried excluding explicitly by extending the webpack config and adding a rule, and also excluding in tsconfig. I’m not sure if I’m missing some crucial step or if my webpack foo is not on point (likely). I was able to temporarily bypass this issue by simply deleting the “@grafana/create-plugin/templates” dir in the node_modules.

Also, looking at the loaders documentation, it seems like it should be covered by the first rule in the webpack config anyway.

Anyone else experiencing something similar? The templates don’t seem relevant to building my plugin dist for production.

Hi @ohmakai a couple things to keep in mind

  • Your webpack config should not be trying to parse all the packages inside node_modules. only the ones you require in your source code files, so check you are not using a custom webpack config that makes it go and parse all your node_modules
  • remove @grafana/create-plugin as a dependency (or dev dependency) for your project. Create-plugin is better used as an standalone CLI tool and there’s no need to have it as a dependency since you only use it when you either create a new plugin or update your configuration.

Do you have a public repository we can use to test your case?

:person_facepalming: yep, that was it (I’d installed it in my dependencies for some reason). Makes sense, all example usages are execution of the binary package. Thank you @academo for pointing that out.