import nodeFs from 'node:fs'; import { type Configuration, type RuleSetRule } from 'webpack'; export type BuildInfoT = { key: string; publicPath: string; timestamp: string; useServiceWorker: boolean; }; export type OptionsT = { babelEnv: string; babelLoaderExclude?: RuleSetRule['exclude']; babelLoaderOptions?: object; context: string; cssLocalIdent?: string; dontEmitBuildInfo?: boolean; dontUseProgressPlugin?: boolean; entry: string | string[]; fs?: typeof nodeFs; keepBuildInfo?: BuildInfoT | boolean; mode: 'development' | 'none' | 'production'; outputPath?: string; publicPath?: string; sitemap?: string; typescript?: boolean; workbox?: boolean | object; }; /** * Creates a new Webpack config object, and performs some auxiliary operations * on the way. * @param {object} ops Configuration params. This allows to modify some * frequently changed options in a convenient way, without a need to manipulate * directly with the created config object. * @param {string} ops.babelEnv Babel environment to use for the Babel * compilation step. * @param [ops.babelLoaderExclude] Overrides the default value of `exclude` * option of babel-loader, which is [/node_modules/]. * @param {object} [ops.babelLoaderOptions] Overrides for default Babel options * of JSX and SVG files loader. * @param ops.context Base URL for resolution of relative config paths. * @param {string} [ops.cssLocalIdent=hash:base64:6] The template for * CSS classnames generation by the Webpack's `css-loader`; it is passed into * the `localIdentName` param of the loader. It should match the corresponding * setting in the Babel config. * @param {boolean} [ops.dontEmitBuildInfo] If set the `.build-info` file won't * be created at the disk during the compilation. * @param [ops.dontUseProgressPlugin] Set to not include progress * plugin. * @param {string|string[]} ops.entry Entry points for "main" chunk. The config * will prepend them by some necessary polyfills, e.g.: * ([babel-polyfill](https://babeljs.io/docs/usage/polyfill/), * [nodelist-foreach-polyfill](https://www.npmjs.com/package/nodelist-foreach-polyfill)). * @param {boolean|object} ops.workbox If evaluates to a truthy value, * [Workbox's InjectManifest plugin](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#injectmanifest_plugin) * is added to the array of Webpack plugins, to generate service worker for * browser. If the value is an object, it is merged into the options passed * into the plugin, otherwise default options are used: * ```json * { * "importWorkboxFrom": "local", * "swSrc": "@dr.pogodin/react-utils/config/workbox/default.js", * "swDest": "__service-worker.js" * } * ``` * If service worker is generated by this option, it will be automatically * initiated at the client side by the standard * [client-side initialization script](docs/client.md) * provided by **@dr.pogodin/react-utils**. Note that `swDest`'s value cannot be * overriden by config options provided via `workbox` object. * @param {object} [ops.fs] Filesystem to use instead of the Node's FS. * @param {boolean|object} [ops.keepBuildInfo] If `true` and a `.build-info` * file from a previous build exists in the context directory, it will be * loaded and used, rather than re-generated by the config factory. It allows * to re-create the Webpack config during a server launch without re-generation * of the build info file created during a previous build (and thus bundled * into the frontend bundle). If an object is provided, it will be used as * the build info, instead of trying to load it from the filesystem. This * feature is intended for testing context. * @param {string} ops.mode * [Webpack mode](https://webpack.js.org/concepts/mode/). * @param {string} [ops.outputPath=build] Optional. Output path for the build. * @param {string} ops.publicPath Base URL for the output of the build assets. * @param {string} [ops.sitemap] The path to JS or JSON config for sitemap. * It can be relative to the context, and can be a factory, which returns * the config. The config should be compatible with * [`sitemap`](https://www.npmjs.com/package/sitemap) library, and if * provided the Webpack config factory will use it to gererate `sitemap.xml` * file in the output folder, and then serve it from the app root. * @return The generated config will opt to: * - Bundle the font assets (EOF, OTF, TTF, WOFF, WOFF2 files from * the `src/assets/fonts` folder of your source code will be bundled * and output into the `[PUBLIC_PATH]/fonts` folder); * - Bundle image assets (GIF, JPEG, JPG, PNG files from any folder of * your source code will be bundled and output into the * `[PUBLIC_PATH]/images` folder); * - Bundle SCSS files from any folder of your source code, beside * `node_modules` and its subfolders. The files will be compiled, * bundled and extracted into the `[PUBLIC_PATH]/[CHUNK_NAME].css` * bundles; * - Bundle CSS files from any folder of your code. The files will be * bundled and extracted into the `[PUBLIC_PATH]/[CHUNK_NAME].css` * bundles; * - Bundle JS, JSX, and SVG files; they will be compiled into the * `[PUBLIC_PATH]/[CHUNK_NAME].js` bundles, using the Babel environment * specified in the factory options, and * [`config/babel/webpack`](./babel-config.js#webpack) config. * * - The following path aliases will be automatically set: * - **`assets`** for `[CONTEXT]/src/assets`; * - **`components`** for `[CONTEXT]/src/shared/components`; * - **`fonts`** for `[CONTEXT]/src/assets/fonts`; * - **`styles`** for `[CONTEXT]/src/styles`. * * Also `resolve.symlinks` Webpack option is set to *false* to avoid problems * with resolution of assets from packages linked with `npm link`. * * - The following global variables will be emulated inside the output * JS bundle: * - **`BUILD_RNDKEY`** — A random 32 bit key that can be used * for encryption, it is set just as a global variable accessible in * the code; * - **`BUILD_TIMESTAMP`** — UTC timestamp of the beginning of * the build; * - **`FRONT_END`** — It will be set *true* inside the bundle, * so that shared code can use it to determine that it is executed * at the client side. * * - It also opts to polyfill the `__dirname` global variable, * and to ignore imports of the `fs` Node package; * * - Also, it will store to the disk (re-writes if exists) the file * `[CONTEXT]/.build-info` which will contain a stringified JSON * object with the following fields: * - **`rndkey`** — The value set for `BUILD_RNDKEY`; * - **`timestamp`** — The value set for `BUILD_TIMESTAMP`. */ export default function configFactory(ops: OptionsT): Configuration;