@razerspine/webpack-core 1.7.1 → 1.8.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,7 +8,61 @@ required to ensure correct behavior in both development and production modes.
8
8
 
9
9
  ---
10
10
 
11
- ## [1.7.0] - 2026-02-20
11
+ ## [1.8.0] - 2026-03-13
12
+
13
+ ### Added
14
+
15
+ - **Automated Deployment Assets Generation**
16
+ - Integrated `RoutingPlugin` into `createProdConfig` to handle host-specific routing files.
17
+ - **Vercel Support**: Automatically generates `vercel.json` with correct rewrite rules based on `appType`.
18
+ - **Netlify/Cloudflare Support**: Automatically generates `_redirects` file.
19
+ - **Zero-Config Deployment**: Routing files are generated in-memory during the build and emitted directly to the
20
+ `dist` folder.
21
+ - **Enhanced SPA Fallback**
22
+ - Added automatic generation of `404.html` (as a copy of `index.html`) for SPA mode.
23
+ - Ensures seamless routing on platforms like **GitHub Pages** without manual configuration.
24
+
25
+ ### Fixed
26
+
27
+ - **Type Safety**: Improved Webpack 5 internal typing for asset emission using `sources.RawSource`.
28
+ - **Build Reliability**: Replaced `copy-webpack-plugin` for generated assets with a native Webpack emission strategy to
29
+ prevent "file not found" errors during build.
30
+
31
+ ### Changed
32
+
33
+ - **Production Alignment**: `createProdConfig` now actively reads `_meta.appType` from `LoaderOptionsPlugin` to
34
+ synchronize routing logic with the development server.
35
+
36
+ ---
37
+
38
+ ## [1.7.2] - 2026-02-22
39
+
40
+ ### Added
41
+
42
+ - **Universal Pug Loading Strategy**
43
+ - Introduced `pugRule()` with `oneOf` logic to handle different Pug contexts.
44
+ - **Component Support**: Pug files imported via JS/TS are now compiled into functions (`method: 'compile'`), enabling
45
+ Angular-like component architecture.
46
+ - **Static Entry Support**: Pug files used as entry points continue to render as static HTML (`method: 'render'`).
47
+ - This dual-mode approach ensures SPA components work seamlessly without breaking existing MPA templates.
48
+ - **Dynamic SPA Routing Infrastructure**
49
+ - Added support for client-side routing by decoupling Pug templates from the global layout in SPA mode.
50
+ - Enabled support for `document.title` updates and `data-link` interception within the starter templates.
51
+
52
+ ### Changed
53
+
54
+ - **Refactored** `templatesLoader`
55
+ - Decoupled loader logic from the `PugPlugin` instance.
56
+ - Removed global `loaderOptions` from `PugPlugin` to delegate responsibility to the new specialized `pugRule()`.
57
+ - Improved compatibility between dynamic imports and static page generation.
58
+ - **Clean Architecture Alignment**
59
+ - Updated `base.ts` to include `pugRule()` in `module.rules`, establishing a standard for how assets are resolved
60
+ across all 8
61
+ - template variations (JS/TS, SCSS/Less, MPA/SPA).
62
+
63
+ ---
64
+
65
+ ## [1.7.1] - 2026-02-22
12
66
 
13
67
  ### Added
14
68
 
package/README.md CHANGED
@@ -29,12 +29,14 @@ Can be used independently in any Pug-based project.
29
29
  - Recursive file watching (`src/**/*`)
30
30
  - SPA-friendly dev server
31
31
  - Config validation layer
32
- - Centralized options normalization (v1.7.0+)
32
+ - Centralized options normalization (v1.7.1+)
33
33
  - Fully customizable dev & prod configs
34
+ - **New (v1.8.0) Automatic Deployment Configs**: Generates `_redirects` and `vercel.json` automatically.
35
+ - **New (v1.8.0) GitHub Pages SPA Support**: Automatic `404.html` fallback for single-page apps.
34
36
 
