mirror of
https://github.com/grafana/grafana.git
synced 2024-11-21 16:38:03 -06:00
Plugins: Always load decoupled frontend assets from builds (#81873)
* Wip * Wip * Adapt to load external module * build: remove cloudmonitoring from built_in_plugins, clean up webpack output * chore(plugins): remove decoupled plugins from package.json deps * chore(codeowners): update file for nx.json * revert(webpack): put back path in config * build(frontend): use nx to run prod builds of decoupled plugins with yarn build * style(prometheus): run prettier-write to fix tsconfig.json * style(backend): remove unused subFile.isDistDir * revert(locales): remove formatting changes adding new line at end of files * chore(webpack): clean up dev output * build(nx): make grafana an nx project, bump lerna and nx * build(plugin-configs): move cache directory to node_modules * style(datasource-plugins): add eslint ignore for .gen.ts files * chore(codeowners): add frontend-ops as owner of project.json * build(webpack): add getDecoupledPlugins to automatically ignore when watching * ci(drone): skip nx cache when building frontend packages * style(ci): fix missing trailing comma * Revert "style(ci): fix missing trailing comma" This reverts commit7520d41576
. * Revert "ci(drone): skip nx cache when building frontend packages" This reverts commit46938883ac
. * feat(zipkin): remove from grafana core bundle * chore(npm): bump nx package to latest 18.0.8 * docs(dev-guide): add a note about what yarn start now builds --------- Co-authored-by: Andres Martinez <andres.martinez@grafana.com>
This commit is contained in:
parent
75ea33e0cd
commit
6599fa805d
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -350,6 +350,8 @@
|
||||
# root files, mostly frontend
|
||||
/.browserslistrc @grafana/frontend-ops
|
||||
/package.json @grafana/frontend-ops
|
||||
/nx.json @grafana/frontend-ops
|
||||
/project.json @grafana/frontend-ops
|
||||
/tsconfig.json @grafana/frontend-ops
|
||||
/.editorconfig @grafana/frontend-ops
|
||||
/.eslintignore @grafana/frontend-ops
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -204,6 +204,7 @@ public/api-spec.json
|
||||
deployment_tools_config.json
|
||||
|
||||
.betterer.cache
|
||||
.nx
|
||||
|
||||
# Temporary file for backporting PRs
|
||||
.pr-body.txt
|
||||
|
@ -76,6 +76,7 @@ After the command has finished, we can start building our source code:
|
||||
yarn start
|
||||
```
|
||||
|
||||
This command will generate sass theme files, build all external plugins, then build the frontend assets.
|
||||
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets every time you change the code.
|
||||
|
||||
> Troubleshooting: if your first build works, but after pulling updates you see unexpected errors in the "Type-checking in progress..." stage, these can be caused by the [tsbuildinfo cache supporting incremental builds](https://www.typescriptlang.org/tsconfig#incremental). You can `rm tsconfig.tsbuildinfo` and re-try.
|
||||
|
18
nx.json
Normal file
18
nx.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "nx/tasks-runners/default",
|
||||
"options": {
|
||||
"cacheableOperations": ["build"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
"build": {
|
||||
"outputs": ["{projectRoot}/dist"]
|
||||
}
|
||||
},
|
||||
"affected": {
|
||||
"defaultBase": "main"
|
||||
}
|
||||
}
|
37
package.json
37
package.json
@ -6,10 +6,9 @@
|
||||
"version": "11.0.0-pre",
|
||||
"repository": "github:grafana/grafana",
|
||||
"scripts": {
|
||||
"prebuild": "yarn plugin:build",
|
||||
"build": "yarn prebuild & NODE_ENV=production webpack --progress --config scripts/webpack/webpack.prod.js",
|
||||
"build:nominify": "yarn run build --env noMinify=1",
|
||||
"dev": "yarn prebuild & NODE_ENV=dev webpack --progress --color --config scripts/webpack/webpack.dev.js",
|
||||
"build": "NODE_ENV=production nx exec --verbose -- webpack --config scripts/webpack/webpack.prod.js",
|
||||
"build:nominify": "yarn run build -- --env noMinify=1",
|
||||
"dev": "NODE_ENV=dev nx exec -- webpack --config scripts/webpack/webpack.dev.js",
|
||||
"e2e": "./e2e/start-and-run-suite",
|
||||
"e2e:debug": "./e2e/start-and-run-suite debug",
|
||||
"e2e:dev": "./e2e/start-and-run-suite dev",
|
||||
@ -29,21 +28,21 @@
|
||||
"lint:sass": "yarn stylelint '{public/sass,packages}/**/*.scss' --cache",
|
||||
"test:ci": "mkdir -p reports/junit && JEST_JUNIT_OUTPUT_DIR=reports/junit jest --ci --reporters=default --reporters=jest-junit -w ${TEST_MAX_WORKERS:-100%}",
|
||||
"lint:fix": "yarn lint:ts --fix",
|
||||
"packages:build": "lerna run build --ignore '@grafana-plugins/*'",
|
||||
"packages:build": "nx run-many -t build --projects='@grafana/*'",
|
||||
"packages:clean": "rimraf ./npm-artifacts && lerna run clean --parallel",
|
||||
"packages:prepare": "lerna version --no-push --no-git-tag-version --force-publish --exact",
|
||||
"packages:pack": "mkdir -p ./npm-artifacts && lerna exec --no-private -- yarn pack --out \"../../npm-artifacts/%s-%v.tgz\"",
|
||||
"packages:typecheck": "lerna run typecheck",
|
||||
"packages:typecheck": "nx run-many -t typecheck --projects='@grafana/*'",
|
||||
"prettier:check": "prettier --check --list-different=false --log-level=warn \"**/*.{ts,tsx,scss,md,mdx,json}\"",
|
||||
"prettier:checkDocs": "prettier --check --list-different=false --log-level=warn \"docs/**/*.md\" \"*.md\" \"packages/**/*.{ts,tsx,scss,md,mdx,json}\"",
|
||||
"prettier:write": "prettier --list-different \"**/*.{js,ts,tsx,scss,md,mdx,json}\" --write",
|
||||
"start": "yarn themes:generate && yarn dev --watch",
|
||||
"start:noTsCheck": "yarn start --env noTsCheck=1",
|
||||
"start:noLint": "yarn start --env noTsCheck=1 --env noLint=1",
|
||||
"start": "NODE_ENV=dev nx exec -- webpack --config scripts/webpack/webpack.dev.js --watch",
|
||||
"start:noTsCheck": "yarn start -- --env noTsCheck=1",
|
||||
"start:noLint": "yarn start -- --env noTsCheck=1 --env noLint=1",
|
||||
"stats": "webpack --mode production --config scripts/webpack/webpack.prod.js --profile --json > compilation-stats.json",
|
||||
"storybook": "yarn workspace @grafana/ui storybook --ci",
|
||||
"storybook:build": "yarn workspace @grafana/ui storybook:build",
|
||||
"themes:generate": "esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
|
||||
"themes-generate": "esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
|
||||
"themes:usage": "eslint . --ext .tsx,.ts --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --rule '{ @grafana/theme-token-usage: \"error\" }'",
|
||||
"typecheck": "tsc --noEmit && yarn run packages:typecheck",
|
||||
"plugins:build-bundled": "find plugins-bundled -name package.json -not -path '*/node_modules/*' -execdir yarn build \\;",
|
||||
@ -59,9 +58,9 @@
|
||||
"betterer:stats": "ts-node --transpile-only --project ./scripts/cli/tsconfig.json ./scripts/cli/reportBettererStats.ts",
|
||||
"betterer:issues": "ts-node --transpile-only --project ./scripts/cli/tsconfig.json ./scripts/cli/generateBettererIssues.ts",
|
||||
"generate-icons-bundle-cache-file": "node ./scripts/generate-icon-bundle.js",
|
||||
"plugin:build": "lerna run build --ignore=\"@grafana/*\" --ignore=\"@grafana-plugins/input-datasource\"",
|
||||
"plugin:build:commit": "lerna run build:commit --ignore=\"@grafana/*\" --ignore=\"@grafana-plugins/input-datasource\"",
|
||||
"plugin:build:dev": "lerna run dev --ignore=\"@grafana/*\" --ignore=\"@grafana-plugins/input-datasource\""
|
||||
"plugin:build": "nx run-many -t build --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\"",
|
||||
"plugin:build:commit": "nx run-many -t build:commit --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\"",
|
||||
"plugin:build:dev": "nx run-many -t dev --projects='@grafana-plugins/*' --exclude \"@grafana-plugins/input-datasource\""
|
||||
},
|
||||
"grafana": {
|
||||
"whatsNewUrl": "https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-v11-0/",
|
||||
@ -78,6 +77,7 @@
|
||||
"@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules",
|
||||
"@grafana/plugin-e2e": "^0.19.0",
|
||||
"@grafana/tsconfig": "^1.3.0-rc1",
|
||||
"@manypkg/get-packages": "^2.2.0",
|
||||
"@playwright/test": "^1.41.2",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11",
|
||||
"@react-types/button": "3.9.2",
|
||||
@ -195,6 +195,7 @@
|
||||
"mutationobserver-shim": "0.3.7",
|
||||
"ngtemplate-loader": "2.1.0",
|
||||
"node-notifier": "10.0.1",
|
||||
"nx": "18.0.8",
|
||||
"postcss": "8.4.35",
|
||||
"postcss-loader": "8.1.1",
|
||||
"postcss-reporter": "7.1.0",
|
||||
@ -219,11 +220,13 @@
|
||||
"ts-node": "10.9.2",
|
||||
"typescript": "5.3.3",
|
||||
"webpack": "5.90.3",
|
||||
"webpack-assets-manifest": "^5.1.0",
|
||||
"webpack-bundle-analyzer": "4.10.1",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "5.0.3",
|
||||
"webpack-manifest-plugin": "5.0.0",
|
||||
"webpack-merge": "5.10.0",
|
||||
"webpackbar": "^6.0.0",
|
||||
"yaml": "^2.0.0",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
@ -234,13 +237,6 @@
|
||||
"@fingerprintjs/fingerprintjs": "^3.4.2",
|
||||
"@floating-ui/react": "0.26.9",
|
||||
"@glideapps/glide-data-grid": "^6.0.0",
|
||||
"@grafana-plugins/grafana-azure-monitor-datasource": "workspace:*",
|
||||
"@grafana-plugins/grafana-pyroscope-datasource": "workspace:*",
|
||||
"@grafana-plugins/grafana-testdata-datasource": "workspace:*",
|
||||
"@grafana-plugins/parca": "workspace:*",
|
||||
"@grafana-plugins/stackdriver": "workspace:*",
|
||||
"@grafana-plugins/tempo": "workspace:*",
|
||||
"@grafana-plugins/zipkin": "workspace:*",
|
||||
"@grafana/aws-sdk": "0.3.2",
|
||||
"@grafana/data": "workspace:*",
|
||||
"@grafana/e2e-selectors": "workspace:*",
|
||||
@ -410,7 +406,6 @@
|
||||
"uplot": "1.6.30",
|
||||
"uuid": "9.0.1",
|
||||
"visjs-network": "4.25.0",
|
||||
"webpack-assets-manifest": "^5.1.0",
|
||||
"whatwg-fetch": "3.6.20",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz"
|
||||
},
|
||||
|
@ -213,6 +213,8 @@ const config = async (env: Record<string, unknown>): Promise<Configuration> => {
|
||||
unsafeCache: true,
|
||||
},
|
||||
|
||||
stats: 'minimal',
|
||||
|
||||
watchOptions: {
|
||||
ignored: ['**/node_modules', '**/dist', '**/.yarn'],
|
||||
},
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
)
|
||||
|
||||
// Service provides methods for constructing asset paths for plugins.
|
||||
@ -58,9 +57,7 @@ func (s *Service) Base(n PluginInfo) (string, error) {
|
||||
// Module returns the module.js path for the specified plugin.
|
||||
func (s *Service) Module(n PluginInfo) (string, error) {
|
||||
if n.class == plugins.ClassCore {
|
||||
if s.cfg.Features != nil &&
|
||||
s.cfg.Features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) &&
|
||||
filepath.Base(n.dir) == "dist" {
|
||||
if filepath.Base(n.dir) == "dist" {
|
||||
// The core plugin has been built externally, use the module from the dist folder
|
||||
} else {
|
||||
baseDir := getBaseDir(n.dir)
|
||||
|
@ -59,12 +59,7 @@ func (l *Local) Find(ctx context.Context, src plugins.PluginSource) ([]*plugins.
|
||||
continue
|
||||
}
|
||||
|
||||
followDistFolder := true
|
||||
if src.PluginClass(ctx) == plugins.ClassCore &&
|
||||
!l.features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) {
|
||||
followDistFolder = false
|
||||
}
|
||||
paths, err := l.getAbsPluginJSONPaths(path, followDistFolder)
|
||||
paths, err := l.getAbsPluginJSONPaths(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -167,7 +162,7 @@ func (l *Local) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error)
|
||||
return plugin, nil
|
||||
}
|
||||
|
||||
func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]string, error) {
|
||||
func (l *Local) getAbsPluginJSONPaths(path string) ([]string, error) {
|
||||
var pluginJSONPaths []string
|
||||
|
||||
var err error
|
||||
@ -176,7 +171,7 @@ func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]str
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
if err = walk(path, true, true, followDistFolder,
|
||||
if err = walk(path, true, true,
|
||||
func(currentPath string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
|
@ -313,7 +313,7 @@ func TestFinder_Find(t *testing.T) {
|
||||
func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
t.Run("When scanning a folder that doesn't exists shouldn't return an error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, os.ErrNotExist)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@ -321,14 +321,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("When scanning a folder that lacks permission shouldn't return an error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, os.ErrPermission)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@ -336,14 +336,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("When scanning a folder that returns a non-handled error should return that error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, errors.New("random error"))
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@ -351,44 +351,10 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.Error(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("The followDistFolder state controls whether certain folders are followed", func(t *testing.T) {
|
||||
dir, err := filepath.Abs("../../testdata/pluginRootWithDist")
|
||||
require.NoError(t, err)
|
||||
|
||||
tcs := []struct {
|
||||
name string
|
||||
followDist bool
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "When followDistFolder is enabled, only the nested dist folder will be followed",
|
||||
followDist: true,
|
||||
expected: []string{
|
||||
filepath.Join(dir, "dist/plugin.json"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "When followDistFolder is disabled, no dist folders will be followed",
|
||||
followDist: false,
|
||||
expected: []string{
|
||||
filepath.Join(dir, "datasource/plugin.json"),
|
||||
filepath.Join(dir, "panel/src/plugin.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
pluginBundles, err := NewLocalFinder(false, featuremgmt.WithFeatures()).getAbsPluginJSONPaths(dir, tc.followDist)
|
||||
require.NoError(t, err)
|
||||
|
||||
sort.Strings(pluginBundles)
|
||||
require.Equal(t, tc.expected, pluginBundles)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var fsComparer = cmp.Comparer(func(fs1 plugins.FS, fs2 plugins.FS) bool {
|
||||
|
@ -30,7 +30,7 @@ func newWalker(rootDir string) *walker {
|
||||
// can detect infinite loops while following symlinks.
|
||||
// It solves the issue where your WalkFunc needs a path relative to the symbolic link
|
||||
// (resolving links within walkfunc loses the path to the symbolic link for each traversal).
|
||||
func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, followDistFolder bool, walkFn WalkFunc) error {
|
||||
func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, walkFn WalkFunc) error {
|
||||
info, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -44,7 +44,7 @@ func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, foll
|
||||
}
|
||||
}
|
||||
|
||||
return newWalker(path).walk(path, info, resolvedPath, symlinkPathsFollowed, followDistFolder, walkFn)
|
||||
return newWalker(path).walk(path, info, resolvedPath, symlinkPathsFollowed, walkFn)
|
||||
}
|
||||
|
||||
// walk walks the path. It is a helper/sibling function to Walk.
|
||||
@ -53,7 +53,7 @@ func Walk(path string, followSymlinks bool, detectSymlinkInfiniteLoop bool, foll
|
||||
//
|
||||
// If resolvedPath is "", then we are not following symbolic links.
|
||||
// If symlinkPathsFollowed is not nil, then we need to detect infinite loop.
|
||||
func (w *walker) walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollowed map[string]bool, followDistFolder bool, walkFn WalkFunc) error {
|
||||
func (w *walker) walk(path string, info os.FileInfo, resolvedPath string, symlinkPathsFollowed map[string]bool, walkFn WalkFunc) error {
|
||||
if info == nil {
|
||||
return errors.New("walk: Nil FileInfo passed")
|
||||
}
|
||||
@ -91,7 +91,7 @@ func (w *walker) walk(path string, info os.FileInfo, resolvedPath string, symlin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return w.walk(path, info2, path2, symlinkPathsFollowed, followDistFolder, walkFn)
|
||||
return w.walk(path, info2, path2, symlinkPathsFollowed, walkFn)
|
||||
} else if info.IsDir() {
|
||||
list, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
@ -112,23 +112,19 @@ func (w *walker) walk(path string, info os.FileInfo, resolvedPath string, symlin
|
||||
subFiles = append(subFiles, subFile{path: path2, resolvedPath: resolvedPath2, fileInfo: fileInfo})
|
||||
}
|
||||
|
||||
if followDistFolder && w.containsDistFolder(subFiles) {
|
||||
if w.containsDistFolder(subFiles) {
|
||||
err := w.walk(
|
||||
filepath.Join(path, "dist"),
|
||||
info,
|
||||
filepath.Join(resolvedPath, "dist"),
|
||||
symlinkPathsFollowed,
|
||||
followDistFolder,
|
||||
walkFn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for _, p := range subFiles {
|
||||
if p.isDistDir() && !followDistFolder {
|
||||
continue
|
||||
}
|
||||
err = w.walk(p.path, p.fileInfo, p.resolvedPath, symlinkPathsFollowed, followDistFolder, walkFn)
|
||||
err = w.walk(p.path, p.fileInfo, p.resolvedPath, symlinkPathsFollowed, walkFn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -154,10 +150,6 @@ type subFile struct {
|
||||
fileInfo os.FileInfo
|
||||
}
|
||||
|
||||
func (s subFile) isDistDir() bool {
|
||||
return s.fileInfo.IsDir() && s.fileInfo.Name() == "dist"
|
||||
}
|
||||
|
||||
// CleanRelativePath returns the shortest path name equivalent to path
|
||||
// by purely lexical processing. It makes sure the provided path is rooted
|
||||
// and then uses filepath.Clean and filepath.Rel to make sure the path
|
||||
|
35
project.json
Normal file
35
project.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "grafana",
|
||||
"$schema": "node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"start": {
|
||||
"dependsOn": [
|
||||
"themes-generate",
|
||||
{
|
||||
"projects": ["@grafana-plugins/**"],
|
||||
"target": "build"
|
||||
}
|
||||
]
|
||||
},
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"themes-generate",
|
||||
{
|
||||
"projects": ["@grafana-plugins/**"],
|
||||
"target": "build"
|
||||
}
|
||||
],
|
||||
"outputs": ["{workspaceRoot}/public/build"],
|
||||
"cache": true
|
||||
},
|
||||
"themes-generate": {
|
||||
"outputs": [
|
||||
"{workspaceRoot}/public/sass/_variables.generated.scss",
|
||||
"{workspaceRoot}/public/sass/_variables.dark.generated.scss",
|
||||
"{workspaceRoot}/public/sass/_variables.light.generated.scss"
|
||||
],
|
||||
"cache": true
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ const influxdbPlugin = async () =>
|
||||
const lokiPlugin = async () => await import(/* webpackChunkName: "lokiPlugin" */ 'app/plugins/datasource/loki/module');
|
||||
const jaegerPlugin = async () =>
|
||||
await import(/* webpackChunkName: "jaegerPlugin" */ 'app/plugins/datasource/jaeger/module');
|
||||
const zipkinPlugin = async () => await import(/* webpackChunkName: "zipkinPlugin" */ '@grafana-plugins/zipkin/module');
|
||||
const mixedPlugin = async () =>
|
||||
await import(/* webpackChunkName: "mixedPlugin" */ 'app/plugins/datasource/mixed/module');
|
||||
const mysqlPlugin = async () =>
|
||||
@ -26,18 +25,8 @@ const prometheusPlugin = async () =>
|
||||
await import(/* webpackChunkName: "prometheusPlugin" */ 'app/plugins/datasource/prometheus/module');
|
||||
const mssqlPlugin = async () =>
|
||||
await import(/* webpackChunkName: "mssqlPlugin" */ 'app/plugins/datasource/mssql/module');
|
||||
const testDataDSPlugin = async () =>
|
||||
await import(/* webpackChunkName: "testDataDSPlugin" */ '@grafana-plugins/grafana-testdata-datasource/module');
|
||||
const cloudMonitoringPlugin = async () =>
|
||||
await import(/* webpackChunkName: "cloudMonitoringPlugin" */ '@grafana-plugins/stackdriver/module');
|
||||
const azureMonitorPlugin = async () =>
|
||||
await import(/* webpackChunkName: "azureMonitorPlugin" */ '@grafana-plugins/grafana-azure-monitor-datasource/module');
|
||||
const tempoPlugin = async () => await import(/* webpackChunkName: "tempoPlugin" */ '@grafana-plugins/tempo/module');
|
||||
const alertmanagerPlugin = async () =>
|
||||
await import(/* webpackChunkName: "alertmanagerPlugin" */ 'app/plugins/datasource/alertmanager/module');
|
||||
const pyroscopePlugin = async () =>
|
||||
await import(/* webpackChunkName: "pyroscopePlugin" */ '@grafana-plugins/grafana-pyroscope-datasource/module');
|
||||
const parcaPlugin = async () => await import(/* webpackChunkName: "parcaPlugin" */ '@grafana-plugins/parca/module');
|
||||
|
||||
import * as alertGroupsPanel from 'app/plugins/panel/alertGroups/module';
|
||||
import * as alertListPanel from 'app/plugins/panel/alertlist/module';
|
||||
@ -90,19 +79,12 @@ const builtInPlugins: Record<string, System.Module | (() => Promise<System.Modul
|
||||
'core:plugin/influxdb': influxdbPlugin,
|
||||
'core:plugin/loki': lokiPlugin,
|
||||
'core:plugin/jaeger': jaegerPlugin,
|
||||
'core:plugin/zipkin': zipkinPlugin,
|
||||
'core:plugin/mixed': mixedPlugin,
|
||||
'core:plugin/mysql': mysqlPlugin,
|
||||
'core:plugin/grafana-postgresql-datasource': postgresPlugin,
|
||||
'core:plugin/mssql': mssqlPlugin,
|
||||
'core:plugin/prometheus': prometheusPlugin,
|
||||
'core:plugin/grafana-testdata-datasource': testDataDSPlugin,
|
||||
'core:plugin/cloud-monitoring': cloudMonitoringPlugin,
|
||||
'core:plugin/azuremonitor': azureMonitorPlugin,
|
||||
'core:plugin/tempo': tempoPlugin,
|
||||
'core:plugin/alertmanager': alertmanagerPlugin,
|
||||
'core:plugin/grafana-pyroscope-datasource': pyroscopePlugin,
|
||||
'core:plugin/parca': parcaPlugin,
|
||||
// panels
|
||||
'core:plugin/text': textPanel,
|
||||
'core:plugin/timeseries': timeseriesPanel,
|
||||
|
@ -0,0 +1,2 @@
|
||||
# TS generate from cue by cuetsy
|
||||
**/*.gen.ts
|
@ -0,0 +1,2 @@
|
||||
# TS generate from cue by cuetsy
|
||||
**/*.gen.ts
|
@ -58,10 +58,6 @@ module.exports = {
|
||||
message: /^Critical dependency: the request of a dependency is an expression$/,
|
||||
},
|
||||
],
|
||||
stats: {
|
||||
children: false,
|
||||
source: false,
|
||||
},
|
||||
plugins: [
|
||||
new webpack.NormalModuleReplacementPlugin(/^@grafana\/schema\/dist\/esm\/(.*)$/, (resource) => {
|
||||
resource.request = resource.request.replace('@grafana/schema/dist/esm', '@grafana/schema/src');
|
||||
|
@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const { getPackagesSync } = require('@manypkg/get-packages');
|
||||
const browserslist = require('browserslist');
|
||||
const { resolveToEsbuildTarget } = require('esbuild-plugin-browserslist');
|
||||
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||
@ -9,6 +9,7 @@ const path = require('path');
|
||||
const { DefinePlugin } = require('webpack');
|
||||
const WebpackAssetsManifest = require('webpack-assets-manifest');
|
||||
const { merge } = require('webpack-merge');
|
||||
const WebpackBar = require('webpackbar');
|
||||
|
||||
const common = require('./webpack.common.js');
|
||||
const esbuildTargets = resolveToEsbuildTarget(browserslist(), { printUnknownTargets: false });
|
||||
@ -19,6 +20,12 @@ const esbuildOptions = {
|
||||
format: undefined,
|
||||
};
|
||||
|
||||
// To speed up webpack and prevent unnecessary rebuilds we ignore decoupled packages
|
||||
function getDecoupledPlugins() {
|
||||
const { packages } = getPackagesSync(process.cwd());
|
||||
return packages.filter((pkg) => pkg.dir.includes('plugins/datasource')).map((pkg) => `${pkg.dir}/**`);
|
||||
}
|
||||
|
||||
module.exports = (env = {}) => {
|
||||
return merge(common, {
|
||||
devtool: 'source-map',
|
||||
@ -32,7 +39,7 @@ module.exports = (env = {}) => {
|
||||
|
||||
// If we enabled watch option via CLI
|
||||
watchOptions: {
|
||||
ignored: /node_modules/,
|
||||
ignored: ['/node_modules/', ...getDecoupledPlugins()],
|
||||
},
|
||||
|
||||
resolve: {
|
||||
@ -64,6 +71,8 @@ module.exports = (env = {}) => {
|
||||
],
|
||||
},
|
||||
|
||||
// infrastructureLogging: { level: 'error' },
|
||||
|
||||
// https://webpack.js.org/guides/build-performance/#output-without-path-info
|
||||
output: {
|
||||
pathinfo: false,
|
||||
@ -121,6 +130,12 @@ module.exports = (env = {}) => {
|
||||
integrity: true,
|
||||
publicPath: true,
|
||||
}),
|
||||
new WebpackBar({
|
||||
color: '#eb7b18',
|
||||
name: 'Grafana',
|
||||
}),
|
||||
],
|
||||
|
||||
stats: 'minimal',
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user