@djangocfg/nextjs 2.1.516 → 2.1.519

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/src/pwa/plugin.ts CHANGED
@@ -1,215 +1,129 @@
1
1
  /**
2
- * PWA (Progressive Web App) Plugin
2
+ * PWA (Progressive Web App) Plugin — dependency-free.
3
3
  *
4
- * Configures Serwist for service worker and offline support
5
- * Modern PWA solution for Next.js 15+ with App Router
4
+ * History: this used to wrap `@serwist/next`. Serwist is a **webpack** plugin,
5
+ * and Next.js 16 defaults to Turbopack, which does not run webpack loaders and
6
+ * chokes on serwist's `fileURLToPath(new URL(".", import.meta.url))` during
7
+ * static tracing — failing the whole build even when PWA was never enabled
8
+ * (the mere `require('@serwist/next')` reference was enough). Since no app in
9
+ * this monorepo actually turned PWA on (`withPWA` is opt-in and unused), we
10
+ * dropped serwist entirely.
6
11
  *
7
- * @see https://serwist.pages.dev/
12
+ * What remains:
13
+ * - `createManifest` (in `./manifest`) — the web app manifest, which Next.js
14
+ * supports natively via `app/manifest.ts`; needs no library at all.
15
+ * - `withPWA` — a thin, Turbopack-safe pass-through kept for API stability.
16
+ * - `getServiceWorkerTemplate` — a vanilla service worker you can drop into
17
+ * `app/sw.ts`, no framework runtime required.
18
+ *
19
+ * If you want a full precache/offline story back, wire a real service worker
20
+ * (the template below, or Workbox) yourself — but do it in an app, not here, so
21
+ * one app's PWA choice can't break every consumer's build.
8
22
  */
9
23
 
10
24
  import type { NextConfig } from 'next';
11
- import { consola } from 'consola';
12
- import { createRequire } from 'module';
13
-
14
- // Serwist is an optional peer loaded synchronously at config time, which
15
- // `import()` cannot do. `createRequire` is the ESM-safe equivalent of `require`.
16
- const requirePeer = createRequire(import.meta.url);
17
25
 
18
26
  export interface PWAPluginOptions {
19
27
  /**
20
- * Destination directory for service worker files
21
- * @default 'public'
22
- * @deprecated Use swDest instead
23
- */
24
- dest?: string;
25
-
26
- /**
27
- * Path to service worker source file (relative to project root)
28
+ * Path to service worker source file (relative to project root).
28
29
  * @default 'app/sw.ts'
29
30
  */
30
31
  swSrc?: string;
31
32
 
32
33
  /**
33
- * Destination for compiled service worker
34
+ * Destination for the compiled service worker.
34
35
  * @default 'public/sw.js'
35
36
  */
36
37
  swDest?: string;
37
38
 
38
39
  /**
39
- * Disable PWA completely
40
- * @default false in production, true in development
41
- * @example disable: process.env.NODE_ENV === 'development'
40
+ * Disable PWA completely.
41
+ * @default true in development / static export, false otherwise
42
42
  */
43
43
  disable?: boolean;
44
44
 
45
- /**
46
- * Cache on navigation - cache pages when navigating
47
- * @default true
48
- */
45
+ /** Cache pages on navigation. Consumed by a custom SW, if any. @default true */
49
46
  cacheOnNavigation?: boolean;
50
47
 
51
- /**
52
- * Reload app when device goes back online
53
- * @default true
54
- */
48
+ /** Reload the app when the device comes back online. @default true */
55
49
  reloadOnOnline?: boolean;
56
-
57
- /**
58
- * Additional Serwist options
59
- * @see https://serwist.pages.dev/docs/next/configuring
60
- */
61
- serwistOptions?: Record<string, any>;
62
50
  }
63
51
 
