@razerspine/webpack-core 1.7.2 → 1.9.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/CHANGELOG.md CHANGED
@@ -8,6 +8,57 @@ required to ensure correct behavior in both development and production modes.
8
8
 
9
9
  ---
10
10
 
11
+ ## [1.9.0] - 2026-03-13
12
+
13
+ ### Added
14
+ - **Smart Auto-Hosting Adapter**
15
+ - Integrated `detectHosting()` utility to automatically identify deployment platforms (**Vercel, Netlify, Cloudflare, GitHub Pages**).
16
+ - **Zero-Config Routing**: Automatically generates platform-specific configuration files (`_redirects`, `vercel.json`) based on `appType`.
17
+ - **Interactive Build Logs**: Added `infrastructureLogger` integration. The build now informs the developer about detected platforms (e.g., `📦 Netlify detected. Generating _redirects for SPA...`).
18
+ - **Enhanced SPA Fallback Strategy**
19
+ - Automated `404.html` generation for **GitHub Pages** and static hosts when in SPA mode.
20
+ - Ensures seamless client-side routing without manual file duplication.
21
+
22
+ ### Changed
23
+ - **Architectural Refactoring**
24
+ - Decoupled hosting logic into specialized utilities: `getRedirects`, `getVercelConfig`, and `detectHosting`.
25
+ - Improved `createProdConfig` maintainability by moving business logic out of the main configuration factory.
26
+ - **Production Alignment**
27
+ - `createProdConfig` now actively reads `_meta.appType` from `LoaderOptionsPlugin` to synchronize routing logic with the development server.
28
+
29
+ ### Fixed
30
+ - **Type Safety**: Improved Webpack 5 internal typing for asset emission using `sources.RawSource`.
31
+ - **Build Reliability**: Replaced `copy-webpack-plugin` for generated assets with a native Webpack emission strategy to prevent "file not found" errors during build.
32
+
33
+ ---
34
+
35
+ ## [1.8.0] - 2026-03-13
36
+
37
+ ### Added
38
+
39
+ - **Automated Deployment Assets Generation**
40
+ - Integrated `RoutingPlugin` into `createProdConfig` to handle host-specific routing files.
41
+ - **Vercel Support**: Automatically generates `vercel.json` with correct rewrite rules based on `appType`.
42
+ - **Netlify/Cloudflare Support**: Automatically generates `_redirects` file.
43
+ - **Zero-Config Deployment**: Routing files are generated in-memory during the build and emitted directly to the
44
+ `dist` folder.
45
+ - **Enhanced SPA Fallback**
46
+ - Added automatic generation of `404.html` (as a copy of `index.html`) for SPA mode.
47
+ - Ensures seamless routing on platforms like **GitHub Pages** without manual configuration.
48
+
49
+ ### Fixed
50
+
51
+ - **Type Safety**: Improved Webpack 5 internal typing for asset emission using `sources.RawSource`.
52
+ - **Build Reliability**: Replaced `copy-webpack-plugin` for generated assets with a native Webpack emission strategy to
53
+ prevent "file not found" errors during build.
54
+
55
+ ### Changed
56
+
57
+ - **Production Alignment**: `createProdConfig` now actively reads `_meta.appType` from `LoaderOptionsPlugin` to
58
+ synchronize routing logic with the development server.
59
+
60
+ ---
61
+
11
62
  ## [1.7.2] - 2026-02-22
12
63
 
13
64
  ### Added
@@ -29,7 +80,8 @@ required to ensure correct behavior in both development and production modes.
29
80
  - Removed global `loaderOptions` from `PugPlugin` to delegate responsibility to the new specialized `pugRule()`.
30
81
  - Improved compatibility between dynamic imports and static page generation.
31
82
  - **Clean Architecture Alignment**
32
- - Updated `base.ts` to include `pugRule()` in `module.rules`, establishing a standard for how assets are resolved across all 8
83
+ - Updated `base.ts` to include `pugRule()` in `module.rules`, establishing a standard for how assets are resolved
84
+ across all 8
33
85
  - template variations (JS/TS, SCSS/Less, MPA/SPA).
34
86
 
35
87
  ---
package/README.md CHANGED
@@ -1,90 +1,62 @@
1
1
  # @razerspine/webpack-core