35
37
  ---
36
38
 
37
- ## Application Modes (v1.7.0+)
39
+ ## Application Modes (v1.7.1+)
38
40
 
39
41
  ### MPA (Default)
40
42
 
@@ -63,10 +65,10 @@ appType: 'spa'
63
65
  - **Webpack is responsible for**: module resolution, aliases (`resolve.alias`), and asset handling.
64
66
  - **Template-driven architecture**: Webpack JS entry is intentionally disabled. Builds are driven by Pug template entries.
65
67
  - **MPA by default**: Directory-based page generation remains the primary mode.
66
- - **Optional SPA support (v1.7.0+)**: Single-entry template mode is supported without breaking MPA workflow.
68
+ - **Optional SPA support (v1.7.1+)**: Single-entry template mode is supported without breaking MPA workflow.
67
69
  - **Stability-first production defaults**: No aggressive optimizations (e.g. `splitChunks`) are enabled by default to prevent template asset resolution issues.
68
70
  - **Validated configuration layer**: Core options are validated before Webpack initialization.
69
- - **Centralized option normalization (v1.7.0+)**: Default resolution is handled internally through a normalization layer to avoid configuration drift.
71
+ - **Centralized option normalization (v1.7.1+)**: Default resolution is handled internally through a normalization layer to avoid configuration drift.
70
72
  - **Flexible overrides**: Dev and Prod configs can be extended safely via optional parameters.
71
73
 
72
74
  ---
@@ -163,7 +165,7 @@ if (mode === 'production') {
163
165
  - No implicit webpack JS entry
164
166
  - No aggressive production optimizations by default
165
167
  - Options validated before build initialization
166
- - Defaults resolved through a normalization layer (v1.7.0+)
168
+ - Defaults resolved through a normalization layer (v1.7.1+)
167
169
 
168
170
  ---
169
171
 
@@ -203,7 +205,11 @@ All options are validated before initialization.
203
205
 
204
206
  - `baseConfig`: The configuration returned by createBaseConfig.
205
207
  - `options`: (Optional) Webpack configuration object for production overrides.
206
- - **Default behavior**: Enables source maps, minification, and disables `splitChunks` for template compatibility.
208
+ - **Default behavior**:
209
+ - Enables source maps and minification.
210
+ - Disables `splitChunks` for template compatibility.
211
+ - **New**: Generates routing assets (`_redirects`, `vercel.json`) based on `appType`.
212
+ - **New**: Creates `404.html` fallback for SPA mode.
207
213
 
208
214
  ---
209
215
 
@@ -65,6 +65,21 @@ export declare function createBaseConfig(options: ConfigOptionType): {
65
65
  postcssOptions?: undefined;
66
66
  };
67
67
  })[];
68
+ } | {
69
+ test: RegExp;
70
+ oneOf: ({
71
+ issuer: RegExp;
72
+ loader: any;
73
+ options: {
74
+ method: string;
75
+ };
76
+ } | {
77
+ loader: any;
78
+ options: {
79
+ method: string;
80
+ };
81
+ issuer?: undefined;
82
+ })[];
68
83
  })[];
69
84
  };
70
85
  plugins: any[];
@@ -24,6 +24,7 @@ function createBaseConfig(options) {
24
24
  },
