'use strict'; const fs = require('fs'); const path = require('path'); const webpack = require('webpack'); const resolve = require('resolve'); const PnpWebpackPlugin = require('pnp-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const safePostCssParser = require('postcss-safe-parser'); const ManifestPlugin = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const ESLintPlugin = require('eslint-webpack-plugin'); const paths = require('./paths'); const modules = require('./modules'); const alias = require('./alias'); const getClientEnvironment = require('./env'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin'); const typescriptFormatter = require('react-dev-utils/typescriptFormatter'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const postcssNormalize = require('postcss-normalize'); const appPackageJson = require(paths.appPackageJson); const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; const webpackDevClientEntry = require.resolve( 'react-dev-utils/webpackHotDevClient' ); const reactRefreshOverlayEntry = require.resolve( 'react-dev-utils/refreshOverlayInterop' ); const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false'; const imageInlineSizeLimit = parseInt( process.env.IMAGE_INLINE_SIZE_LIMIT || '10000' ); const useTypeScript = fs.existsSync(paths.appTsConfig); const swSrc = paths.swSrc; const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; const hasJsxRuntime = (() => { if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { return false; } try { require.resolve('react/jsx-runtime'); return true; } catch (e) { return false; } })(); module.exports = function (webpackEnv) { const isEnvDevelopment = webpackEnv === 'development'; const isEnvProduction = webpackEnv === 'production'; const isEnvProductionProfile = isEnvProduction && process.argv.includes('--profile'); const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); const shouldUseReactRefresh = env.raw.FAST_REFRESH; const getStyleLoaders = (cssOptions, preProcessor) => { const loaders = [ isEnvDevelopment && require.resolve('style-loader'), isEnvProduction && { loader: require.resolve('style-loader'), options: paths.publicUrlOrPath.startsWith('.') ? { publicPath: '../../', attributes: { nonce: 'MzA3MWM2MTA4NjFhYzY1Y2RlOTRjZjdiODdkNzczNjkK'} } : { attributes: { nonce: 'MzA3MWM2MTA4NjFhYzY1Y2RlOTRjZjdiODdkNzczNjkK'} }, }, { loader: require.resolve('css-loader'), options: cssOptions, }, { loader: require.resolve('postcss-loader'), options: { ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009', }, stage: 3, }), postcssNormalize(), ], sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }, }, ].filter(Boolean); if (preProcessor) { loaders.push( { loader: require.resolve('resolve-url-loader'), options: { sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, root: paths.appSrc, }, }, { loader: require.resolve(preProcessor), options: { sourceMap: true, }, } ); } return loaders; }; console.log('-----------------'); console.log('Build Time Env ::: ', process.env.APP_ENV); console.log('Build Time API Url ::: ', process.env.API_URL); console.log('Build Time NODE Env ::: ', process.env.NODE_ENV); console.log('Build Time Replace Origin Logo ::: ', process.env.REPLACE_COMPANY_LOGO); console.log('-----------------'); return { mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development', bail: isEnvProduction, devtool: isEnvProduction ? shouldUseSourceMap ? 'source-map' : false : isEnvDevelopment && 'cheap-module-source-map', entry: isEnvDevelopment && !shouldUseReactRefresh ? [ webpackDevClientEntry, paths.appIndexJs, ] : paths.appIndexJs, output: { path: isEnvProduction ? paths.appBuild : undefined, pathinfo: isEnvDevelopment, filename: isEnvProduction ? 'static/js/[name].[contenthash:8].js' : isEnvDevelopment && 'static/js/bundle.js', futureEmitAssets: true, chunkFilename: isEnvProduction ? 'static/js/[name].[contenthash:8].chunk.js' : isEnvDevelopment && 'static/js/[name].chunk.js', publicPath: paths.publicUrlOrPath, devtoolModuleFilenameTemplate: isEnvProduction ? info => path .relative(paths.appSrc, info.absoluteResourcePath) .replace(/\\/g, '/') : isEnvDevelopment && (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), jsonpFunction: `webpackJsonp${appPackageJson.name}`, globalObject: 'this', }, optimization: { minimize: isEnvProduction, minimizer: [ new TerserPlugin({ terserOptions: { parse: { ecma: 8, }, compress: { ecma: 5, warnings: false, comparisons: false, inline: 2, }, mangle: { safari10: true, }, keep_classnames: isEnvProductionProfile, keep_fnames: isEnvProductionProfile, output: { ecma: 5, comments: false, ascii_only: true, }, }, sourceMap: shouldUseSourceMap, }), new OptimizeCSSAssetsPlugin({ cssProcessorOptions: { parser: safePostCssParser, map: shouldUseSourceMap ? { inline: false, annotation: true, } : false, }, cssProcessorPluginOptions: { preset: ['default', { minifyFontValues: { removeQuotes: false } }], }, }), ], splitChunks: { chunks: 'all', name: false, }, runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}`, }, }, resolve: { modules: ['node_modules', paths.appNodeModules].concat( modules.additionalModulePaths || [] ), extensions: paths.moduleFileExtensions .map(ext => `.${ext}`) .filter(ext => useTypeScript || !ext.includes('ts')), alias: { 'react-native': 'react-native-web', ...(isEnvProductionProfile && { 'react-dom$': 'react-dom/profiling', 'scheduler/tracing': 'scheduler/tracing-profiling', }), ...(modules.webpackAliases || {}), ...alias, }, plugins: [ PnpWebpackPlugin, new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson, reactRefreshOverlayEntry, ]), ], }, resolveLoader: { plugins: [ PnpWebpackPlugin.moduleLoader(module), ], }, module: { strictExportPresence: true, rules: [ { parser: { requireEnsure: false } }, { oneOf: [ { test: [/\.avif$/], loader: require.resolve('url-loader'), options: { limit: imageInlineSizeLimit, mimetype: 'image/avif', name: 'static/media/[name].[hash:8].[ext]', }, }, { test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: require.resolve('url-loader'), options: { limit: imageInlineSizeLimit, name: 'static/media/[name].[hash:8].[ext]', }, }, { test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, loader: require.resolve('babel-loader'), options: { customize: require.resolve( 'babel-preset-react-app/webpack-overrides' ), presets: [ [ require.resolve('babel-preset-react-app'), { runtime: hasJsxRuntime ? 'automatic' : 'classic', }, ], ], plugins: [ [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]', }, }, }, ], isEnvDevelopment && shouldUseReactRefresh && require.resolve('react-refresh/babel'), ].filter(Boolean), cacheDirectory: true, cacheCompression: false, compact: isEnvProduction, }, }, { test: /\.(js|mjs)$/, exclude: /@babel(?:\/|\\{1,2})runtime/, loader: require.resolve('babel-loader'), options: { babelrc: false, configFile: false, compact: false, presets: [ [ require.resolve('babel-preset-react-app/dependencies'), { helpers: true, useBuiltIns: 'entry' }, ], ], cacheDirectory: true, cacheCompression: false, sourceMaps: shouldUseSourceMap, inputSourceMap: shouldUseSourceMap, }, }, { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }), sideEffects: true, }, { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }), }, { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }, 'sass-loader' ), sideEffects: true, }, { test: sassModuleRegex, use: getStyleLoaders( { importLoaders: 3, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }, 'sass-loader' ), }, { loader: require.resolve('file-loader'), exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], options: { name: 'static/media/[name].[hash:8].[ext]', }, }, ], }, ], }, plugins: [ new HtmlWebpackPlugin( Object.assign( {}, { inject: true, template: paths.appHtml, }, isEnvProduction ? { minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true, }, } : undefined ) ), isEnvProduction && shouldInlineRuntimeChunk && new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw), new ModuleNotFoundPlugin(paths.appPath), new webpack.DefinePlugin(env.stringified), isEnvDevelopment && new webpack.HotModuleReplacementPlugin(), isEnvDevelopment && shouldUseReactRefresh && new ReactRefreshWebpackPlugin({ overlay: { entry: webpackDevClientEntry, module: reactRefreshOverlayEntry, sockIntegration: false, }, }), isEnvDevelopment && new CaseSensitivePathsPlugin(), isEnvDevelopment && new WatchMissingNodeModulesPlugin(paths.appNodeModules), isEnvProduction && new MiniCssExtractPlugin({ filename: 'static/css/[name].[contenthash:8].css', chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', }), new ManifestPlugin({ fileName: 'asset-manifest.json', publicPath: paths.publicUrlOrPath, generate: (seed, files, entrypoints) => { const manifestFiles = files.reduce((manifest, file) => { manifest[file.name] = file.path; return manifest; }, seed); const entrypointFiles = entrypoints.main.filter( fileName => !fileName.endsWith('.map') ); return { files: manifestFiles, entrypoints: entrypointFiles, }; }, }), isEnvProduction && fs.existsSync(swSrc) && new WorkboxWebpackPlugin.InjectManifest({ swSrc, dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/], maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, }), useTypeScript && new ForkTsCheckerWebpackPlugin({ typescript: resolve.sync('typescript', { basedir: paths.appNodeModules, }), async: isEnvDevelopment, checkSyntacticErrors: true, resolveModuleNameModule: process.versions.pnp ? `${__dirname}/pnpTs.js` : undefined, resolveTypeReferenceDirectiveModule: process.versions.pnp ? `${__dirname}/pnpTs.js` : undefined, tsconfig: paths.appTsConfig, reportFiles: [ '../**/src/**/*.{ts,tsx}', '**/src/**/*.{ts,tsx}', '!**/src/**/__tests__/**', '!**/src/**/?(*.)(spec|test).*', '!**/src/setupProxy.*', '!**/src/setupTests.*', ], silent: true, formatter: isEnvProduction ? typescriptFormatter : undefined, }), new ESLintPlugin({ extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], formatter: require.resolve('react-dev-utils/eslintFormatter'), eslintPath: require.resolve('eslint'), context: paths.appSrc, cache: true, cwd: paths.appPath, resolvePluginsRelativeTo: __dirname, baseConfig: { extends: [require.resolve('eslint-config-react-app/base')], rules: { ...(!hasJsxRuntime && { 'react/react-in-jsx-scope': 'error', }), }, }, }), ].filter(Boolean), node: { module: 'empty', dgram: 'empty', dns: 'mock', fs: 'empty', http2: 'empty', net: 'empty', tls: 'empty', child_process: 'empty', }, performance: false, }; };