mirror of
https://github.com/grafana/grafana.git
synced 2026-06-12 10:01:06 -04:00
* build(webpack): add tsconfig.json for Node strip-types compliance * build(webpack): extract shared esbuild options to esbuild.ts * build(webpack): add package.json to declare ESM module type * build(webpack): convert sass.rule to TypeScript * build(webpack): convert CorsWorkerPlugin to TypeScript * build(webpack): convert FeatureFlaggedSriPlugin to TypeScript * build(webpack): convert webpack.common to TypeScript, add theme entries * build(webpack): convert webpack.dev to TypeScript, remove esbuild duplication * build(webpack): convert webpack.prod to TypeScript, remove esbuild duplication * build(webpack): fix TypeScript types in webpack.prod transform callback * build(webpack): convert webpack.stats to TypeScript * build(webpack): update scripts to use TypeScript webpack configs * build(webpack): simplify env-util to use import.meta.dirname directly * build(webpack): tidy up plugins * build(webpack): move rules for ts and sass into single module * build(webpack): consolidate shared config into common, move splitChunks to prod - Move MiniCssExtractPlugin, esbuildRule and sassRule into common so both dev and prod configs share them without duplication - Move splitChunks/runtimeChunk optimisation to webpack.prod only (not needed in dev) - Use require() for SubresourceIntegrityPlugin to work around broken ESM build (waysact/webpack-subresource-integrity#236) - Refactor conditional plugin logic in dev from ternary to if-blocks * build(webpack): remove dead import and clarify webpack destructure pattern - Remove unused MiniCssExtractPlugin import from webpack.prod (moved to common) - Add comment explaining why DefinePlugin/EnvironmentPlugin are destructured from the default webpack import rather than using named ESM imports * style(webpack): reorder consts * chore(env-util): fix up env-util and webpack configs so tests continue to run * refactor(env-util): accept grafanaRoot param instead of relying on __dirname Removes the global.__dirname mutation hack in webpack.common.ts by making the grafana root path an explicit argument to getEnvConfig. Each caller resolves its own root and passes it in, removing the implicit path-depth contract and the CJS/ESM compatibility workaround. * build(webpack): remove unused angular chunk group
147 lines
4.3 KiB
TypeScript
147 lines
4.3 KiB
TypeScript
import { getPackagesSync } from '@manypkg/get-packages';
|
|
import ESLintPlugin from 'eslint-webpack-plugin';
|
|
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import webpack, { type Configuration } from 'webpack';
|
|
import WebpackAssetsManifest from 'webpack-assets-manifest';
|
|
import LiveReloadPlugin from 'webpack-livereload-plugin';
|
|
import { merge } from 'webpack-merge';
|
|
import WebpackBar from 'webpackbar';
|
|
|
|
import common, { type Env } from './webpack.common.ts';
|
|
|
|
// webpack does not correctly export named ESM bindings — destructure from the default import
|
|
const { DefinePlugin, EnvironmentPlugin } = webpack;
|
|
|
|
// To speed up webpack and prevent unnecessary rebuilds we ignore decoupled packages
|
|
function getDecoupledPlugins(): string[] {
|
|
const { packages } = getPackagesSync(process.cwd());
|
|
return packages.filter((pkg) => pkg.dir.includes('plugins/datasource')).map((pkg) => `${pkg.dir}/**`);
|
|
}
|
|
|
|
// When linking scenes for development, resolve the path to the src directory for sourcemaps
|
|
function scenesModule(): string {
|
|
const scenesPath = path.resolve('./node_modules/@grafana/scenes');
|
|
try {
|
|
const status = fs.lstatSync(scenesPath);
|
|
if (status.isSymbolicLink()) {
|
|
console.log(`scenes is linked to local scenes repo`);
|
|
return path.resolve(scenesPath + '/src');
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error checking scenes path: ${error instanceof Error ? error.message : String(error)}`);
|
|
}
|
|
return scenesPath;
|
|
}
|
|
const decoupledPlugins = getDecoupledPlugins();
|
|
|
|
export default (env: Env = {}) => {
|
|
const devConfig: Configuration = {
|
|
devtool: 'source-map',
|
|
mode: 'development',
|
|
|
|
// If we enabled watch option via CLI
|
|
watchOptions: {
|
|
ignored: ['/node_modules/', ...decoupledPlugins],
|
|
},
|
|
|
|
resolve: {
|
|
alias: {
|
|
// Packages linked for development need react to be resolved from the same location
|
|
react: path.resolve('./node_modules/react'),
|
|
|
|
// This is required to correctly resolve react-router-dom when linking with
|
|
// local version of @grafana/scenes
|
|
'react-router-dom': path.resolve('./node_modules/react-router-dom'),
|
|
'@grafana/scenes': scenesModule(),
|
|
},
|
|
},
|
|
|
|
// https://webpack.js.org/guides/build-performance/#output-without-path-info
|
|
output: {
|
|
pathinfo: false,
|
|
},
|
|
|
|
// https://webpack.js.org/guides/build-performance/#avoid-extra-optimization-steps
|
|
optimization: {
|
|
moduleIds: 'named',
|
|
runtimeChunk: true,
|
|
removeAvailableModules: false,
|
|
removeEmptyChunks: false,
|
|
splitChunks: false,
|
|
},
|
|
|
|
// enable persistent cache for faster cold starts
|
|
cache: {
|
|
type: 'filesystem',
|
|
name: 'grafana-default-development',
|
|
buildDependencies: {
|
|
config: [import.meta.filename],
|
|
},
|
|
},
|
|
|
|
plugins: [
|
|
new DefinePlugin({
|
|
'process.env': {
|
|
NODE_ENV: JSON.stringify('development'),
|
|
},
|
|
}),
|
|
new WebpackAssetsManifest({
|
|
entrypoints: true,
|
|
integrity: true,
|
|
integrityHashes: ['sha384', 'sha512'],
|
|
publicPath: true,
|
|
output: env.react19 ? 'assets-manifest-react19.json' : 'assets-manifest.json',
|
|
}),
|
|
new WebpackBar({
|
|
color: '#eb7b18',
|
|
name: 'Grafana',
|
|
}),
|
|
],
|
|
|
|
stats: 'minimal',
|
|
};
|
|
|
|
if (Number(env.liveReload)) {
|
|
devConfig.plugins?.push(
|
|
new LiveReloadPlugin({
|
|
appendScriptTag: true,
|
|
useSourceHash: true,
|
|
hostname: 'localhost',
|
|
protocol: 'http',
|
|
port: 35750,
|
|
})
|
|
);
|
|
}
|
|
|
|
if (!Number(env.noTsCheck)) {
|
|
devConfig.plugins?.push(
|
|
new ForkTsCheckerWebpackPlugin({
|
|
async: true, // don't block webpack emit
|
|
typescript: {
|
|
mode: 'write-references',
|
|
memoryLimit: 8192,
|
|
diagnosticOptions: {
|
|
semantic: true,
|
|
syntactic: true,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
if (!Number(env.noLint)) {
|
|
devConfig.plugins?.push(
|
|
new ESLintPlugin({
|
|
cache: true,
|
|
lintDirtyModulesOnly: true, // don't lint on start, only lint changed files
|
|
extensions: ['.ts', '.tsx'],
|
|
configType: 'flat',
|
|
failOnError: false,
|
|
})
|
|
);
|
|
}
|
|
|
|
return merge(common(env), devConfig);
|
|
};
|