64
52
  /**
65
- * Add PWA configuration to Next.js config using Serwist
53
+ * Turbopack-safe PWA pass-through.
66
54
  *
67
- * @example Basic usage
68
- * ```ts
69
- * import { createBaseNextConfig, withPWA } from '@djangocfg/nextjs/config';
55
+ * This no longer injects a build plugin — Next.js's native manifest support
56
+ * plus a hand-written `app/sw.ts` (see {@link getServiceWorkerTemplate}) cover
57
+ * the PWA surface without a webpack-only dependency. Kept as a named export so
58
+ * existing `withPWA(config)` / `createBaseNextConfig({ pwa })` call sites keep
59
+ * type-checking and behave predictably (they return the config unchanged).
70
60
  *
71
- * const nextConfig = createBaseNextConfig({...});
72
- *
73
- * export default withPWA(nextConfig, {
74
- * swSrc: 'app/sw.ts',
75
- * disable: process.env.NODE_ENV === 'development',
76
- * });
77
- * ```
78
- *
79
- * @example Integrated with createBaseNextConfig
61
+ * @example
80
62
  * ```ts
81
63
  * import { createBaseNextConfig } from '@djangocfg/nextjs/config';
82
- *
83
- * const config = createBaseNextConfig({
84
- * pwa: {
85
- * swSrc: 'app/sw.ts',
86
- * disable: false,
87
- * },
88
- * });
89
- *
90
- * export default config;
64
+ * export default createBaseNextConfig({ pwa: { swSrc: 'app/sw.ts' } });
91
65
  * ```
92
66
  */
93
67
  export function withPWA(
94
68
  nextConfig: NextConfig,
95
- options: PWAPluginOptions = {}
69
+ _options: PWAPluginOptions = {}
96
70
  ): NextConfig {
97
- const isDev = process.env.NODE_ENV === 'development';
98
- const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';
99
-
100
- // Determine if PWA should be disabled:
101
- // - Explicitly disabled via options
102
- // - In development mode (default)
103
- // - Static build (output: 'export' doesn't support service workers)
104
- const shouldDisable = options.disable !== undefined
105
- ? options.disable
106
- : (isDev || isStaticBuild);
107
-
108
- const defaultOptions: PWAPluginOptions = {
109
- swSrc: 'app/sw.ts',
110
- swDest: 'public/sw.js',
111
- disable: shouldDisable,
112
- cacheOnNavigation: true,
113
- reloadOnOnline: true,
114
- ...options,
115
- };
116
-
117
- try {
118
- // Suppress Turbopack warning - it only applies to dev mode, not production builds
119
- // The warning is misleading when running `next build` with Turbopack
120
- // See: https://github.com/serwist/serwist/issues/54
121
- if (!process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING) {
122
- process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING = '1';
123
- }
124
-
125
- const withSerwistInit = requirePeer('@serwist/next').default;
126
-
127
- const withSerwist = withSerwistInit({
128
- swSrc: defaultOptions.swSrc,
129
- swDest: defaultOptions.swDest,
130
- disable: defaultOptions.disable,
131
- cacheOnNavigation: defaultOptions.cacheOnNavigation,
132
- reloadOnOnline: defaultOptions.reloadOnOnline,
133
- ...defaultOptions.serwistOptions,
134
- });
135
-
136
- return withSerwist(nextConfig);
137
- } catch (error) {
138
- consola.error('Failed to configure Serwist:', error);
139
- return nextConfig;
140
- }
71
+ return nextConfig;
141
72
  }
142
73
 
143
74
  /**
144
- * Get service worker template content
75
+ * Vanilla service-worker template — no library.
145
76
  *
146
- * Returns ready-to-use service worker code for app/sw.ts
77
+ * Returns ready-to-use, framework-free service worker source. Copy it into
78
+ * `app/sw.ts` (or generate it) if you want offline support. It uses only the
79
+ * standard Service Worker + Cache APIs, so it builds under Turbopack with no
80
+ * extra dependency.
147
81
  *
148
82
  * @example
149
83
  * ```ts
150
84
  * import { getServiceWorkerTemplate } from '@djangocfg/nextjs/config';
151
- *
152
- * // Copy this to your app/sw.ts file
153
- * console.log(getServiceWorkerTemplate());
85
+ * console.log(getServiceWorkerTemplate()); // → paste into app/sw.ts
154
86
  * ```
155
87
  */
