const fs = require("fs"); const path = require("path"); const Copy = require("copy-webpack-plugin"); const Extract = require("mini-css-extract-plugin"); const TerserJSPlugin = require('terser-webpack-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const CompressionPlugin = require("compression-webpack-plugin"); const ESLintPlugin = require('eslint-webpack-plugin'); const CockpitPoPlugin = require("./src/lib/cockpit-po-plugin"); const CockpitRsyncPlugin = require("./src/lib/cockpit-rsync-plugin"); const StylelintPlugin = require('stylelint-webpack-plugin'); const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const webpack = require('webpack'); /* A standard nodejs and webpack pattern */ const production = process.env.NODE_ENV === 'production'; const development = !production; /* development options for faster iteration */ const eslint = process.env.ESLINT !== '0'; /* Default to disable csslint for faster production builds */ const stylelint = process.env.STYLELINT ? (process.env.STYLELINT !== '0') : development; // Cockpit target managed by the development server, // by default connect to a locally running Cockpit let cockpitTarget = process.env.COCKPIT_TARGET || "localhost"; // add the default port if not specified if (cockpitTarget.indexOf(":") === -1) cockpitTarget += ":9090"; cockpitTarget = "https://" + cockpitTarget; // Obtain package name from package.json const packageJson = JSON.parse(fs.readFileSync('package.json')); // Non-JS files which are copied verbatim to dist/ const copy_files = [ "./src/index.html", "./src/manifest.json", // TODO: consider using something more complete like https://github.com/jantimon/favicons-webpack-plugin "./src/assets/favicon.svg", ]; const plugins = [ new Copy({ patterns: copy_files }), new Extract({ filename: "[name].css" }), new CockpitPoPlugin(), new CockpitRsyncPlugin({ dest: packageJson.name }), development && new ReactRefreshWebpackPlugin({ overlay: false }), // replace the "process.env.WEBPACK_SERVE" text in the source code by // the current value of the environment variable, that variable is set to // "true" when running the development server ("npm run server") // https://webpack.js.org/plugins/environment-plugin/ new webpack.EnvironmentPlugin({ WEBPACK_SERVE: null }), // similarly for a non-environment value // https://webpack.js.org/plugins/define-plugin/ // but because ESlint runs *before* the DefinePlugin we need to // add it as a global variable in .eslintrc.json config file new webpack.DefinePlugin({ COCKPIT_TARGET_URL: JSON.stringify(cockpitTarget) }), ].filter(Boolean); if (eslint) { plugins.push(new ESLintPlugin({ extensions: ["js", "jsx"], failOnWarning: true, })); } if (stylelint) { plugins.push(new StylelintPlugin({ context: "src/", })); } /* Only minimize when in production mode */ if (production) { plugins.unshift(new CompressionPlugin({ test: /\.(js|html|css)$/, deleteOriginalAssets: true })); } module.exports = { mode: production ? 'production' : 'development', resolve: { modules: ["node_modules", path.resolve(__dirname, 'src/lib')], plugins: [new TsconfigPathsPlugin({ extensions: [".js", ".jsx", ".json"] })], extensions: ['', '.js', '.json', '.jsx'] }, resolveLoader: { modules: ["node_modules", path.resolve(__dirname, 'src/lib')], }, watchOptions: { ignored: /node_modules/, }, entry: { reactRefreshSetup: '@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js', index: ["./src/index.js"], }, // cockpit.js gets included via