/* This is the OpenMCT common webpack file. It is imported by the other three webpack configurations: - webpack.prod.mjs - the production configuration for OpenMCT (default) - webpack.dev.mjs - the development configuration for OpenMCT - webpack.coverage.mjs - imports webpack.dev.js and adds code coverage There are separate npm scripts to use these configurations, though simply running `npm install` will use the default production configuration. */ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import CopyWebpackPlugin from 'copy-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import { VueLoaderPlugin } from 'vue-loader'; import webpack from 'webpack'; import { merge } from 'webpack-merge'; let gitRevision = 'error-retrieving-revision'; let gitBranch = 'error-retrieving-branch'; const { version } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url))); try { gitRevision = execSync('git rev-parse HEAD').toString().trim(); gitBranch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim(); } catch (err) { console.warn(err); } const projectRootDir = fileURLToPath(new URL('../', import.meta.url)); /** @type {import('webpack').Configuration} */ const config = { context: projectRootDir, devServer: { client: { progress: true, overlay: { // Disable overlay for runtime errors. // See: https://github.com/webpack/webpack-dev-server/issues/4771 runtimeErrors: false } } }, entry: { openmct: './openmct.js', generatorWorker: './example/generator/generatorWorker.js', couchDBChangesFeed: './src/plugins/persistence/couch/CouchChangesFeed.js', inMemorySearchWorker: './src/api/objects/InMemorySearchWorker.js', compsMathWorker: './src/plugins/comps/CompsMathWorker.js', espressoTheme: './src/plugins/themes/espresso-theme.scss', snowTheme: './src/plugins/themes/snow-theme.scss', darkmatterTheme: './src/plugins/themes/darkmatter-theme.scss', historicalTelemetryWorker: './src/plugins/condition/historicalTelemetryWorker.js', }, output: { globalObject: 'this', filename: '[name].js', path: path.resolve(projectRootDir, 'dist'), library: { name: 'openmct', type: 'umd', export: 'default' }, publicPath: '', hashFunction: 'xxhash64', clean: true }, resolve: { alias: { '@': path.join(projectRootDir, 'src'), legacyRegistry: path.join(projectRootDir, 'src/legacyRegistry'), csv: 'comma-separated-values', bourbon: 'bourbon.scss', 'plotly-basic': 'plotly.js-basic-dist-min', 'plotly-gl2d': 'plotly.js-gl2d-dist-min', printj: 'printj/printj.mjs', styles: path.join(projectRootDir, 'src/styles'), MCT: path.join(projectRootDir, 'src/MCT'), testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'), objectUtils: path.join(projectRootDir, 'src/api/objects/object-utils.js'), utils: path.join(projectRootDir, 'src/utils'), vue: 'vue/dist/vue.esm-bundler' } }, plugins: [ new webpack.DefinePlugin({ __OPENMCT_VERSION__: `'${version}'`, __OPENMCT_BUILD_DATE__: `'${new Date()}'`, __OPENMCT_REVISION__: `'${gitRevision}'`, __OPENMCT_BUILD_BRANCH__: `'${gitBranch}'`, __VUE_OPTIONS_API__: true, // enable/disable Options API support, default: true __VUE_PROD_DEVTOOLS__: false, // enable/disable devtools support in production, default: false __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false, // enable/disable hydration mismatch details in production, default: false }), new VueLoaderPlugin(), new CopyWebpackPlugin({ patterns: [ { from: 'src/images/favicons', to: 'favicons' }, { from: './index.html', transform: function (content) { return content.toString().replace(/dist\//g, ''); } }, { from: 'src/plugins/imagery/layers', to: 'imagery' } ] }), new MiniCssExtractPlugin({ filename: '[name].css', chunkFilename: '[name].css' }), // Add a UTF-8 BOM to CSS output to avoid random mojibake new webpack.BannerPlugin({ test: /.*Theme\.css$/, raw: true, banner: '@charset "UTF-8";' }) ], module: { rules: [ { test: /\.(sc|sa|c)ss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader' }, { loader: 'resolve-url-loader' }, { loader: 'sass-loader', options: { sourceMap: true } } ] }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { hoistStatic: false, whitespace: 'preserve' } } }, { test: /\.html$/, type: 'asset/source' }, { test: /\.(jpg|jpeg|png|svg)$/, type: 'asset/resource', generator: { filename: 'images/[name][ext]' } }, { test: /\.ico$/, type: 'asset/resource', generator: { filename: 'icons/[name][ext]' } }, { test: /\.(woff|woff2?|eot|ttf)$/, type: 'asset/resource', generator: { filename: 'fonts/[name][ext]' } } ] }, stats: 'errors-warnings', performance: { // We should eventually consider chunking to decrease // these values maxEntrypointSize: 27000000, maxAssetSize: 27000000 } }; export default config;