156
88
  export function getServiceWorkerTemplate(): string {
157
89
  return `/**
158
- * Service Worker (Serwist)
159
- *
160
- * Modern PWA service worker using Serwist
90
+ * Service Worker (vanilla) — standard Cache + Fetch APIs, no library.
161
91
  */
162
92
 
163
- import { defaultCache } from '@serwist/next/worker';
164
- import { Serwist } from 'serwist';
165
-
93
+ /// <reference lib="webworker" />
166
94
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
95
  declare const self: any;
168
96
 
169
- const serwist = new Serwist({
170
- // Precache entries injected by Serwist build plugin
171
- precacheEntries: self.__SW_MANIFEST,
97
+ const CACHE = 'app-cache-v1';
98
+ const OFFLINE_URL = '/_offline';
172
99
 
173
- // Skip waiting - activate new SW immediately
174
- skipWaiting: true,
175
-
176
- // Take control of all clients immediately
177
- clientsClaim: true,
178
-
179
- // Enable navigation preload for faster loads
180
- navigationPreload: true,
181
-
182
- // Use default Next.js runtime caching strategies
183
- runtimeCaching: defaultCache,
100
+ // Precache the offline fallback on install.
101
+ self.addEventListener('install', (event: any) => {
102
+ event.waitUntil(
103
+ caches.open(CACHE).then((cache: Cache) => cache.addAll([OFFLINE_URL]))
104
+ );
105
+ self.skipWaiting();
106
+ });
184
107
 
185
- // Fallback pages for offline
186
- fallbacks: {
187
- entries: [
188
- {
189
- url: '/_offline',
190
- matcher({ request }) {
191
- return request.destination === 'document';
192
- },
193
- },
194
- ],
195
- },
108
+ // Drop stale caches on activate and take control immediately.
109
+ self.addEventListener('activate', (event: any) => {
110
+ event.waitUntil(
111
+ caches.keys().then((keys: string[]) =>
112
+ Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
113
+ )
114
+ );
115
+ self.clients.claim();
196
116
  });
197
117
 
198
- serwist.addEventListeners();
118
+ // Network-first for navigations, with an offline fallback.
119
+ self.addEventListener('fetch', (event: any) => {
120
+ const { request } = event;
121
+ if (request.mode !== 'navigate') return;
122
+ event.respondWith(
123
+ fetch(request).catch(() =>
124
+ caches.match(OFFLINE_URL).then((r: Response | undefined) => r ?? Response.error())
125
+ )
126
+ );
127
+ });
199
128
  `;
200
129
  }
201
-
202
- // Backward compatibility exports (deprecated)
203
- export const defaultRuntimeCaching = [];
204
- export function createApiCacheRule() {
205
- consola.warn('createApiCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');
206
- return {};
207
- }
208
- export function createStaticAssetRule() {
209
- consola.warn('createStaticAssetRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');
210
- return {};
211
- }
212
- export function createCdnCacheRule() {
213
- consola.warn('createCdnCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');
214
- return {};
215
- }
@@ -1,94 +1,80 @@
1
1
  /**
2
- * Service Worker Utilities
2
+ * Service Worker Utilities — vanilla, dependency-free.
3
3
  *
4
- * Ready-to-use Serwist configuration for Next.js PWA
4
+ * Was a Serwist wrapper; serwist is a webpack-only plugin incompatible with
5
+ * Next.js 16's Turbopack, so this is now a hand-written service worker built on
6
+ * the standard Service Worker + Cache APIs. Same `createServiceWorker(options)`
7
+ * entry point, no library, Turbopack-safe.
5
8
  */
6
9
 
7
10
  /// <reference lib="webworker" />
8
11
 
