// ~~ ENV const dotenv = require('dotenv'); // const path = require('path'); const fs = require('fs'); const webpack = require('webpack'); // ~~ PLUGINS // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const TerserJSPlugin = require('terser-webpack-plugin'); // ~~ PackageJSON // const vtkRules = require('vtk.js/Utilities/config/dependency.js').webpack.core // .rules; // ~~ RULES // const loadShadersRule = require('./rules/loadShaders.js'); const loadWebWorkersRule = require('./rules/loadWebWorkers.js'); const transpileJavaScriptRule = require('./rules/transpileJavaScript.js'); const cssToJavaScript = require('./rules/cssToJavaScript.js'); // Only uncomment for old v2 stylus // const stylusToJavaScript = require('./rules/stylusToJavaScript.js'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); // ~~ ENV VARS const NODE_ENV = process.env.NODE_ENV; const QUICK_BUILD = process.env.QUICK_BUILD; const BUILD_NUM = process.env.CIRCLE_BUILD_NUM || '0'; // read from ../version.txt const VERSION_NUMBER = fs.readFileSync(path.join(__dirname, '../version.txt'), 'utf8') || ''; const COMMIT_HASH = fs.readFileSync(path.join(__dirname, '../commit.txt'), 'utf8') || ''; // dotenv.config(); const defineValues = { /* Application */ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 'process.env.NODE_DEBUG': JSON.stringify(process.env.NODE_DEBUG), 'process.env.DEBUG': JSON.stringify(process.env.DEBUG), 'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL || '/'), 'process.env.BUILD_NUM': JSON.stringify(BUILD_NUM), 'process.env.VERSION_NUMBER': JSON.stringify(VERSION_NUMBER), 'process.env.COMMIT_HASH': JSON.stringify(COMMIT_HASH), /* i18n */ 'process.env.USE_LOCIZE': JSON.stringify(process.env.USE_LOCIZE || ''), 'process.env.LOCIZE_PROJECTID': JSON.stringify(process.env.LOCIZE_PROJECTID || ''), 'process.env.LOCIZE_API_KEY': JSON.stringify(process.env.LOCIZE_API_KEY || ''), 'process.env.REACT_APP_I18N_DEBUG': JSON.stringify(process.env.REACT_APP_I18N_DEBUG || ''), }; // Only redefine updated values. This avoids warning messages in the logs if (!process.env.APP_CONFIG) { defineValues['process.env.APP_CONFIG'] = ''; } module.exports = (env, argv, { SRC_DIR, ENTRY }) => { if (!process.env.NODE_ENV) { throw new Error('process.env.NODE_ENV not set'); } const mode = NODE_ENV === 'production' ? 'production' : 'development'; const isProdBuild = NODE_ENV === 'production'; const isQuickBuild = QUICK_BUILD === 'true'; const config = { mode: isProdBuild ? 'production' : 'development', devtool: isProdBuild ? 'source-map' : 'cheap-module-source-map', entry: ENTRY, optimization: { // splitChunks: { // // include all types of chunks // chunks: 'all', // }, //runtimeChunk: 'single', minimize: isProdBuild, sideEffects: false, }, output: { // clean: true, publicPath: '/', }, context: SRC_DIR, stats: { colors: true, hash: true, timings: true, assets: true, chunks: false, chunkModules: false, modules: false, children: false, warnings: true, }, cache: { type: 'filesystem', }, module: { noParse: [/(dicomicc)/], rules: [ ...(isProdBuild ? [] : [ { test: /\.[jt]sx?$/, exclude: /node_modules/, loader: 'babel-loader', options: { plugins: ['react-refresh/babel'], }, }, ]), { test: /\.svg?$/, oneOf: [ { use: [ { loader: '@svgr/webpack', options: { svgoConfig: { plugins: [ { name: 'preset-default', params: { overrides: { removeViewBox: false, }, }, }, ], }, prettier: false, svgo: true, titleProp: true, }, }, ], issuer: { and: [/\.(ts|tsx|js|jsx|md|mdx)$/], }, }, ], }, transpileJavaScriptRule(mode), loadWebWorkersRule, // loadShadersRule, { test: /\.m?js/, resolve: { fullySpecified: false, }, }, cssToJavaScript, // Note: Only uncomment the following if you are using the old style of stylus in v2 // Also you need to uncomment this platform/app/.webpack/rules/extractStyleChunks.js // stylusToJavaScript, { test: /\.wasm/, type: 'asset/resource', }, { test: /\.(png|jpe?g|gif|svg)$/i, use: [ { loader: 'file-loader', options: { name: 'assets/images/[name].[ext]', }, }, ], }, ], //.concat(vtkRules), }, resolve: { mainFields: ['module', 'browser', 'main'], alias: { // Viewer project '@': path.resolve(__dirname, '../platform/app/src'), '@components': path.resolve(__dirname, '../platform/app/src/components'), '@hooks': path.resolve(__dirname, '../platform/app/src/hooks'), '@routes': path.resolve(__dirname, '../platform/app/src/routes'), '@state': path.resolve(__dirname, '../platform/app/src/state'), 'dicom-microscopy-viewer': 'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js', }, // Which directories to search when resolving modules modules: [ // Modules specific to this package path.resolve(__dirname, '../node_modules'), // Hoisted Yarn Workspace Modules path.resolve(__dirname, '../../../node_modules'), path.resolve(__dirname, '../platform/app/node_modules'), path.resolve(__dirname, '../platform/ui/node_modules'), SRC_DIR, ], // Attempt to resolve these extensions in order. extensions: ['.js', '.jsx', '.json', '.ts', '.tsx', '*'], // symlinked resources are resolved to their real path, not their symlinked location symlinks: true, fallback: { fs: false, path: false, zlib: false, buffer: require.resolve('buffer'), }, }, plugins: [ new webpack.DefinePlugin(defineValues), new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], }), ...(isProdBuild ? [] : [new ReactRefreshWebpackPlugin({ overlay: false })]), // Uncomment to generate bundle analyzer // new BundleAnalyzerPlugin(), ], }; if (isProdBuild) { config.optimization.minimizer = [ new TerserJSPlugin({ parallel: true, terserOptions: {}, }), ]; } if (isQuickBuild) { config.optimization.minimize = false; config.devtool = false; } return config; };