25
25
  module: {
26
26
  rules: [
27
+ (0, templates_1.pugRule)(),
27
28
  (0, assets_1.assetsLoader)(),
28
29
  (0, scripts_1.scriptsLoader)(normalized),
29
30
  (0, styles_1.stylesLoader)(normalized),
@@ -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,48 @@
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
+ function getRedirects(appType) {
7
+ return appType === 'spa'
8
+ ? '/* /index.html 200\n'
9
+ : '/* /404.html 404\n';
10
+ }
11
+ function getVercelConfig(appType) {
12
+ const config = appType === 'spa'
13
+ ? { routes: [{ src: '/(.*)', dest: '/index.html' }] }
14
+ : {
15
+ routes: [
16
+ { handle: 'filesystem' },
17
+ { src: '/(.*)', dest: '/404.html', status: 404 }
18
+ ]
19
+ };
20
+ return JSON.stringify(config, null, 2);
21
+ }
5
22
  function createProdConfig(baseConfig, options = {}) {
23
+ var _a, _b, _c, _d, _e;
24
+ const loaderPlugin = (_a = baseConfig.plugins) === null || _a === void 0 ? void 0 : _a.find((p) => p instanceof webpack_1.LoaderOptionsPlugin);
25
+ 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';
26
+ const routingPlugin = {
27
+ apply(compiler) {
28
+ compiler.hooks.thisCompilation.tap('RoutingPlugin', (compilation) => {
29
+ compilation.hooks.processAssets.tap({
30
+ name: 'RoutingPlugin',
31
+ stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
32
+ }, () => {
33
+ const { RawSource } = webpack_1.sources;
34
+ compilation.emitAsset('_redirects', new RawSource(getRedirects(appType)));
35
+ compilation.emitAsset('vercel.json', new RawSource(getVercelConfig(appType)));
36
+ if (appType === 'spa') {
37
+ const indexAsset = compilation.getAsset('index.html');
38
+ if (indexAsset) {
39
+ compilation.emitAsset('404.html', indexAsset.source);
40
+ }
41
+ }
42
+ });
43
+ });
44
+ },
45
+ };
6
46
  const defaultConfig = {
7
47
  devtool: 'source-map',
8
48
  optimization: {
@@ -13,6 +53,7 @@ function createProdConfig(baseConfig, options = {}) {
13
53
  performance: {
14
54
  hints: false,
15
55
  },
56
+ plugins: [routingPlugin],
16
57
  };
17
58
  return (0, webpack_merge_1.merge)(baseConfig, defaultConfig, options);
18
59
  }
@@ -1,5 +1,21 @@
1
1
  import { ModeType } from '../types/mode-type';
2
2
  import { AppType } from '../types/app-type';
3
+ export declare function pugRule(): {
4
+ test: RegExp;
5
+ oneOf: ({
6
+ issuer: RegExp;
7
+ loader: any;
8
+ options: {
9
+ method: string;
10
+ };
11
+ } | {
12
+ loader: any;
13
+ options: {
14
+ method: string;
15
+ };
16
+ issuer?: undefined;
17
+ })[];
18
+ };
3
19
  export declare function templatesLoader(options: {
4
20
  entry: string;
5
21
  mode: ModeType;
@@ -3,9 +3,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.pugRule = pugRule;
6
7
  exports.templatesLoader = templatesLoader;
7
8
  const pug_plugin_1 = __importDefault(require("pug-plugin"));
8
9
  const fs_1 = __importDefault(require("fs"));
10
+ function pugRule() {
11
+ return {
12
+ test: /\.pug$/,
13
+ oneOf: [
14
+ {
15
+ issuer: /\.(js|ts|tsx|jsx)$/,
16
+ loader: pug_plugin_1.default.loader,
17
+ options: {
18
+ method: 'compile',
19
+ },
20
+ },
21
+ {
22
+ loader: pug_plugin_1.default.loader,
23
+ options: {
24
+ method: 'render',
25
+ },
26
+ },
27
+ ],
28
+ };
29
+ }
9
30
  function templatesLoader(options) {
10
31
  const { entry, appType } = options;
11
32
  if (!fs_1.default.existsSync(entry)) {
@@ -22,9 +43,6 @@ function templatesLoader(options) {
22
43
  return [
23
44
  new pug_plugin_1.default({
24
45
  entry: pluginEntry,
25
- loaderOptions: {
26
- method: 'compile'
27
- },
28
46
  filename: ({ chunk }) => {
29
47
  if (appType === 'spa') {
30
48
  return 'index.html';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razerspine/webpack-core",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "description": "Core webpack config and loaders for starter templates",
5
5
  "keywords": [
6
6
  "webpack",