9
- import { Serwist } from 'serwist';
10
-
11
- import { defaultCache } from '@serwist/next/worker';
12
-
13
12
  export interface ServiceWorkerOptions {
14
- /**
15
- * Offline fallback URL
16
- * @default '/_offline'
17
- */
13
+ /** Offline fallback URL. @default '/_offline' */
18
14
  offlineFallback?: string;
19
-
20
- /**
21
- * Skip waiting - activate new SW immediately
22
- * @default true
23
- */
15
+ /** Activate a new SW immediately instead of waiting. @default true */
24
16
  skipWaiting?: boolean;
25
-
26
- /**
27
- * Take control of all clients immediately
28
- * @default true
29
- */
17
+ /** Take control of open clients immediately. @default true */
30
18
  clientsClaim?: boolean;
31
-
32
- /**
33
- * Enable navigation preload for faster loads
34
- * @default true
35
- */
36
- navigationPreload?: boolean;
19
+ /** Name of the runtime cache bucket. @default 'app-cache-v1' */
20
+ cacheName?: string;
37
21
  }
38
22
 
39
23
  /**
40
- * Create and initialize Serwist service worker
24
+ * Register a minimal offline-capable service worker.
25
+ *
26
+ * Network-first for navigations with an offline fallback page; stale caches are
27
+ * cleared on activate. No precache manifest (that was a serwist build-time
28
+ * injection) — add your own `cache.addAll([...])` in the install step if you
29
+ * need assets precached.
41
30
  *
42
31
  * @example
43
32
  * ```ts
44
33
  * // app/sw.ts
45
34
  * import { createServiceWorker } from '@djangocfg/nextjs/worker';
46
- *
47
- * createServiceWorker({
48
- * offlineFallback: '/_offline',
49
- * });
35
+ * createServiceWorker({ offlineFallback: '/_offline' });
50
36
  * ```
51
37
  */