2
+
2
3
  [![npm version](https://img.shields.io/npm/v/@razerspine/webpack-core.svg)](https://www.npmjs.com/package/@razerspine/webpack-core)
3
4
  [![changelog](https://img.shields.io/badge/docs-changelog-blue.svg)](./CHANGELOG.md)
4
5
  [![license](https://img.shields.io/npm/l/@razerspine/webpack-core.svg)](./LICENSE)
5
6
 
6
-
7
7
  Core webpack configuration and loaders for **Pug-based** projects.
8
8
 
9
- This package provides a stable, production-safe webpack foundation for
10
- template-driven builds using `pug-plugin`.
9
+ This package provides a stable, production-safe webpack foundation for template-driven builds using `pug-plugin`, now
10
+ with **Smart Auto-Hosting** support.
11
11
 
12
12
  ---
13
13
 
14
- ## Designed for
15
-
16
- Part of the
17
- [Webpack Starter Monorepo](https://github.com/Razerspine/webpack-starter-monorepo).
14
+ ## 🚀 Key Features
18
15
 
19
- Can be used independently in any Pug-based project.
16
+ - **Pug template-driven builds**: Webpack JS entry is intentionally disabled.
17
+ - **Hybrid Modes**: Full support for Multi-page (MPA) and Single-page (SPA) architectures.
18
+ - **Smart Auto-Hosting (v1.9.0)**: Automatically detects **Vercel, Netlify, Cloudflare**, and **GitHub Pages** to
19
+ generate required routing configs.
20
+ - **Zero-Config SPA Fallback**: Automatic `404.html` generation for GitHub Pages to fix client-side routing.
21
+ - **Full Tech Stack**: Native support for TypeScript/JavaScript and SCSS/Less.
22
+ - **Developer Experience**: Recursive file watching (`src/**/*`), auto-browser open, and infrastructure logging.
23
+ - **Validation Layer**: Core options are validated and normalized before Webpack initialization.
20
24
 
21
25
  ---
22
26
 
23
- ## Key Features
24
-
25
- - Pug template-driven builds (no implicit JS entry)
26
- - Multi-page (MPA) and Single-page (SPA) modes
27
- - JavaScript or TypeScript support
28
- - SCSS or Less support
29
- - Recursive file watching (`src/**/*`)
30
- - SPA-friendly dev server
31
- - Config validation layer
32
- - Centralized options normalization (v1.7.1+)
33
- - Fully customizable dev & prod configs
34
-
35
- ---
36
-
37
- ## Application Modes (v1.7.1+)
27
+ ## 🛠 Application Modes
38
28
 
39
29
  ### MPA (Default)
40
30
 
41
- ```js
42
- appType: 'mpa'
43
- ```
31
+ `appType: 'mpa'`
44
32
 
45
- - `templates.entry` must be a directory
46
- - Example: `src/views/pages`
47
- - Each page generates its own HTML file
33
+ - `templates.entry` must be a **directory** (e.g., `src/views/pages`).
34
+ - Each Pug file in the directory generates its own HTML file.
48
35
 
49
36
  ### SPA
50
37
 
51
- ```js
52
- appType: 'spa'
53
- ```
38
+ `appType: 'spa'`
54
39
 
55
- - `templates.entry` must be a single Pug file
56
- - Example: `src/views/app.pug`
57
- - Always outputs: `index.html`
40
+ - `templates.entry` must be a **single Pug file** (e.g., `src/app/app.pug`).
41
+ - Always outputs `index.html`.
42
+ - Enables automatic routing configuration for production hosting.
58
43
 
59
44
  ---
60
45
 
61
- ## Design Principles
62
-
63
- - **Webpack is responsible for**: module resolution, aliases (`resolve.alias`), and asset handling.
64
- - **Template-driven architecture**: Webpack JS entry is intentionally disabled. Builds are driven by Pug template entries.
65
- - **MPA by default**: Directory-based page generation remains the primary mode.
66
- - **Optional SPA support (v1.7.1+)**: Single-entry template mode is supported without breaking MPA workflow.
67
- - **Stability-first production defaults**: No aggressive optimizations (e.g. `splitChunks`) are enabled by default to prevent template asset resolution issues.
68
- - **Validated configuration layer**: Core options are validated before Webpack initialization.
69
- - **Centralized option normalization (v1.7.1+)**: Default resolution is handled internally through a normalization layer to avoid configuration drift.
70
- - **Flexible overrides**: Dev and Prod configs can be extended safely via optional parameters.
71
-
72
- ---
46
+ ## 🌍 Smart Hosting Adapter (New v1.9.0)
73
47
 
74
- ## Features
48
+ The core now detects the environment during the production build and emits the necessary configuration files:
75
49
 
76
- - **Pug templates support** with auto-discovery.
77
- - **JavaScript / TypeScript** integration.
78
- - **SCSS / Less** styling support.
79
- - **Recursive File Watching**: Dev server watches all changes in `src/**/*`.
80
- - **SPA-friendly Dev Server**: Integrated historyApiFallback (redirects to 404.html).
81
- - **Customizable**: Easily override devServer or optimization settings.
82
- - **Configuration validation layer**
83
- - **Automatic browser open in development (v1.2.2+)**
50
+ | Platform | Generated File | Purpose |
51
+ |:-------------------------|:---------------|:-------------------------------------------------------------|
52
+ | **Netlify / Cloudflare** | `_redirects` | Handles SPA rewrites and MPA fallbacks. |
53
+ | **Vercel** | `vercel.json` | Configures Vercel Edge Network routing. |
54
+ | **GitHub Pages** | `404.html` | Duplicates `index.html` to prevent 404 errors on deep links. |
55
+ | **Static / Others** | `404.html` | Generic fallback for SPA mode. |
84
56
 
85
57
  ---
86
58
 
87
- ## Installation
59
+ ## 📦 Installation
88
60
 
89
61
  ```bash
90
62
  npm install @razerspine/webpack-core
@@ -92,7 +64,7 @@ npm install @razerspine/webpack-core
92
64
 
93
65
  ---
94
66
 
95
- ## Usage
67
+ ## 📖 Usage
96
68
 
97
69
  ### Basic Setup
98
70
 
@@ -105,20 +77,20 @@ const {
105
77
  } = require('@razerspine/webpack-core');
106
78
 
107
79
  module.exports = (env = {}, argv = {}) => {
108
- const mode = argv.mode || 'development';
80
+ const mode = argv.mode || process.env.NODE_ENV || 'development';
109
81
 
110
82
  const baseConfig = createBaseConfig({
111
83
  mode,
112
- appType: 'mpa', // or 'spa'
113
- scripts: 'js', // or 'ts'
114
- styles: 'scss', // or 'less'
84
+ appType: 'spa', // 'spa' or 'mpa'
85
+ scripts: 'ts', // 'js' or 'ts'
86
+ styles: 'scss', // 'scss' or 'less'
115
87
  templates: {
116
- entry: 'src/views/pages',
88
+ entry: 'src/app/app.pug',
117
89
  },
118
90
  resolve: {
119
91
  alias: {
120
- '@views': path.resolve(process.cwd(), 'src/views'),
121
- '@styles': path.resolve(process.cwd(), 'src/assets/styles'),
92
+ '@app': path.resolve(process.cwd(), 'src/app'),
93
+ '@styles': path.resolve(process.cwd(), 'src/styles'),
122
94
  },
123
95
  },
124
96
  });
@@ -131,21 +103,20 @@ module.exports = (env = {}, argv = {}) => {
131
103
  };
132
104
  ```
133
105
 
134
- ### Customizing Configuration (v1.2.1+)
106
+ ### Customizing Configuration
135
107
 
136
- You can now pass an optional second argument to `createDevConfig` and `createProdConfig` to override defaults:
108
+ You can override any default setting by passing an object as the second argument:
137
109
 
138
110
  ```js
139
- // Customizing the Dev Server (port, open browser, etc.)
111
+ // Customizing the Dev Server
140
112
  if (mode === 'development') {
141
113
  return createDevConfig(baseConfig, {
142
114
  port: 3000,
143
115
  open: true,
144
- // extra devServer options...
145
116
  });
146
117
  }
147
118
 
148
- // Customizing Production (minification, performance hints, etc.)
119
+ // Customizing Production optimizations
149
120
  if (mode === 'production') {
150
121
  return createProdConfig(baseConfig, {
151
122
  performance: {
@@ -157,53 +128,13 @@ if (mode === 'production') {
157
128
 
158
129
  ---
159
130
 
160
- ## Architecture Principles
161
- - Webpack handles module resolution and asset processing
162
- - PugPlugin handles template compilation
163
- - No implicit webpack JS entry
164
- - No aggressive production optimizations by default
165
- - Options validated before build initialization
166
- - Defaults resolved through a normalization layer (v1.7.1+)
167
-
168
- ---
169
-
170
- ## Stability
171
-
172
- Versions prior to 1.1.6 were part of a stabilization phase and are not recommended for production use.
173
-
174
- ---
175
-
176
- ## API Reference
177
-
178
- `createBaseConfig(options)`
179
-
180
- Core configuration factory.
181
-
182
- **Options include**:
183
-
184
- - `mode` — `'development' | 'production'`
185
- - `scripts` — `'js' | 'ts'`
186
- - `styles` — `'scss' | 'less'`
187
- - `templates.entry` — Path to template pages directory
188
- - `resolve.alias` — Webpack aliases
189
-
190
- All options are validated before initialization.
191
-
192
- ---
193
-
194
- `createDevConfig(baseConfig, options?)`
195
-
196
- - `baseConfig`: The configuration returned by createBaseConfig.
197
- - `options`: (Optional) webpack-dev-server configuration object.
198
- - **Default behavior**: Watches `src/**/*`, uses port `8080`, and rewrites 404s to `/404.html`.
199
-
200
- ---
201
-
202
- `createProdConfig(baseConfig, options?)`
131
+ ## 🏗 Architecture Principles
203
132
 
204
- - `baseConfig`: The configuration returned by createBaseConfig.
205
- - `options`: (Optional) Webpack configuration object for production overrides.
206
- - **Default behavior**: Enables source maps, minification, and disables `splitChunks` for template compatibility.
133
+ - **Template-First**: Webpack handles assets, but Pug templates drive the entry points.
134
+ - **Stability-First**: Aggressive optimizations (like `splitChunks`) are disabled by default to ensure reliable asset
135
+ resolution in templates.
136
+ - **Environment Aware**: The build process is aware of CI/CD environments and adapts output artifacts accordingly.
137
+ - **Type Safe**: Improved internal typing for Webpack 5 asset emission.
207
138
 
208
139
  ---
209
140
 
@@ -1,2 +1,2 @@
1
- import type { Configuration } from 'webpack';
1
+ import { Configuration } from 'webpack';
2
2
  export declare function createProdConfig(baseConfig: Configuration, options?: Configuration): Configuration;
@@ -1,8 +1,59 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createProdConfig = createProdConfig;
4
+ const webpack_1 = require("webpack");
4
5
  const webpack_merge_1 = require("webpack-merge");
6
+ const detect_hosting_1 = require("../utils/detect-hosting");
7
+ const get_vercel_config_1 = require("../utils/get-vercel-config");
8
+ const get_redirects_1 = require("../utils/get-redirects");
5
9
  function createProdConfig(baseConfig, options = {}) {
10
+ var _a, _b, _c, _d, _e;
11
+ const loaderPlugin = (_a = baseConfig.plugins) === null || _a === void 0 ? void 0 : _a.find((p) => p instanceof webpack_1.LoaderOptionsPlugin);
12
+ const appType = (_e = (_d = (_c = (_b = loaderPlugin === null || loaderPlugin === void 0 ? void 0 : loaderPlugin.options) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c._meta) === null || _d === void 0 ? void 0 : _d.appType) !== null && _e !== void 0 ? _e : 'mpa';
13
+ const hosting = (0, detect_hosting_1.detectHosting)();
14
+ const routingPlugin = {
15
+ apply(compiler) {
16
+ const logger = compiler.getInfrastructureLogger('@razerspine/webpack-core');
17
+ compiler.hooks.thisCompilation.tap('RoutingPlugin', (compilation) => {
18
+ compilation.hooks.processAssets.tap({
19
+ name: 'RoutingPlugin',
20
+ stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
21
+ }, () => {
22
+ /**
23
+ * Netlify / Cloudflare
24
+ */
25
+ if (hosting === 'netlify' || hosting === 'cloudflare') {
26
+ logger.info(`📦 ${hosting.charAt(0).toUpperCase() + hosting.slice(1)} detected. Generating _redirects for ${appType.toUpperCase()}...`);
27
+ compilation.emitAsset('_redirects', new webpack_1.sources.RawSource((0, get_redirects_1.getRedirects)(appType)));
28
+ }
29
+ /**
30
+ * Vercel
31
+ */
32
+ if (hosting === 'vercel') {
33
+ logger.info(`📦 Vercel detected. Generating vercel.json for ${appType.toUpperCase()}...`);
34
+ compilation.emitAsset('vercel.json', new webpack_1.sources.RawSource((0, get_vercel_config_1.getVercelConfig)(appType)));
35
+ }
36
+ /**
37
+ * SPA fallback
38
+ * Needed for:
39
+ * - GitHub Pages
40
+ * - static hosting
41
+ */
42
+ if (appType === 'spa') {
43
+ const indexAsset = compilation.getAsset('index.html');
44
+ if (indexAsset) {
45
+ const source = indexAsset.source.source().toString();
46
+ if (hosting === 'github' || hosting === 'static') {
47
+ const hostName = hosting === 'github' ? 'GitHub Pages' : 'Static hosting';
48
+ logger.info(`📦 ${hostName} detected. Creating 404.html fallback for SPA...`);
49
+ compilation.emitAsset('404.html', new webpack_1.sources.RawSource(source));
50
+ }
51
+ }
52
+ }
53
+ });
54
+ });
55
+ },
56
+ };
6
57
  const defaultConfig = {
7
58
  devtool: 'source-map',
8
59
  optimization: {
@@ -13,6 +64,7 @@ function createProdConfig(baseConfig, options = {}) {
13
64
  performance: {
14
65
  hints: false,
15
66
  },
67
+ plugins: [routingPlugin],
16
68
  };
17
69
  return (0, webpack_merge_1.merge)(baseConfig, defaultConfig, options);
18
70
  }
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@ export * from './types/style-type';
7
7
  export * from './types/app-type';
8
8
  export * from './types/config-option-type';
9
9
  export * from './types/base-webpack-config-type';
10
+ export * from './types/hosting-type';
package/dist/index.js CHANGED
@@ -27,3 +27,4 @@ __exportStar(require("./types/style-type"), exports);
27
27
  __exportStar(require("./types/app-type"), exports);
28
28
  __exportStar(require("./types/config-option-type"), exports);
29
29
  __exportStar(require("./types/base-webpack-config-type"), exports);
30
+ __exportStar(require("./types/hosting-type"), exports);
@@ -0,0 +1 @@
1
+ export type HostingType = 'netlify' | 'vercel' | 'cloudflare' | 'github' | 'static';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import { HostingType } from '../types/hosting-type';
2
+ export declare function detectHosting(): HostingType;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectHosting = detectHosting;
4
+ function detectHosting() {
5
+ if (process.env.NETLIFY)
6
+ return 'netlify';
7
+ if (process.env.VERCEL)
8
+ return 'vercel';
9
+ if (process.env.CF_PAGES)
10
+ return 'cloudflare';
11
+ if (process.env.GITHUB_ACTIONS)
12
+ return 'github';
13
+ return 'static';
14
+ }
@@ -0,0 +1,2 @@
1
+ import { AppType } from '../types/app-type';
2
+ export declare function getRedirects(appType: AppType): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRedirects = getRedirects;
4
+ function getRedirects(appType) {
5
+ return appType === 'spa'
6
+ ? '/* /index.html 200\n'
7
+ : '/* /404.html 404\n';
8
+ }
@@ -0,0 +1,2 @@
1
+ import { AppType } from '../types/app-type';
2
+ export declare function getVercelConfig(appType: AppType): string;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVercelConfig = getVercelConfig;
4
+ function getVercelConfig(appType) {
5
+ const config = appType === 'spa'
6
+ ? {
7
+ routes: [
8
+ {
9
+ src: '/(.*)',
10
+ dest: '/index.html',
11
+ },
12
+ ],
13
+ }
14
+ : {
15
+ routes: [
16
+ {
17
+ handle: 'filesystem'
18
+ },
19
+ {
20
+ src: '/(.*)',
21
+ dest: '/404.html',
22
+ status: 404,
23
+ },
24
+ ],
25
+ };
26
+ return JSON.stringify(config, null, 2);
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razerspine/webpack-core",
3
- "version": "1.7.2",
3
+ "version": "1.9.0",
4
4
  "description": "Core webpack config and loaders for starter templates",
5
5
  "keywords": [
6
6
  "webpack",