@davnx/webpack 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +390 -0
- package/create-webpack-dev.d.ts +24 -0
- package/create-webpack-dev.js +155 -0
- package/create-webpack-dev.js.map +1 -0
- package/create-webpack-prod.d.ts +32 -0
- package/create-webpack-prod.js +186 -0
- package/create-webpack-prod.js.map +1 -0
- package/executors/build/build.impl.d.ts +42 -0
- package/executors/build/build.impl.js +107 -0
- package/executors/build/build.impl.js.map +1 -0
- package/executors/build/schema.json +115 -0
- package/executors/serve/schema.json +94 -0
- package/executors/serve/serve.impl.d.ts +42 -0
- package/executors/serve/serve.impl.js +227 -0
- package/executors/serve/serve.impl.js.map +1 -0
- package/executors.json +14 -0
- package/index.d.ts +3 -0
- package/index.js +8 -0
- package/index.js.map +1 -0
- package/main.devserver.d.ts +2 -0
- package/main.devserver.js +482 -0
- package/main.devserver.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# @davnx/webpack
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@davnx/webpack)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
Custom Nx executors for building and serving NestJS applications with webpack. Includes a multi-process development server with hot module reload and round-robin load balancing.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -D @davnx/webpack
|
|
12
|
+
# or
|
|
13
|
+
yarn add -D @davnx/webpack
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Peer dependencies** (must be installed in your workspace):
|
|
17
|
+
|
|
18
|
+
- `webpack` ^5.0.0
|
|
19
|
+
- `@nx/webpack` >=20.0.0
|
|
20
|
+
- `@nx/devkit` >=20.0.0
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
Add the executors to your NestJS app's `project.json`:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"targets": {
|
|
29
|
+
"build": {
|
|
30
|
+
"executor": "@davnx/webpack:build",
|
|
31
|
+
"dependsOn": ["^build"],
|
|
32
|
+
"options": {
|
|
33
|
+
"entryFile": "./src/deployments/service/main.ts",
|
|
34
|
+
"tsConfigFile": "./tsconfig.app.json",
|
|
35
|
+
"orgScopes": ["@myorg"]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"serve": {
|
|
39
|
+
"executor": "@davnx/webpack:serve",
|
|
40
|
+
"options": {
|
|
41
|
+
"entryFile": "./src/deployments/service/main.ts",
|
|
42
|
+
"tsConfigFile": "./tsconfig.app.json",
|
|
43
|
+
"orgScopes": ["@myorg"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then run:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
nx serve my-app # Development with hot reload
|
|
54
|
+
nx build my-app # Production build
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Executors
|
|
58
|
+
|
|
59
|
+
### `@davnx/webpack:build`
|
|
60
|
+
|
|
61
|
+
Production webpack build for NestJS applications. Compiles your application with full type checking, tree shaking, and generates a deployable `package.json`.
|
|
62
|
+
|
|
63
|
+
#### Options
|
|
64
|
+
|
|
65
|
+
| Option | Type | Default | Description |
|
|
66
|
+
|--------|------|---------|-------------|
|
|
67
|
+
| `entryFile` | `string` | `./src/deployments/service/main.ts` | Entry point file (relative to project root) |
|
|
68
|
+
| `tsConfigFile` | `string` | `./tsconfig.app.json` | TypeScript config file |
|
|
69
|
+
| `outputPath` | `string` | `dist/{projectRoot}` | Output directory (relative to workspace root) |
|
|
70
|
+
| `assets` | `string[]` | `[]` | Static assets to copy to the output |
|
|
71
|
+
| `additionalEntryPoints` | `object[]` | `[]` | Extra webpack entry points (`{ entryName, entryPath }`) |
|
|
72
|
+
| `runtimeDependencies` | `string[]` | `[]` | Extra dependencies for the generated `package.json` |
|
|
73
|
+
| `ormConfigPath` | `string` | auto-detect | Path to `ormconfig.ts` (empty string to disable) |
|
|
74
|
+
| `migrationsDir` | `string` | `./src/migrations` | TypeORM migrations directory |
|
|
75
|
+
| `memoryLimit` | `number` | `8192` | Memory limit (MB) for the TypeScript type checker |
|
|
76
|
+
| `generatePackageJson` | `boolean` | `true` | Generate a `package.json` in the output directory |
|
|
77
|
+
| `buildLibsFromSource` | `boolean` | `false` | Read workspace libraries from source instead of pre-built dist |
|
|
78
|
+
| `orgScopes` | `string[]` | `[]` | Org scopes to bundle into the output (e.g. `["@myorg"]`) |
|
|
79
|
+
| `bundlePackages` | `string[]` | `[]` | Explicit package names to force-bundle (e.g. `["lodash"]`) |
|
|
80
|
+
| `nodeExternalsConfig` | `object` | `{}` | Override options for `webpack-node-externals` (see [Externals Configuration](#externals-configuration)) |
|
|
81
|
+
| `webpackConfigPath` | `string` | — | Path to a JS/TS file exporting a `(config) => config` override function (see [Webpack Overrides](#webpack-overrides)) |
|
|
82
|
+
|
|
83
|
+
#### TypeORM Support
|
|
84
|
+
|
|
85
|
+
If an `ormconfig.ts` file is detected in `src/ormconfig.ts` (or at the path specified by `ormConfigPath`), the build executor automatically creates a second webpack compilation that bundles:
|
|
86
|
+
|
|
87
|
+
- `ormconfig.js` — the TypeORM CLI configuration
|
|
88
|
+
- `migrations/*.js` — all migration files from `migrationsDir`
|
|
89
|
+
|
|
90
|
+
This allows running TypeORM CLI commands (`typeorm migration:run`) directly against the production build output.
|
|
91
|
+
|
|
92
|
+
#### Example: Full Configuration
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"build": {
|
|
97
|
+
"executor": "@davnx/webpack:build",
|
|
98
|
+
"dependsOn": ["^build"],
|
|
99
|
+
"options": {
|
|
100
|
+
"entryFile": "./src/deployments/service/main.ts",
|
|
101
|
+
"tsConfigFile": "./tsconfig.app.json",
|
|
102
|
+
"outputPath": "dist/apps/my-api",
|
|
103
|
+
"orgScopes": ["@myorg"],
|
|
104
|
+
"additionalEntryPoints": [
|
|
105
|
+
{ "entryName": "worker", "entryPath": "./src/deployments/worker/main.ts" }
|
|
106
|
+
],
|
|
107
|
+
"runtimeDependencies": ["pg", "redis"],
|
|
108
|
+
"assets": ["apps/my-api/src/assets"]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### `@davnx/webpack:serve`
|
|
115
|
+
|
|
116
|
+
Development server with webpack watch mode, async type checking, and an integrated multi-process HTTP server with hot module reload.
|
|
117
|
+
|
|
118
|
+
#### Options
|
|
119
|
+
|
|
120
|
+
| Option | Type | Default | Description |
|
|
121
|
+
|--------|------|---------|-------------|
|
|
122
|
+
| `entryFile` | `string` | `./src/deployments/service/main.ts` | Entry point file |
|
|
123
|
+
| `tsConfigFile` | `string` | `./tsconfig.app.json` | TypeScript config file |
|
|
124
|
+
| `outputPath` | `string` | `dist/{projectRoot}` | Output directory |
|
|
125
|
+
| `assets` | `string[]` | `[]` | Static assets to copy |
|
|
126
|
+
| `configEnv` | `string` | `development` | Config YAML environment (`config/config.{env}.yaml`) |
|
|
127
|
+
| `memoryLimit` | `number` | `8192` | Memory limit (MB) for the TypeScript type checker |
|
|
128
|
+
| `childCount` | `number` | `1` | Number of child worker processes |
|
|
129
|
+
| `buildLibsFromSource` | `boolean` | `true` | Read workspace libraries from source for faster dev builds |
|
|
130
|
+
| `orgScopes` | `string[]` | `[]` | Org scopes to bundle (e.g. `["@myorg"]`) |
|
|
131
|
+
| `bundlePackages` | `string[]` | `[]` | Explicit package names to force-bundle (e.g. `["lodash"]`) |
|
|
132
|
+
| `nodeExternalsConfig` | `object` | `{}` | Override options for `webpack-node-externals` (see [Externals Configuration](#externals-configuration)) |
|
|
133
|
+
| `webpackConfigPath` | `string` | — | Path to a JS/TS file exporting a `(config) => config` override function (see [Webpack Overrides](#webpack-overrides)) |
|
|
134
|
+
|
|
135
|
+
#### How the Dev Server Works
|
|
136
|
+
|
|
137
|
+
The serve executor runs a multi-process architecture:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
┌─────────────────────────────────────────────┐
|
|
141
|
+
│ Webpack (watch mode) │
|
|
142
|
+
│ Compiles on file change → triggers reload │
|
|
143
|
+
└──────────────┬──────────────────────────────┘
|
|
144
|
+
│ POST /webpack/reload
|
|
145
|
+
▼
|
|
146
|
+
┌─────────────────────────────────────────────┐
|
|
147
|
+
│ Parent Process (port from config YAML) │
|
|
148
|
+
│ Round-robin load balancer │
|
|
149
|
+
│ Service prefix enforcement │
|
|
150
|
+
├────────────┬────────────────────────────────┤
|
|
151
|
+
│ Child #1 │ Child #2 │ ... Child #N │
|
|
152
|
+
│ NestJS app │ NestJS app │ NestJS app │
|
|
153
|
+
│ Unix sock │ Unix sock │ Unix sock │
|
|
154
|
+
└────────────┴────────────┴───────────────────┘
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
1. **Webpack watches** for file changes and recompiles
|
|
158
|
+
2. On successful build, a **reload signal** is sent to the parent process
|
|
159
|
+
3. The parent forwards the reload to all **child processes** via IPC
|
|
160
|
+
4. Each child **hot-swaps** the NestJS application in-process (no restart needed)
|
|
161
|
+
5. Incoming HTTP requests are **round-robin proxied** to healthy children
|
|
162
|
+
6. If a child crashes, the parent **respawns** it automatically
|
|
163
|
+
|
|
164
|
+
#### Config Resolution
|
|
165
|
+
|
|
166
|
+
The serve executor reads `config/config.{configEnv}.yaml` from the workspace root to resolve:
|
|
167
|
+
|
|
168
|
+
- `port` — the port the dev server listens on (default: `3050`)
|
|
169
|
+
- `serviceName` — used for URL prefix enforcement and socket naming
|
|
170
|
+
|
|
171
|
+
```yaml
|
|
172
|
+
# config/config.development.yaml
|
|
173
|
+
port: 3050
|
|
174
|
+
serviceName: my-api
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
With `serviceName: my-api`, the devserver enforces that all requests start with `/my-api/`, mimicking production gateway behavior. Requests without the prefix return 404.
|
|
178
|
+
|
|
179
|
+
## NestJS Bootstrap Contract
|
|
180
|
+
|
|
181
|
+
Your application's entry point must implement a dual-mode bootstrap pattern to support both standalone production and devserver development modes.
|
|
182
|
+
|
|
183
|
+
### How It Works
|
|
184
|
+
|
|
185
|
+
| Mode | Trigger | Behavior |
|
|
186
|
+
|------|---------|----------|
|
|
187
|
+
| **Production** | `node dist/.../main.js` | Starts normally via `startStandalone()` — binds to a port |
|
|
188
|
+
| **Development** | `nx serve` | Devserver sets `DEVSERVER_MODE=1`, loads the bundle, and calls `global.createChildApp()` — the app bootstraps without binding to a port |
|
|
189
|
+
|
|
190
|
+
### Required Type
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
export type BuiltChildApp = {
|
|
194
|
+
handler: http.RequestListener; // Raw HTTP request handler (Fastify/Express)
|
|
195
|
+
serviceConfig: { port: number | string }; // Service configuration
|
|
196
|
+
close: () => Promise<void>; // Cleanup function for graceful shutdown
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Entry Point Template
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// src/deployments/service/main.ts
|
|
204
|
+
import '../tracing/service'; // must be first for APM instrumentation
|
|
205
|
+
import { createAppModule } from './app.module';
|
|
206
|
+
import {
|
|
207
|
+
createStandaloneFunction,
|
|
208
|
+
createChildAppFunction,
|
|
209
|
+
bootstrapDevServerIfNeeded,
|
|
210
|
+
} from '../bootstrap';
|
|
211
|
+
|
|
212
|
+
const appModule = createAppModule();
|
|
213
|
+
const startStandalone = createStandaloneFunction(appModule);
|
|
214
|
+
const createChildApp = createChildAppFunction(appModule);
|
|
215
|
+
bootstrapDevServerIfNeeded(startStandalone, createChildApp);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Bootstrap Implementation
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// src/deployments/bootstrap.ts
|
|
222
|
+
import { NestFactory } from '@nestjs/core';
|
|
223
|
+
import {
|
|
224
|
+
FastifyAdapter,
|
|
225
|
+
NestFastifyApplication,
|
|
226
|
+
} from '@nestjs/platform-fastify';
|
|
227
|
+
import * as http from 'node:http';
|
|
228
|
+
|
|
229
|
+
export function createStandaloneFunction(appModule: any) {
|
|
230
|
+
return async () => {
|
|
231
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
232
|
+
appModule,
|
|
233
|
+
new FastifyAdapter(),
|
|
234
|
+
);
|
|
235
|
+
await app.listen(process.env.PORT || 3000, '0.0.0.0');
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function createChildAppFunction(appModule: any) {
|
|
240
|
+
return async (): Promise<BuiltChildApp> => {
|
|
241
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
242
|
+
appModule,
|
|
243
|
+
new FastifyAdapter(),
|
|
244
|
+
);
|
|
245
|
+
await app.init();
|
|
246
|
+
await app.getHttpAdapter().getInstance().ready();
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
handler: app.getHttpServer() as http.RequestListener,
|
|
250
|
+
serviceConfig: { port: process.env.PORT || 3000 },
|
|
251
|
+
close: () => app.close(),
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function bootstrapDevServerIfNeeded(
|
|
257
|
+
startStandalone: () => Promise<void>,
|
|
258
|
+
createChildApp: () => Promise<BuiltChildApp>,
|
|
259
|
+
) {
|
|
260
|
+
if (process.env.DEVSERVER_MODE === '1') {
|
|
261
|
+
// Devserver mode: export factory for the devserver to call
|
|
262
|
+
(global as any).createChildApp = createChildApp;
|
|
263
|
+
} else {
|
|
264
|
+
// Standalone mode: start the app normally
|
|
265
|
+
startStandalone();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Externals Configuration
|
|
271
|
+
|
|
272
|
+
By default, all `node_modules` are externalized (not bundled) except:
|
|
273
|
+
- Packages matching `orgScopes` (monorepo org scopes)
|
|
274
|
+
- Workspace paths (`apps/`, `libs/`)
|
|
275
|
+
|
|
276
|
+
Use `bundlePackages` and `nodeExternalsConfig` for fine-grained control over what gets bundled vs. externalized.
|
|
277
|
+
|
|
278
|
+
### `bundlePackages`
|
|
279
|
+
|
|
280
|
+
Force-bundle specific npm packages into the output:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"options": {
|
|
285
|
+
"orgScopes": ["@myorg"],
|
|
286
|
+
"bundlePackages": ["lodash", "date-fns"]
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### `nodeExternalsConfig`
|
|
292
|
+
|
|
293
|
+
Override [webpack-node-externals](https://github.com/liady/webpack-node-externals) options:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"options": {
|
|
298
|
+
"nodeExternalsConfig": {
|
|
299
|
+
"allowlist": ["some-esm-only-pkg"],
|
|
300
|
+
"additionalModuleDirs": ["../../shared-modules"],
|
|
301
|
+
"importType": "module"
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
The `allowlist` entries are **appended** to the auto-generated patterns from `orgScopes` and `bundlePackages`.
|
|
308
|
+
|
|
309
|
+
## Webpack Overrides
|
|
310
|
+
|
|
311
|
+
For advanced customization (custom plugins, loaders, output tweaks), point `webpackConfigPath` to a JS file that exports a transform function:
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"options": {
|
|
316
|
+
"webpackConfigPath": "./webpack.overrides.js"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
```js
|
|
322
|
+
// webpack.overrides.js
|
|
323
|
+
const { BannerPlugin } = require('webpack');
|
|
324
|
+
|
|
325
|
+
module.exports = (config) => {
|
|
326
|
+
// Add a custom plugin
|
|
327
|
+
config.plugins.push(new BannerPlugin({ banner: '/* custom banner */' }));
|
|
328
|
+
|
|
329
|
+
// Modify output settings
|
|
330
|
+
config.output.library = { type: 'commonjs2' };
|
|
331
|
+
|
|
332
|
+
return config;
|
|
333
|
+
};
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The override function receives the fully-built webpack config and must return the modified config. For the build executor, it is called on each config in the array (main build + ORM config if present).
|
|
337
|
+
|
|
338
|
+
## Programmatic API
|
|
339
|
+
|
|
340
|
+
The webpack config generators can be used directly for custom build setups:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { createProdWebpackConfig, createDevWebpackConfig } from '@davnx/webpack';
|
|
344
|
+
|
|
345
|
+
// Production config
|
|
346
|
+
const prodConfigs = createProdWebpackConfig({
|
|
347
|
+
appName: 'my-app',
|
|
348
|
+
appRoot: '/path/to/app',
|
|
349
|
+
outputDir: '/path/to/dist',
|
|
350
|
+
main: './src/main.ts',
|
|
351
|
+
tsConfig: './tsconfig.app.json',
|
|
352
|
+
workspaceRoot: '/path/to/workspace',
|
|
353
|
+
orgScopes: ['@myorg'],
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// Development config
|
|
357
|
+
const devConfig = createDevWebpackConfig({
|
|
358
|
+
appName: 'my-app',
|
|
359
|
+
appRoot: '/path/to/app',
|
|
360
|
+
outputDir: '/path/to/dist',
|
|
361
|
+
main: './src/main.ts',
|
|
362
|
+
tsConfig: './tsconfig.app.json',
|
|
363
|
+
workspaceRoot: '/path/to/workspace',
|
|
364
|
+
port: 3050,
|
|
365
|
+
serviceName: 'my-app',
|
|
366
|
+
orgScopes: ['@myorg'],
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### `createProdWebpackConfig(options)`
|
|
371
|
+
|
|
372
|
+
Returns an array of webpack configurations. The first config is always the main application build. If an `ormconfig.ts` is detected, a second config for TypeORM migrations is included.
|
|
373
|
+
|
|
374
|
+
### `createDevWebpackConfig(options)`
|
|
375
|
+
|
|
376
|
+
Returns a single webpack configuration with watch mode enabled, HMR, async type checking, filesystem caching, and the `DevServerReloadPlugin` that notifies the devserver after each successful build.
|
|
377
|
+
|
|
378
|
+
## Key Features
|
|
379
|
+
|
|
380
|
+
- **Node 22 target** — compiled with `target: node22` for modern JavaScript
|
|
381
|
+
- **Org scope bundling** — packages matching `orgScopes` are bundled into the output instead of being externalized, useful for monorepo packages
|
|
382
|
+
- **Async type checking** — `fork-ts-checker-webpack-plugin` runs type checking in a separate process so builds aren't blocked
|
|
383
|
+
- **Filesystem caching** — webpack cache persists across dev rebuilds for fast incremental compilation
|
|
384
|
+
- **Auto package.json** — production builds generate a `package.json` with only the runtime dependencies needed
|
|
385
|
+
- **Source maps** — inline source maps in production, eval source maps in development
|
|
386
|
+
- **Multi-child devserver** — scale development with multiple child processes for parallel request handling
|
|
387
|
+
|
|
388
|
+
## License
|
|
389
|
+
|
|
390
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface NodeExternalsConfig {
|
|
2
|
+
allowlist?: (string | RegExp)[];
|
|
3
|
+
additionalModuleDirs?: string[];
|
|
4
|
+
importType?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DevWebpackOptions {
|
|
7
|
+
appName: string;
|
|
8
|
+
appRoot: string;
|
|
9
|
+
outputDir: string;
|
|
10
|
+
main: string;
|
|
11
|
+
tsConfig: string;
|
|
12
|
+
workspaceRoot: string;
|
|
13
|
+
assets?: string[];
|
|
14
|
+
port: number;
|
|
15
|
+
serviceName: string;
|
|
16
|
+
memoryLimit?: number;
|
|
17
|
+
buildLibsFromSource?: boolean;
|
|
18
|
+
orgScopes?: string[];
|
|
19
|
+
bundlePackages?: string[];
|
|
20
|
+
nodeExternalsConfig?: NodeExternalsConfig;
|
|
21
|
+
webpackConfigPath?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function createDevWebpackConfig(options: DevWebpackOptions): Record<string, any>;
|
|
24
|
+
//# sourceMappingURL=create-webpack-dev.d.ts.map
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createDevWebpackConfig = createDevWebpackConfig;
|
|
37
|
+
const app_plugin_1 = require("@nx/webpack/app-plugin");
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const nodeExternals = __importStar(require("webpack-node-externals"));
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
41
|
+
const webpack = require('webpack');
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
43
|
+
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
|
44
|
+
class DevServerReloadPlugin {
|
|
45
|
+
url;
|
|
46
|
+
constructor(port) {
|
|
47
|
+
this.url = `http://localhost:${port}/webpack/reload`;
|
|
48
|
+
}
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
apply(compiler) {
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
compiler.hooks.done.tap('DevServerReloadPlugin', async (stats) => {
|
|
53
|
+
try {
|
|
54
|
+
if (stats.hasErrors())
|
|
55
|
+
return;
|
|
56
|
+
await fetch(this.url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' });
|
|
57
|
+
console.log('[DevServerReloadPlugin] notified devserver to reload');
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
console.log('[DevServerReloadPlugin] devserver not running yet');
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function buildScopePatterns(orgScopes) {
|
|
66
|
+
const allowlistPatterns = orgScopes.map((scope) => new RegExp(`^${scope.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}/`));
|
|
67
|
+
const scopePrefixes = orgScopes.map((scope) => (scope.endsWith('/') ? scope : `${scope}/`));
|
|
68
|
+
return { allowlistPatterns, scopePrefixes };
|
|
69
|
+
}
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
function createDevWebpackConfig(options) {
|
|
72
|
+
const { appRoot, outputDir, main, tsConfig, workspaceRoot, assets = [], port, memoryLimit = 8192, buildLibsFromSource = true, orgScopes = [], bundlePackages = [], nodeExternalsConfig: userNodeExternalsConfig, webpackConfigPath, } = options;
|
|
73
|
+
const { allowlistPatterns, scopePrefixes } = buildScopePatterns(orgScopes);
|
|
74
|
+
// Build combined allowlist: orgScopes + bundlePackages + user-provided
|
|
75
|
+
const bundlePatterns = bundlePackages.map((pkg) => new RegExp(`^${pkg.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(/|$)`));
|
|
76
|
+
const combinedAllowlist = [
|
|
77
|
+
/webpack\/hot\/poll\?100/,
|
|
78
|
+
...allowlistPatterns,
|
|
79
|
+
...bundlePatterns,
|
|
80
|
+
...(userNodeExternalsConfig?.allowlist || []),
|
|
81
|
+
];
|
|
82
|
+
const config = {
|
|
83
|
+
output: {
|
|
84
|
+
path: outputDir,
|
|
85
|
+
...(process.env.NODE_ENV !== 'production' && {
|
|
86
|
+
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
|
|
87
|
+
}),
|
|
88
|
+
clean: true,
|
|
89
|
+
},
|
|
90
|
+
externals: [
|
|
91
|
+
nodeExternals({
|
|
92
|
+
allowlist: combinedAllowlist,
|
|
93
|
+
additionalModuleDirs: userNodeExternalsConfig?.additionalModuleDirs || [],
|
|
94
|
+
...(userNodeExternalsConfig?.importType && { importType: userNodeExternalsConfig.importType }),
|
|
95
|
+
}),
|
|
96
|
+
({ request }, callback) => {
|
|
97
|
+
if (request &&
|
|
98
|
+
(request.startsWith(path.join(workspaceRoot, 'apps')) ||
|
|
99
|
+
request.startsWith(path.join(workspaceRoot, 'libs')))) {
|
|
100
|
+
return callback();
|
|
101
|
+
}
|
|
102
|
+
if (request && scopePrefixes.some((prefix) => request.startsWith(prefix))) {
|
|
103
|
+
return callback();
|
|
104
|
+
}
|
|
105
|
+
if (request && !(request.startsWith('./') || request.startsWith('..'))) {
|
|
106
|
+
return callback(null, `commonjs ${request}`);
|
|
107
|
+
}
|
|
108
|
+
return callback();
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
mode: 'development',
|
|
112
|
+
devtool: 'eval-cheap-module-source-map',
|
|
113
|
+
plugins: [
|
|
114
|
+
new webpack.HotModuleReplacementPlugin(),
|
|
115
|
+
new app_plugin_1.NxAppWebpackPlugin({
|
|
116
|
+
target: 'node22',
|
|
117
|
+
compiler: 'tsc',
|
|
118
|
+
main,
|
|
119
|
+
additionalEntryPoints: [],
|
|
120
|
+
verbose: true,
|
|
121
|
+
sourceMap: 'eval-cheap-module-source-map',
|
|
122
|
+
mergeExternals: true,
|
|
123
|
+
externalDependencies: [],
|
|
124
|
+
memoryLimit,
|
|
125
|
+
tsConfig,
|
|
126
|
+
assets,
|
|
127
|
+
optimization: false,
|
|
128
|
+
progress: false,
|
|
129
|
+
outputHashing: 'none',
|
|
130
|
+
generatePackageJson: false,
|
|
131
|
+
watchDependencies: true,
|
|
132
|
+
typeCheckOptions: {
|
|
133
|
+
async: true,
|
|
134
|
+
},
|
|
135
|
+
buildLibsFromSource,
|
|
136
|
+
}),
|
|
137
|
+
new DevServerReloadPlugin(port),
|
|
138
|
+
],
|
|
139
|
+
snapshot: { managedPaths: [/^(.+?[\\/])?node_modules[\\/]/] },
|
|
140
|
+
watch: true,
|
|
141
|
+
watchOptions: {
|
|
142
|
+
ignored: ['**/*.env.template', '**/config.template.json', '**/*.md', '**/dist/**', '**/migrations/**'],
|
|
143
|
+
},
|
|
144
|
+
cache: { type: 'filesystem' },
|
|
145
|
+
};
|
|
146
|
+
// Apply user webpack overrides if configured
|
|
147
|
+
if (webpackConfigPath) {
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
149
|
+
const overrideModule = require(path.resolve(appRoot, webpackConfigPath));
|
|
150
|
+
const overrideFn = overrideModule.default || overrideModule;
|
|
151
|
+
return overrideFn(config);
|
|
152
|
+
}
|
|
153
|
+
return config;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=create-webpack-dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-webpack-dev.js","sourceRoot":"","sources":["../../../libs/webpack/src/create-webpack-dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
type Configuration = Record<string, any>;
|
|
2
|
+
export interface NodeExternalsConfig {
|
|
3
|
+
allowlist?: (string | RegExp)[];
|
|
4
|
+
additionalModuleDirs?: string[];
|
|
5
|
+
importType?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ProdWebpackOptions {
|
|
8
|
+
appName: string;
|
|
9
|
+
appRoot: string;
|
|
10
|
+
outputDir: string;
|
|
11
|
+
main: string;
|
|
12
|
+
tsConfig: string;
|
|
13
|
+
workspaceRoot: string;
|
|
14
|
+
assets?: string[];
|
|
15
|
+
additionalEntryPoints?: Array<{
|
|
16
|
+
entryName: string;
|
|
17
|
+
entryPath: string;
|
|
18
|
+
}>;
|
|
19
|
+
runtimeDependencies?: string[];
|
|
20
|
+
memoryLimit?: number;
|
|
21
|
+
generatePackageJson?: boolean;
|
|
22
|
+
buildLibsFromSource?: boolean;
|
|
23
|
+
ormConfigPath?: string;
|
|
24
|
+
migrationsDir?: string;
|
|
25
|
+
orgScopes?: string[];
|
|
26
|
+
bundlePackages?: string[];
|
|
27
|
+
nodeExternalsConfig?: NodeExternalsConfig;
|
|
28
|
+
webpackConfigPath?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function createProdWebpackConfig(options: ProdWebpackOptions): Configuration[];
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=create-webpack-prod.d.ts.map
|