52
- export function createServiceWorker(options: ServiceWorkerOptions = {}) {
38
+ export function createServiceWorker(options: ServiceWorkerOptions = {}): void {
53
39
  const {
54
40
  offlineFallback = '/_offline',
55
41
  skipWaiting = true,
56
42
  clientsClaim = true,
57
- navigationPreload = true,
43
+ cacheName = 'app-cache-v1',
58
44
  } = options;
59
45
 
60
46
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
- const self = globalThis as any;
62
- console.log('SW: Worker Initialized 🚀');
47
+ const sw = self as any;
63
48
 
64
- const serwist = new Serwist({
65
- // Precache entries injected by Serwist build plugin
66
- precacheEntries: self.__SW_MANIFEST,
67
-
68
- // Skip waiting - activate new SW immediately
69
- skipWaiting,
70
-
71
- // Take control of all clients immediately
72
- clientsClaim,
73
-
74
- // Enable navigation preload for faster loads
75
- navigationPreload,
76
-
77
- // Use default Next.js runtime caching strategies
78
- runtimeCaching: defaultCache,
49
+ sw.addEventListener('install', (event: any) => {
50
+ event.waitUntil(
51
+ caches.open(cacheName).then((cache: Cache) => cache.addAll([offlineFallback]))
52
+ );
53
+ if (skipWaiting) sw.skipWaiting();
54
+ });
79
55
 
80
- // Fallback pages for offline
81
- fallbacks: {
82
- entries: [
83
- {
84
- url: offlineFallback,
85
- matcher({ request }) {
86
- return request.destination === 'document';
87
- },
88
- },
89
- ],
90
- },
56
+ sw.addEventListener('activate', (event: any) => {
57
+ event.waitUntil(
58
+ caches
59
+ .keys()
60
+ .then((keys: string[]) =>
61
+ Promise.all(keys.filter((k) => k !== cacheName).map((k) => caches.delete(k)))
62
+ )
63
+ .then(() => {
64
+ if (clientsClaim) return sw.clients.claim();
65
+ })
66
+ );
91
67
  });
92
68
 
93
- serwist.addEventListeners();
69
+ sw.addEventListener('fetch', (event: any) => {
70
+ const { request } = event;
71
+ if (request.mode !== 'navigate') return;
72
+ event.respondWith(
73
+ fetch(request).catch(() =>
74
+ caches
75
+ .match(offlineFallback)
76
+ .then((r: Response | undefined) => r ?? Response.error())
77
+ )
78
+ );
79
+ });
94
80
  }
@@ -1,100 +0,0 @@
1
- import { NextConfig } from 'next';
2
-
3
- /**
4
- * PWA (Progressive Web App) Plugin
5
- *
6
- * Configures Serwist for service worker and offline support
7
- * Modern PWA solution for Next.js 15+ with App Router
8
- *
9
- * @see https://serwist.pages.dev/
10
- */
11
-
12
- interface PWAPluginOptions {
13
- /**
14
- * Destination directory for service worker files
15
- * @default 'public'
16
- * @deprecated Use swDest instead
17
- */
18
- dest?: string;
19
- /**
20
- * Path to service worker source file (relative to project root)
21
- * @default 'app/sw.ts'
22
- */
23
- swSrc?: string;
24
- /**
25
- * Destination for compiled service worker
26
- * @default 'public/sw.js'
27
- */
28
- swDest?: string;
29
- /**
30
- * Disable PWA completely
31
- * @default false in production, true in development
32
- * @example disable: process.env.NODE_ENV === 'development'
33
- */
34
- disable?: boolean;
35
- /**
36
- * Cache on navigation - cache pages when navigating
37
- * @default true
38
- */
39
- cacheOnNavigation?: boolean;
40
- /**
41
- * Reload app when device goes back online
42
- * @default true
43
- */
44
- reloadOnOnline?: boolean;
45
- /**
46
- * Additional Serwist options
47
- * @see https://serwist.pages.dev/docs/next/configuring
48
- */
49
- serwistOptions?: Record<string, any>;
50
- }
51
- /**
52
- * Add PWA configuration to Next.js config using Serwist
53
- *
54
- * @example Basic usage
55
- * ```ts
56
- * import { createBaseNextConfig, withPWA } from '@djangocfg/nextjs/config';
57
- *
58
- * const nextConfig = createBaseNextConfig({...});
59
- *
60
- * export default withPWA(nextConfig, {
61
- * swSrc: 'app/sw.ts',
62
- * disable: process.env.NODE_ENV === 'development',
63
- * });
64
- * ```
65
- *
66
- * @example Integrated with createBaseNextConfig
67
- * ```ts
68
- * import { createBaseNextConfig } from '@djangocfg/nextjs/config';
69
- *
70
- * const config = createBaseNextConfig({
71
- * pwa: {
72
- * swSrc: 'app/sw.ts',
73
- * disable: false,
74
- * },
75
- * });
76
- *
77
- * export default config;
78
- * ```
79
- */
80
- declare function withPWA(nextConfig: NextConfig, options?: PWAPluginOptions): NextConfig;
81
- /**
82
- * Get service worker template content
83
- *
84
- * Returns ready-to-use service worker code for app/sw.ts
85
- *
86
- * @example
87
- * ```ts
88
- * import { getServiceWorkerTemplate } from '@djangocfg/nextjs/config';
89
- *
90
- * // Copy this to your app/sw.ts file
91
- * console.log(getServiceWorkerTemplate());
92
- * ```
93
- */
94
- declare function getServiceWorkerTemplate(): string;
95
- declare const defaultRuntimeCaching: any[];
96
- declare function createApiCacheRule(): {};
97
- declare function createStaticAssetRule(): {};
98
- declare function createCdnCacheRule(): {};
99
-
100
- export { type PWAPluginOptions as P, createCdnCacheRule as a, createStaticAssetRule as b, createApiCacheRule as c, defaultRuntimeCaching as d, getServiceWorkerTemplate as g, withPWA as w };