mirror of
https://github.com/grafana/grafana.git
synced 2026-08-11 13:44:59 -05:00
Build: Upgrade Webpack 5 (#36444)
* build(webpack): bump to v5 and successful yarn start compilation * build(webpack): update postcss dependencies * build(webpack): silence warnings about hash renamed to fullhash * build(webpack): enable persistent cache to store generated webpack modules / chunks * build(webpack): prefer eslintWebpackPlugin over tschecker so eslint doesn't block typechecking * chore(yarn): run yarn-deduplicate to clean up dependencies * chore(yarn): refresh lock file after clean install * build(webpack): prefer output.clean over CleanWebpackPlugin * build(webpack): prefer esbuild over babel-loader for dev config * build(babel): turn off cache compression to improve build performance * build(webpack): get production builds working * build(webpack): remove phantomJS (removed from grafana in v7) specific loader * build(webpack): put back babel for dev builds no performance gain in using esbuild in webpack * build(webpack): prefer terser and optimise css plugins for prod. slower but smaller bundles * build(webpack): clean up redundant code. inform postcss about node_modules * build(webpack): remove deprecation warnings flag * build(webpack): bump packages, dev performance optimisations, attempt to get hot working * chore(storybook): use webpack 5 for dev and production builds * build(storybook): speed up dev build * chore(yarn): refresh lock file * chore(webpack): bump webpack and related deps to latest * refactor(webpack): put back inline-source-map, move start scripts out of grafana toolkit * feat(webpack): prefer react-refresh over react-hot-loader * build(webpack): update webpack.hot to use react-refresh * chore: remove react-hot-loader from codebase * refactor(queryeditorrow): fix circular dependency causing react-fast-refresh errors * revert(webpack): remove stats.errorDetails from common config * build(webpack): bump to v5 and successful yarn start compilation * build(webpack): update postcss dependencies * build(webpack): silence warnings about hash renamed to fullhash * build(webpack): enable persistent cache to store generated webpack modules / chunks * build(webpack): prefer eslintWebpackPlugin over tschecker so eslint doesn't block typechecking * chore(yarn): run yarn-deduplicate to clean up dependencies * chore(yarn): refresh lock file after clean install * build(webpack): prefer output.clean over CleanWebpackPlugin * build(webpack): prefer esbuild over babel-loader for dev config * build(babel): turn off cache compression to improve build performance * build(webpack): get production builds working * build(webpack): remove phantomJS (removed from grafana in v7) specific loader * build(webpack): put back babel for dev builds no performance gain in using esbuild in webpack * build(webpack): prefer terser and optimise css plugins for prod. slower but smaller bundles * build(webpack): clean up redundant code. inform postcss about node_modules * build(webpack): remove deprecation warnings flag * build(webpack): bump packages, dev performance optimisations, attempt to get hot working * chore(storybook): use webpack 5 for dev and production builds * build(storybook): speed up dev build * chore(yarn): refresh lock file * chore(webpack): bump webpack and related deps to latest * refactor(webpack): put back inline-source-map, move start scripts out of grafana toolkit * feat(webpack): prefer react-refresh over react-hot-loader * build(webpack): update webpack.hot to use react-refresh * chore: remove react-hot-loader from codebase * refactor(queryeditorrow): fix circular dependency causing react-fast-refresh errors * revert(webpack): remove stats.errorDetails from common config * revert(webpack): remove include from babel-loader so symlinks (enterprise) work as before * refactor(webpack): fix deprecation warnings in prod builds * fix(storybook): fix failing builds due to replacing css-optimise webpack plugin * fix(storybook): use raw-loader for svg icons * build(webpack): fix dev script colors error * chore(webpack): bump css-loader and react-refresh-webpack-plugin to latest versions Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
co-authored by
Torkel Ödegaard
parent
b40d48258d
commit
8d3b31ff23
@@ -1,6 +1,7 @@
|
||||
module.exports = function getBabelConfig(options = {}) {
|
||||
return {
|
||||
const babelOptions = {
|
||||
cacheDirectory: true,
|
||||
cacheCompression: false,
|
||||
babelrc: false,
|
||||
// Note: order is bottom-to-top and/or right-to-left
|
||||
presets: [
|
||||
@@ -43,4 +44,10 @@ module.exports = function getBabelConfig(options = {}) {
|
||||
'angularjs-annotate',
|
||||
],
|
||||
};
|
||||
|
||||
if (options.REACT_REFRESH) {
|
||||
babelOptions.plugins.push('react-refresh/babel');
|
||||
}
|
||||
|
||||
return babelOptions;
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ module.exports.pitch = function pitch(remainingRequest) {
|
||||
|
||||
function getOutputFilename(options, { target }) {
|
||||
if (!options) {
|
||||
return { filename: `[hash].${target}.js`, options: undefined };
|
||||
return { filename: `[fullhash].${target}.js`, options: undefined };
|
||||
}
|
||||
if (typeof options === 'string') {
|
||||
return { filename: options, options: undefined };
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
module.exports = () => {
|
||||
return {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
'postcss-reporter': {},
|
||||
'postcss-browser-reporter': {},
|
||||
},
|
||||
};
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
'postcss-reporter': {},
|
||||
'postcss-browser-reporter': {},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
|
||||
module.exports = function (options) {
|
||||
return {
|
||||
test: /\.scss$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
@@ -19,7 +21,9 @@ module.exports = function (options) {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: options.sourceMap,
|
||||
config: { path: __dirname },
|
||||
postcssOptions: {
|
||||
config: path.resolve(__dirname),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const getBabelConfig = require('./babel.config');
|
||||
|
||||
class CopyUniconsPlugin {
|
||||
apply(compiler) {
|
||||
@@ -17,31 +16,15 @@ class CopyUniconsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/visionmedia/debug/issues/701#issuecomment-505487361
|
||||
function shouldExclude(filename) {
|
||||
// There is external js code inside this which needs to be processed by babel.
|
||||
if (filename.indexOf(`jaeger-ui-components`) > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const packagesToProcessbyBabel = ['debug', 'lru-cache', 'yallist', 'react-hook-form', 'rc-trigger'];
|
||||
for (const package of packagesToProcessbyBabel) {
|
||||
if (filename.indexOf(`node_modules/${package}`) > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log(path.resolve());
|
||||
module.exports = {
|
||||
target: 'web',
|
||||
entry: {
|
||||
app: './public/app/index.ts',
|
||||
},
|
||||
output: {
|
||||
clean: true,
|
||||
path: path.resolve(__dirname, '../../public/build'),
|
||||
filename: '[name].[hash].js',
|
||||
filename: '[name].[fullhash].js',
|
||||
// Keep publicPath relative for host.com/grafana/ deployments
|
||||
publicPath: 'public/build/',
|
||||
},
|
||||
@@ -64,15 +47,16 @@ module.exports = {
|
||||
// we need full path to root node_modules for grafana-enterprise symlink to work
|
||||
path.resolve('node_modules'),
|
||||
],
|
||||
fallback: {
|
||||
fs: false,
|
||||
stream: false,
|
||||
},
|
||||
},
|
||||
ignoreWarnings: [/export .* was not found in/],
|
||||
stats: {
|
||||
children: false,
|
||||
warningsFilter: /export .* was not found in/,
|
||||
source: false,
|
||||
},
|
||||
node: {
|
||||
fs: 'empty',
|
||||
},
|
||||
plugins: [
|
||||
new CopyUniconsPlugin(),
|
||||
new CopyWebpackPlugin({
|
||||
@@ -97,33 +81,12 @@ module.exports = {
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
/**
|
||||
* Some npm packages are bundled with es2015 syntax, ie. debug
|
||||
* To make them work with PhantomJS we need to transpile them
|
||||
* to get rid of unsupported syntax.
|
||||
*/
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: shouldExclude,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: getBabelConfig(),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: require.resolve('jquery'),
|
||||
use: [
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: 'jQuery',
|
||||
},
|
||||
{
|
||||
loader: 'expose-loader',
|
||||
query: '$',
|
||||
},
|
||||
],
|
||||
loader: 'expose-loader',
|
||||
options: {
|
||||
exposes: ['$', 'jQuery'],
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
@@ -135,10 +98,11 @@ module.exports = {
|
||||
{
|
||||
loader: 'html-loader',
|
||||
options: {
|
||||
attrs: [],
|
||||
minimize: true,
|
||||
removeComments: false,
|
||||
collapseWhitespace: false,
|
||||
sources: false,
|
||||
minimize: {
|
||||
removeComments: false,
|
||||
collapseWhitespace: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -170,7 +134,7 @@ module.exports = {
|
||||
},
|
||||
// https://webpack.js.org/plugins/split-chunks-plugin/#split-chunks-example-3
|
||||
optimization: {
|
||||
moduleIds: 'hashed',
|
||||
moduleIds: 'named',
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
@@ -194,7 +158,7 @@ module.exports = {
|
||||
priority: 50,
|
||||
enforce: true,
|
||||
},
|
||||
vendors: {
|
||||
defaultVendors: {
|
||||
test: /[\\/]node_modules[\\/].*[jt]sx?$/,
|
||||
chunks: 'initial',
|
||||
priority: -10,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const merge = require('webpack-merge');
|
||||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const { DefinePlugin } = require('webpack');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const getBabelConfig = require('./babel.config');
|
||||
@@ -32,13 +32,11 @@ module.exports = (env = {}) =>
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: getBabelConfig({ BABEL_ENV: 'dev' }),
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: getBabelConfig({ BABEL_ENV: 'dev' }),
|
||||
},
|
||||
],
|
||||
},
|
||||
require('./sass.rule.js')({
|
||||
sourceMap: false,
|
||||
@@ -47,19 +45,25 @@ module.exports = (env = {}) =>
|
||||
],
|
||||
},
|
||||
|
||||
// https://webpack.js.org/guides/build-performance/#output-without-path-info
|
||||
output: {
|
||||
pathinfo: false,
|
||||
filename: '[name].js',
|
||||
},
|
||||
|
||||
// https://webpack.js.org/guides/build-performance/#avoid-extra-optimization-steps
|
||||
optimization: {
|
||||
runtimeChunk: true,
|
||||
removeAvailableModules: false,
|
||||
removeEmptyChunks: false,
|
||||
splitChunks: false,
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
env.noTsCheck
|
||||
? new webpack.DefinePlugin({}) // bogus plugin to satisfy webpack API
|
||||
parseInt(env.noTsCheck, 10)
|
||||
? new DefinePlugin({}) // bogus plugin to satisfy webpack API
|
||||
: new ForkTsCheckerWebpackPlugin({
|
||||
eslint: {
|
||||
enabled: true,
|
||||
files: ['public/app/**/*.{ts,tsx}', 'packages/*/src/**/*.{ts,tsx}'],
|
||||
options: {
|
||||
cache: true,
|
||||
},
|
||||
memoryLimit: 4096,
|
||||
},
|
||||
async: true, // don't block webpack emit
|
||||
typescript: {
|
||||
mode: 'write-references',
|
||||
memoryLimit: 4096,
|
||||
@@ -69,8 +73,13 @@ module.exports = (env = {}) =>
|
||||
},
|
||||
},
|
||||
}),
|
||||
// next major version of ForkTsChecker is dropping support for ESLint
|
||||
new ESLintPlugin({
|
||||
lintDirtyModulesOnly: true, // don't lint on start, only lint changed files
|
||||
extensions: ['.ts', '.tsx'],
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'grafana.[name].[hash].css',
|
||||
filename: 'grafana.[name].[fullhash].css',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: path.resolve(__dirname, '../../public/views/error.html'),
|
||||
@@ -82,13 +91,12 @@ module.exports = (env = {}) =>
|
||||
new HtmlWebpackPlugin({
|
||||
filename: path.resolve(__dirname, '../../public/views/index.html'),
|
||||
template: path.resolve(__dirname, '../../public/views/index-template.html'),
|
||||
hash: true,
|
||||
inject: false,
|
||||
chunksSortMode: 'none',
|
||||
excludeChunks: ['dark', 'light'],
|
||||
}),
|
||||
new webpack.NamedModulesPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
new DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('development'),
|
||||
},
|
||||
|
||||
@@ -1,104 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
const merge = require('webpack-merge');
|
||||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const { DefinePlugin } = require('webpack');
|
||||
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
|
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const getBabelConfig = require('./babel.config');
|
||||
|
||||
module.exports = merge(common, {
|
||||
devtool: 'inline-source-map',
|
||||
mode: 'development',
|
||||
|
||||
entry: {
|
||||
app: ['webpack-dev-server/client?http://localhost:3333', './public/app/dev.ts'],
|
||||
app: ['./public/app/index.ts'],
|
||||
dark: './public/sass/grafana.dark.scss',
|
||||
light: './public/sass/grafana.light.scss',
|
||||
},
|
||||
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../../public/build'),
|
||||
filename: '[name].[hash].js',
|
||||
publicPath: '/public/build/',
|
||||
pathinfo: false,
|
||||
watchOptions: {
|
||||
ignored: /node_modules/,
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: ['.scss', '.ts', '.tsx', '.es6', '.js', '.json', '.svg', '.woff2', '.png', '.html'],
|
||||
},
|
||||
|
||||
devtool: 'eval-source-map',
|
||||
|
||||
devServer: {
|
||||
publicPath: '/public/build/',
|
||||
devMiddleware: {
|
||||
writeToDisk: true,
|
||||
},
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
open: false,
|
||||
port: 3333,
|
||||
proxy: {
|
||||
'!/public/build': 'http://localhost:3000',
|
||||
},
|
||||
watchOptions: {
|
||||
ignored: /node_modules/,
|
||||
static: {
|
||||
publicPath: '/public/build/',
|
||||
},
|
||||
},
|
||||
|
||||
optimization: {
|
||||
removeAvailableModules: false,
|
||||
runtimeChunk: false,
|
||||
removeEmptyChunks: false,
|
||||
splitChunks: false,
|
||||
},
|
||||
|
||||
module: {
|
||||
// Note: order is bottom-to-top and/or right-to-left
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: getBabelConfig({ BABEL_ENV: 'dev', REACT_REFRESH: true }),
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: getBabelConfig(),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
'style-loader', // creates style nodes from JS strings
|
||||
'css-loader', // translates CSS into CommonJS
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
config: {
|
||||
path: __dirname + '/postcss.config.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
|
||||
loader: 'file-loader',
|
||||
include: [path.resolve(__dirname, '../../public/'), path.resolve(__dirname, '../../packages/')],
|
||||
},
|
||||
require('./sass.rule.js')({
|
||||
sourceMap: false,
|
||||
preserveUrl: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
// https://webpack.js.org/guides/build-performance/#output-without-path-info
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
pathinfo: false,
|
||||
},
|
||||
|
||||
// https://webpack.js.org/guides/build-performance/#avoid-extra-optimization-steps
|
||||
optimization: {
|
||||
runtimeChunk: true,
|
||||
removeAvailableModules: false,
|
||||
removeEmptyChunks: false,
|
||||
splitChunks: false,
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'grafana.[name].[fullhash].css',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: path.resolve(__dirname, '../../public/views/index.html'),
|
||||
template: path.resolve(__dirname, '../../public/views/index-template.html'),
|
||||
inject: 'body',
|
||||
alwaysWriteToDisk: true,
|
||||
hash: true,
|
||||
inject: false,
|
||||
chunksSortMode: 'none',
|
||||
excludeChunks: ['dark', 'light'],
|
||||
}),
|
||||
new HtmlWebpackHarddiskPlugin(),
|
||||
new webpack.NamedModulesPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
GRAFANA_THEME: JSON.stringify(process.env.GRAFANA_THEME || 'dark'),
|
||||
new ReactRefreshWebpackPlugin(),
|
||||
new DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('development'),
|
||||
},
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const merge = require('webpack-merge');
|
||||
const { merge } = require('webpack-merge');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const getBabelConfig = require('./babel.config');
|
||||
|
||||
module.exports = merge(common, {
|
||||
@@ -41,16 +41,14 @@ module.exports = merge(common, {
|
||||
nodeEnv: 'production',
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
cache: false,
|
||||
parallel: false,
|
||||
sourceMap: true,
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'grafana.[name].[hash].css',
|
||||
filename: 'grafana.[name].[fullhash].css',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: path.resolve(__dirname, '../../public/views/error.html'),
|
||||
|
||||
Reference in New Issue
Block a user