next-build-filter 0.1.0 → 0.2.1
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 +469 -26
- package/index.d.ts +14 -3
- package/lib/empty-module.js +79 -14
- package/lib/next-build-filter-plugin.js +19 -4
- package/lib/with-page-filter.js +13 -1
- package/package.json +23 -10
package/README.md
CHANGED
|
@@ -8,10 +8,11 @@ A powerful Next.js plugin that allows you to exclude specific pages/routes from
|
|
|
8
8
|
- 📱 **App Router Support** - Full Next.js 13+ App Router compatibility
|
|
9
9
|
- 📄 **Pages Router Support** - Traditional Pages Router support
|
|
10
10
|
- 🎯 **Flexible filtering** with multiple configuration options
|
|
11
|
+
- 🌟 **Glob Pattern Matching** - Use powerful wildcards like `admin/**`, `*/test`, `blog/*`, `**/internal/**`
|
|
11
12
|
- 🔄 **Non-destructive** - files remain in your codebase
|
|
12
13
|
- 🌍 **Environment-aware** - different configurations for dev/prod
|
|
13
14
|
- 📝 **Verbose logging** to see what's being filtered
|
|
14
|
-
- 🎨 **
|
|
15
|
+
- 🎨 **Advanced pattern matching** support with regex (for complex cases)
|
|
15
16
|
- 🔧 **TypeScript support** with full type definitions
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
@@ -34,8 +35,8 @@ const filterConfig = {
|
|
|
34
35
|
supportPagesRouter: true,
|
|
35
36
|
supportAppRouter: false,
|
|
36
37
|
excludedPages: [
|
|
37
|
-
'admin',
|
|
38
|
-
'dev
|
|
38
|
+
'admin/**', // Exclude all admin pages (supports glob patterns)
|
|
39
|
+
'dev/**', // Exclude all dev pages
|
|
39
40
|
],
|
|
40
41
|
};
|
|
41
42
|
|
|
@@ -56,8 +57,8 @@ const filterConfig = {
|
|
|
56
57
|
supportAppRouter: true,
|
|
57
58
|
supportPagesRouter: false,
|
|
58
59
|
excludedPages: [
|
|
59
|
-
'admin',
|
|
60
|
-
'dev
|
|
60
|
+
'admin/**', // Excludes all routes under app/admin/ (glob pattern)
|
|
61
|
+
'dev/**', // Excludes all routes under app/dev/
|
|
61
62
|
],
|
|
62
63
|
};
|
|
63
64
|
|
|
@@ -81,8 +82,9 @@ const filterConfig = {
|
|
|
81
82
|
supportAppRouter: true,
|
|
82
83
|
supportPagesRouter: true,
|
|
83
84
|
excludedPages: [
|
|
84
|
-
'admin',
|
|
85
|
-
'dev
|
|
85
|
+
'admin/**', // Excludes both pages/admin/** and app/admin/** (glob pattern)
|
|
86
|
+
'dev/**', // Excludes both pages/dev/** and app/dev/**
|
|
87
|
+
'**/internal', // Excludes any route ending with /internal
|
|
86
88
|
],
|
|
87
89
|
};
|
|
88
90
|
|
|
@@ -106,6 +108,30 @@ FILTER_PAGES=true npm run build
|
|
|
106
108
|
npm run build:filtered
|
|
107
109
|
```
|
|
108
110
|
|
|
111
|
+
## Glob Pattern Quick Reference
|
|
112
|
+
|
|
113
|
+
The plugin supports powerful glob patterns for flexible page/route matching:
|
|
114
|
+
|
|
115
|
+
| Pattern | What it matches | Example |
|
|
116
|
+
|---------|----------------|---------|
|
|
117
|
+
| `admin` | Exact match | `/admin` only |
|
|
118
|
+
| `admin/*` | One level deep | `/admin/users`, `/admin/settings` |
|
|
119
|
+
| `admin/**` | Any depth | `/admin/users`, `/admin/users/edit`, `/admin/settings/advanced` |
|
|
120
|
+
| `**/test` | Ending with | `/api/test`, `/components/test`, `/admin/tools/test` |
|
|
121
|
+
| `*/debug` | One wildcard | `/api/debug`, `/dev/debug` |
|
|
122
|
+
| `**/internal/**` | Containing | Any route with `/internal/` anywhere in path |
|
|
123
|
+
| `{admin,dev}/**` | Multiple patterns | All routes under `/admin` or `/dev` |
|
|
124
|
+
|
|
125
|
+
**Example Usage:**
|
|
126
|
+
```javascript
|
|
127
|
+
excludedPages: [
|
|
128
|
+
'admin/**', // ✅ Exclude all admin routes (recommended)
|
|
129
|
+
'dev/**/test', // ✅ Exclude test pages in dev directory
|
|
130
|
+
'*-draft', // ✅ Exclude pages ending with -draft
|
|
131
|
+
'api/*/internal', // ✅ Exclude internal API routes
|
|
132
|
+
]
|
|
133
|
+
```
|
|
134
|
+
|
|
109
135
|
## Configuration Options
|
|
110
136
|
|
|
111
137
|
### Basic Options
|
|
@@ -127,7 +153,40 @@ npm run build:filtered
|
|
|
127
153
|
|
|
128
154
|
### Filtering Options
|
|
129
155
|
|
|
156
|
+
The plugin supports three types of matching:
|
|
157
|
+
1. **Exact Match** - Direct string matching
|
|
158
|
+
2. **Glob Patterns** - Flexible wildcard matching (powered by [minimatch](https://github.com/isaacs/minimatch))
|
|
159
|
+
3. **Regex Patterns** - Advanced pattern matching via `excludePatterns`
|
|
160
|
+
|
|
161
|
+
#### Glob Pattern Syntax
|
|
162
|
+
|
|
163
|
+
| Pattern | Description | Example Matches |
|
|
164
|
+
|---------|-------------|-----------------|
|
|
165
|
+
| `*` | Matches any characters except `/` | `blog/*` matches `blog/post1`, `blog/post2` but not `blog/category/post1` |
|
|
166
|
+
| `**` | Matches any characters including `/` | `blog/**` matches `blog/post1`, `blog/category/post1`, `blog/a/b/c` |
|
|
167
|
+
| `?` | Matches exactly one character | `user/?/profile` matches `user/a/profile`, `user/1/profile` |
|
|
168
|
+
| `[abc]` | Matches any character in the brackets | `user/[0-9]/profile` matches `user/0/profile`, `user/5/profile` |
|
|
169
|
+
| `{a,b}` | Matches any of the patterns | `{admin,dev}/**` matches `admin/users`, `dev/debug` |
|
|
170
|
+
| `!` at start | Negation (not commonly used in this plugin) | `!admin/**` would match everything except admin routes |
|
|
171
|
+
|
|
172
|
+
**Common Glob Patterns Cheat Sheet:**
|
|
173
|
+
|
|
174
|
+
| Use Case | Pattern | Matches |
|
|
175
|
+
|----------|---------|---------|
|
|
176
|
+
| Exact page | `admin` | `/admin` only |
|
|
177
|
+
| Direct children | `admin/*` | `/admin/users`, `/admin/settings` (not nested) |
|
|
178
|
+
| All nested routes | `admin/**` | `/admin/users`, `/admin/users/edit`, `/admin/settings/advanced` |
|
|
179
|
+
| Ends with | `**/test` or `**/*-test` | `/api/test`, `/users/profile-test` |
|
|
180
|
+
| Starts with | `admin/**` or `admin*` | `/admin`, `/admin-panel`, `/admin/users` |
|
|
181
|
+
| Contains | `**/internal/**` | Any path with `/internal/` segment |
|
|
182
|
+
| Multiple patterns | `{admin,dev,test}/**` | All routes under `/admin`, `/dev`, or `/test` |
|
|
183
|
+
| Specific file patterns | `**/*-draft` | `/blog/post-draft`, `/products/item-draft` |
|
|
184
|
+
| API versioning | `api/v{1,2}/**` | `/api/v1/*`, `/api/v2/*` |
|
|
185
|
+
| Wildcard in middle | `api/*/internal` | `/api/users/internal`, `/api/products/internal` |
|
|
186
|
+
|
|
130
187
|
#### 1. Include Only Specific Pages
|
|
188
|
+
|
|
189
|
+
**Exact Match:**
|
|
131
190
|
```javascript
|
|
132
191
|
const filterConfig = {
|
|
133
192
|
enabled: true,
|
|
@@ -139,7 +198,22 @@ const filterConfig = {
|
|
|
139
198
|
};
|
|
140
199
|
```
|
|
141
200
|
|
|
201
|
+
**Glob Pattern Matching:**
|
|
202
|
+
```javascript
|
|
203
|
+
const filterConfig = {
|
|
204
|
+
enabled: true,
|
|
205
|
+
includedPages: [
|
|
206
|
+
'index', // Exact match: /
|
|
207
|
+
'blog/*', // All direct children: /blog/post1, /blog/post2
|
|
208
|
+
'products/**', // All nested routes: /products/*, /products/category/*, etc.
|
|
209
|
+
'user/*/profile', // Wildcard in middle: /user/123/profile, /user/456/profile
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
```
|
|
213
|
+
|
|
142
214
|
#### 2. Exclude Specific Pages
|
|
215
|
+
|
|
216
|
+
**Exact Match:**
|
|
143
217
|
```javascript
|
|
144
218
|
const filterConfig = {
|
|
145
219
|
enabled: true,
|
|
@@ -151,18 +225,52 @@ const filterConfig = {
|
|
|
151
225
|
};
|
|
152
226
|
```
|
|
153
227
|
|
|
154
|
-
|
|
228
|
+
**Glob Pattern Matching:**
|
|
229
|
+
```javascript
|
|
230
|
+
const filterConfig = {
|
|
231
|
+
enabled: true,
|
|
232
|
+
excludedPages: [
|
|
233
|
+
'admin', // Exact match: /admin
|
|
234
|
+
'admin/*', // All admin sub-pages: /admin/users, /admin/settings
|
|
235
|
+
'admin/**', // All nested admin routes: /admin/*, /admin/users/*, etc.
|
|
236
|
+
'dev/**', // All dev routes: /dev/*, /dev/debug/*, etc.
|
|
237
|
+
'*/test', // Any route ending with /test: /api/test, /dev/test
|
|
238
|
+
'**/internal/**', // Any route containing /internal/
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### 3. Regex Pattern-Based Exclusion (Advanced)
|
|
244
|
+
|
|
245
|
+
For complex patterns that can't be expressed with glob syntax, use `excludePatterns`:
|
|
155
246
|
```javascript
|
|
156
247
|
const filterConfig = {
|
|
157
248
|
enabled: true,
|
|
158
249
|
excludePatterns: [
|
|
159
|
-
'dev/.*', // All pages in /dev/ directory
|
|
160
|
-
'.*admin.*', // Any page with 'admin' in the path
|
|
161
|
-
'.*test.*', // Any page with 'test' in the path
|
|
250
|
+
'dev/.*', // Regex: All pages in /dev/ directory
|
|
251
|
+
'.*admin.*', // Regex: Any page with 'admin' in the path
|
|
252
|
+
'.*test.*', // Regex: Any page with 'test' in the path
|
|
253
|
+
'^api/v[0-9]+/', // Regex: API versioned routes like /api/v1/, /api/v2/
|
|
162
254
|
],
|
|
163
255
|
};
|
|
164
256
|
```
|
|
165
257
|
|
|
258
|
+
### Glob Patterns vs Regex Patterns
|
|
259
|
+
|
|
260
|
+
Choose the right pattern type for your use case:
|
|
261
|
+
|
|
262
|
+
| Use Case | Glob Pattern | Regex Pattern | Recommendation |
|
|
263
|
+
|----------|--------------|---------------|----------------|
|
|
264
|
+
| Exclude all admin routes | `admin/**` | `admin/.*` | ✅ Use Glob (simpler) |
|
|
265
|
+
| Exclude routes ending with -test | `**/*-test` | `.*-test$` | ✅ Use Glob (simpler) |
|
|
266
|
+
| Exclude versioned API routes (v1, v2) | N/A | `^api/v[0-9]+/` | ✅ Use Regex (complex pattern) |
|
|
267
|
+
| Match any route containing 'internal' | `**/internal/**` | `.*internal.*` | ✅ Use Glob (simpler) |
|
|
268
|
+
| Match routes with date pattern (2024-01-01) | N/A | `^\d{4}-\d{2}-\d{2}$` | ✅ Use Regex (complex pattern) |
|
|
269
|
+
|
|
270
|
+
**Guidelines:**
|
|
271
|
+
- **Use Glob Patterns** (`includedPages`/`excludedPages`) for most cases - they're simpler and more readable
|
|
272
|
+
- **Use Regex Patterns** (`excludePatterns`) only when you need advanced matching like character classes, lookaheads, or complex alternations
|
|
273
|
+
|
|
166
274
|
## Usage Examples
|
|
167
275
|
|
|
168
276
|
### Development Speed Build
|
|
@@ -188,19 +296,114 @@ module.exports = withPageFilter(filterConfig)({
|
|
|
188
296
|
```
|
|
189
297
|
|
|
190
298
|
### Production Admin Exclusion
|
|
191
|
-
Exclude admin and debug pages from production builds:
|
|
299
|
+
Exclude admin and debug pages from production builds using glob patterns:
|
|
192
300
|
|
|
193
301
|
```javascript
|
|
194
302
|
const filterConfig = {
|
|
195
303
|
enabled: process.env.NODE_ENV === 'production',
|
|
196
304
|
excludedPages: [
|
|
197
|
-
'admin',
|
|
198
|
-
'debug',
|
|
199
|
-
'dev
|
|
305
|
+
'admin/**', // Exclude all admin routes
|
|
306
|
+
'debug', // Exclude debug page
|
|
307
|
+
'dev/**', // Exclude all dev tools and utilities
|
|
308
|
+
'**/test', // Exclude all test pages
|
|
309
|
+
'internal/**', // Exclude internal pages
|
|
200
310
|
],
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
311
|
+
};
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Multi-team Development
|
|
315
|
+
Build only specific feature sets for different teams:
|
|
316
|
+
|
|
317
|
+
```javascript
|
|
318
|
+
// Team A: Only marketing pages
|
|
319
|
+
const marketingConfig = {
|
|
320
|
+
enabled: true,
|
|
321
|
+
includedPages: [
|
|
322
|
+
'index',
|
|
323
|
+
'about',
|
|
324
|
+
'contact',
|
|
325
|
+
'blog/**', // All blog routes
|
|
326
|
+
'marketing/**', // All marketing pages
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// Team B: Only product pages
|
|
331
|
+
const productConfig = {
|
|
332
|
+
enabled: true,
|
|
333
|
+
includedPages: [
|
|
334
|
+
'products/**', // All product routes
|
|
335
|
+
'checkout/**', // All checkout routes
|
|
336
|
+
'cart', // Shopping cart
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Exclude Test and Debug Routes
|
|
342
|
+
Use glob patterns to exclude testing and debugging routes:
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
const filterConfig = {
|
|
346
|
+
enabled: process.env.NODE_ENV === 'production',
|
|
347
|
+
excludedPages: [
|
|
348
|
+
'**/*-test', // Exclude all routes ending with -test
|
|
349
|
+
'**/*-debug', // Exclude all routes ending with -debug
|
|
350
|
+
'test/**', // Exclude all test directory routes
|
|
351
|
+
'debug/**', // Exclude all debug directory routes
|
|
352
|
+
'dev/**', // Exclude all development routes
|
|
353
|
+
'playground/**', // Exclude playground routes
|
|
354
|
+
],
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### API Route Filtering
|
|
359
|
+
Filter specific API routes using glob patterns:
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
const filterConfig = {
|
|
363
|
+
enabled: true,
|
|
364
|
+
excludedPages: [
|
|
365
|
+
'api/internal/**', // Exclude internal API routes
|
|
366
|
+
'api/*/admin', // Exclude admin endpoints in any API version
|
|
367
|
+
'api/webhooks/test-*', // Exclude test webhooks
|
|
368
|
+
'api/v*/deprecated/**', // Exclude deprecated endpoints in all versions
|
|
369
|
+
],
|
|
370
|
+
};
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Feature Flag Based Builds
|
|
374
|
+
Create builds with specific features using glob patterns:
|
|
375
|
+
|
|
376
|
+
```javascript
|
|
377
|
+
const filterConfig = {
|
|
378
|
+
enabled: true,
|
|
379
|
+
includedPages: [
|
|
380
|
+
'index', // Home page
|
|
381
|
+
'about', // About page
|
|
382
|
+
// Conditionally include features based on environment
|
|
383
|
+
...(process.env.ENABLE_BLOG ? ['blog/**'] : []),
|
|
384
|
+
...(process.env.ENABLE_SHOP ? ['shop/**', 'cart', 'checkout/**'] : []),
|
|
385
|
+
...(process.env.ENABLE_FORUM ? ['forum/**', 'community/**'] : []),
|
|
386
|
+
],
|
|
387
|
+
};
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Multi-language Site Filtering
|
|
391
|
+
Build specific language versions:
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
const filterConfig = {
|
|
395
|
+
enabled: true,
|
|
396
|
+
// Only build English version
|
|
397
|
+
includedPages: [
|
|
398
|
+
'en/**', // All English pages
|
|
399
|
+
'index', // Root page
|
|
400
|
+
],
|
|
401
|
+
// Or exclude other languages
|
|
402
|
+
excludedPages: [
|
|
403
|
+
'fr/**', // Exclude French
|
|
404
|
+
'de/**', // Exclude German
|
|
405
|
+
'es/**', // Exclude Spanish
|
|
406
|
+
'ja/**', // Exclude Japanese
|
|
204
407
|
],
|
|
205
408
|
};
|
|
206
409
|
```
|
|
@@ -251,10 +454,45 @@ npm start
|
|
|
251
454
|
The plugin works by integrating with Next.js's webpack configuration and build process:
|
|
252
455
|
|
|
253
456
|
1. **Webpack Plugin Integration**: The plugin hooks into webpack's module resolution process
|
|
254
|
-
2. **Page Detection**: It identifies page files in the `/pages`
|
|
255
|
-
3. **
|
|
256
|
-
4. **
|
|
257
|
-
|
|
457
|
+
2. **Page Detection**: It identifies page files in the `/pages` and `/app` directories (based on router support configuration)
|
|
458
|
+
3. **Path Normalization**: Routes are normalized (lowercase, forward slashes) for consistent matching
|
|
459
|
+
4. **Pattern Matching**: For each page, the plugin checks if it should be filtered using:
|
|
460
|
+
- **Glob patterns** (via [minimatch](https://github.com/isaacs/minimatch)) - checked first
|
|
461
|
+
- **Exact string matching** - fallback for backward compatibility
|
|
462
|
+
- **Regex patterns** (via `excludePatterns`) - for advanced cases
|
|
463
|
+
5. **Filtering Logic**: Based on your configuration, it determines which pages to include/exclude
|
|
464
|
+
6. **Module Replacement**: Filtered pages are replaced with empty modules during the build process
|
|
465
|
+
7. **Build Optimization**: The final bundle only includes meaningful content for pages you want
|
|
466
|
+
|
|
467
|
+
### Important: Custom 404 Replacement
|
|
468
|
+
|
|
469
|
+
The plugin **replaces** filtered pages with custom 404 pages rather than **removing** them entirely from the build. This approach:
|
|
470
|
+
|
|
471
|
+
- ✅ **Clear user feedback**: Users see a "Page Not Available" message if they access a filtered page
|
|
472
|
+
- ✅ **Preserves routing structure**: Pages still exist in the manifest
|
|
473
|
+
- ✅ **Prevents build errors**: No missing module errors from dependencies
|
|
474
|
+
- ✅ **Testable**: Contains a unique marker (`NEXT_BUILD_FILTER_EXCLUDED_PAGE`) for verification
|
|
475
|
+
- ✅ **Proper HTTP status**: Returns 404 status code
|
|
476
|
+
|
|
477
|
+
**For App Router**: Uses Next.js's built-in `notFound()` function for proper 404 handling
|
|
478
|
+
**For Pages Router**: Returns a custom 404 component with proper status code
|
|
479
|
+
|
|
480
|
+
**What this means:**
|
|
481
|
+
- Filtered pages will still appear in your `.next/server` directory
|
|
482
|
+
- They will show a "Page Not Available" message if accessed
|
|
483
|
+
- The pages contain minimal code (just the 404 component)
|
|
484
|
+
- Build verification can detect filtered pages via the unique marker
|
|
485
|
+
|
|
486
|
+
### Pattern Matching Priority
|
|
487
|
+
|
|
488
|
+
When matching routes, the plugin uses this order:
|
|
489
|
+
|
|
490
|
+
1. **Glob Pattern Match** (via minimatch): `admin/**` matches `admin/users/list`
|
|
491
|
+
2. **Exact Match**: `admin` matches only `admin`
|
|
492
|
+
3. **Substring Match**: `admin` also matches routes containing `admin` (backward compatibility)
|
|
493
|
+
4. **Regex Match** (if using `excludePatterns`): `admin/.*` matches `admin/anything`
|
|
494
|
+
|
|
495
|
+
This multi-tiered approach ensures backward compatibility while providing powerful glob pattern support.
|
|
258
496
|
|
|
259
497
|
## Project Structure
|
|
260
498
|
|
|
@@ -333,23 +571,228 @@ npm run build:filtered
|
|
|
333
571
|
4. **Test Thoroughly**: Always test your filtered builds to ensure functionality
|
|
334
572
|
5. **Document Configuration**: Keep your filtering logic well-documented for your team
|
|
335
573
|
|
|
574
|
+
## Migration Guide
|
|
575
|
+
|
|
576
|
+
### Migrating from Regex Patterns to Glob Patterns
|
|
577
|
+
|
|
578
|
+
If you're currently using `excludePatterns` with regex, consider migrating to glob patterns in `excludedPages` for better readability:
|
|
579
|
+
|
|
580
|
+
**Before (Regex):**
|
|
581
|
+
```javascript
|
|
582
|
+
const filterConfig = {
|
|
583
|
+
excludePatterns: [
|
|
584
|
+
'admin/.*', // Regex
|
|
585
|
+
'dev/.*', // Regex
|
|
586
|
+
'.*test.*', // Regex
|
|
587
|
+
],
|
|
588
|
+
};
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**After (Glob):**
|
|
592
|
+
```javascript
|
|
593
|
+
const filterConfig = {
|
|
594
|
+
excludedPages: [
|
|
595
|
+
'admin/**', // Glob - clearer intent
|
|
596
|
+
'dev/**', // Glob - easier to read
|
|
597
|
+
'**/test/**', // Glob - more intuitive
|
|
598
|
+
],
|
|
599
|
+
};
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
**Note:** Both approaches work! Use glob patterns for simplicity and regex for complex patterns.
|
|
603
|
+
|
|
336
604
|
## Troubleshooting
|
|
337
605
|
|
|
338
606
|
### Pages Still Appearing in Build
|
|
339
|
-
- Check that `enabled: true` is set in your configuration
|
|
340
|
-
- Verify the page paths match
|
|
341
|
-
- Enable verbose
|
|
607
|
+
- ✅ Check that `enabled: true` is set in your configuration
|
|
608
|
+
- ✅ Verify the page paths match (glob patterns are case-sensitive by default)
|
|
609
|
+
- ✅ Enable `verbose: true` to see what's being processed
|
|
610
|
+
- ✅ Test your glob pattern: `admin/**` matches all nested routes, while `admin/*` only matches direct children
|
|
611
|
+
- ✅ Ensure you're running the build with the correct environment variable: `FILTER_PAGES=true npm run build`
|
|
612
|
+
|
|
613
|
+
### Glob Pattern Not Matching
|
|
614
|
+
|
|
615
|
+
**Common Issues:**
|
|
616
|
+
1. **Wrong wildcard usage**
|
|
617
|
+
- ❌ `admin/*` only matches direct children like `/admin/users`
|
|
618
|
+
- ✅ `admin/**` matches all nested routes like `/admin/users/edit`
|
|
619
|
+
|
|
620
|
+
2. **Case sensitivity**
|
|
621
|
+
- Route paths are normalized to lowercase before matching
|
|
622
|
+
- Pattern: `Admin/**` will be normalized to `admin/**`
|
|
623
|
+
|
|
624
|
+
3. **Missing or extra slashes**
|
|
625
|
+
- ✅ Correct: `admin/users/**`, `**/test`, `api/*`
|
|
626
|
+
- ❌ Avoid: `/admin/users/**` (leading slash not needed)
|
|
627
|
+
|
|
628
|
+
4. **Not matching what you expect**
|
|
629
|
+
- Enable `verbose: true` to see the actual route paths
|
|
630
|
+
- Example verbose output: `📄 Filtering out: admin/users/edit`
|
|
631
|
+
- Compare the logged path with your pattern
|
|
632
|
+
|
|
633
|
+
**Testing Your Patterns:**
|
|
634
|
+
|
|
635
|
+
Use `verbose: true` and check the console output during build:
|
|
636
|
+
```javascript
|
|
637
|
+
const filterConfig = {
|
|
638
|
+
enabled: true,
|
|
639
|
+
verbose: true, // Shows which routes are being filtered
|
|
640
|
+
excludedPages: ['admin/**'],
|
|
641
|
+
};
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
Console output will show:
|
|
645
|
+
```
|
|
646
|
+
📄 Filtering out: admin/dashboard
|
|
647
|
+
📄 Filtering out: admin/users/list
|
|
648
|
+
📄 Filtering out: admin/settings/profile
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**Pattern Matching Examples:**
|
|
652
|
+
|
|
653
|
+
| Route Path | Pattern | Matches? | Why |
|
|
654
|
+
|------------|---------|----------|-----|
|
|
655
|
+
| `admin/users` | `admin/*` | ✅ Yes | Direct child |
|
|
656
|
+
| `admin/users/edit` | `admin/*` | ❌ No | Too deeply nested |
|
|
657
|
+
| `admin/users/edit` | `admin/**` | ✅ Yes | `**` matches any depth |
|
|
658
|
+
| `blog/post-123` | `blog/*-*` | ✅ Yes | `*` matches `post` and `123` |
|
|
659
|
+
| `api/v1/users` | `api/*/users` | ✅ Yes | `*` matches `v1` |
|
|
660
|
+
| `api/v1/internal/users` | `api/*/users` | ❌ No | Too many segments |
|
|
661
|
+
| `anything/internal/data` | `**/internal/**` | ✅ Yes | `**` matches any segments |
|
|
342
662
|
|
|
343
663
|
### Build Errors
|
|
344
|
-
- Ensure all required pages (like `_app.js`, `_document.js`) are not being filtered
|
|
664
|
+
- Ensure all required pages (like `_app.js`, `_document.js`, `_app.tsx`) are not being filtered
|
|
345
665
|
- Check that your regex patterns are valid if using `excludePatterns`
|
|
666
|
+
- Avoid overly broad patterns that might exclude critical Next.js files
|
|
667
|
+
- Test patterns incrementally: start with one pattern and add more once working
|
|
346
668
|
|
|
347
669
|
### Development vs Production Differences
|
|
348
670
|
- Set `enableInDev: true` if you want consistent behavior across environments
|
|
349
671
|
- Use environment variables to control filtering per environment
|
|
672
|
+
- Note: By default, filtering is disabled in development mode unless `enableInDev` is set
|
|
673
|
+
- Remember: `npm run dev` vs `npm run build` behave differently by default
|
|
674
|
+
|
|
675
|
+
### Advanced Debugging
|
|
676
|
+
|
|
677
|
+
If you're having trouble with patterns, try these steps:
|
|
678
|
+
|
|
679
|
+
1. **Start simple**: Test with an exact match first
|
|
680
|
+
```javascript
|
|
681
|
+
excludedPages: ['admin'] // Start with exact match
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
2. **Add verbosity**: See what's being matched
|
|
685
|
+
```javascript
|
|
686
|
+
verbose: true
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
3. **Test one pattern at a time**: Isolate the problematic pattern
|
|
690
|
+
```javascript
|
|
691
|
+
excludedPages: ['admin/**'] // Test one at a time
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
4. **Check the actual route paths**: Look at your project structure
|
|
695
|
+
```
|
|
696
|
+
pages/
|
|
697
|
+
admin/
|
|
698
|
+
users.js → Route path: admin/users
|
|
699
|
+
settings/
|
|
700
|
+
profile.js → Route path: admin/settings/profile
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
5. **Use the demos**: Test your patterns in the included demo projects
|
|
704
|
+
```bash
|
|
705
|
+
cd demo/pages-router-demo
|
|
706
|
+
FILTER_PAGES=true npm run build
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
## Technical Details
|
|
710
|
+
|
|
711
|
+
### Glob Pattern Matching Library
|
|
712
|
+
|
|
713
|
+
This plugin uses [minimatch](https://github.com/isaacs/minimatch) for glob pattern matching, the same library used by many popular tools like:
|
|
714
|
+
- npm
|
|
715
|
+
- webpack
|
|
716
|
+
- babel
|
|
717
|
+
- eslint
|
|
718
|
+
|
|
719
|
+
Minimatch provides powerful and reliable glob pattern matching with full support for:
|
|
720
|
+
- Brace expansion: `{a,b,c}`
|
|
721
|
+
- Extended glob patterns: `@(pattern|list)`
|
|
722
|
+
- Multiple wildcards: `**/**/`
|
|
723
|
+
- Character classes: `[abc]`, `[0-9]`
|
|
724
|
+
|
|
725
|
+
### Performance Considerations
|
|
726
|
+
|
|
727
|
+
- Glob pattern matching is performed during the webpack build phase
|
|
728
|
+
- Pattern matching is highly optimized by minimatch
|
|
729
|
+
- Routes are normalized once and cached for efficient matching
|
|
730
|
+
- Only page/route files are checked (not all webpack modules)
|
|
731
|
+
|
|
732
|
+
### Compatibility
|
|
733
|
+
|
|
734
|
+
- ✅ Next.js 12+ (Pages Router)
|
|
735
|
+
- ✅ Next.js 13+ (App Router)
|
|
736
|
+
- ✅ Node.js 16+
|
|
737
|
+
- ✅ Works with TypeScript
|
|
738
|
+
- ✅ Compatible with all Next.js deployment targets (standalone, static export, etc.)
|
|
739
|
+
|
|
740
|
+
## Testing
|
|
741
|
+
|
|
742
|
+
This project includes a comprehensive test suite with unit tests and end-to-end tests.
|
|
743
|
+
|
|
744
|
+
### Running Tests
|
|
745
|
+
|
|
746
|
+
```bash
|
|
747
|
+
# Run all unit tests
|
|
748
|
+
npm test
|
|
749
|
+
|
|
750
|
+
# Run unit tests in watch mode (for development)
|
|
751
|
+
npm run test:watch
|
|
752
|
+
|
|
753
|
+
# Run unit tests with coverage report
|
|
754
|
+
npm run test:coverage
|
|
755
|
+
|
|
756
|
+
# Run end-to-end tests (actual builds)
|
|
757
|
+
npm run test:e2e
|
|
758
|
+
|
|
759
|
+
# Run all tests (unit + e2e)
|
|
760
|
+
npm run test:all
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Test Structure
|
|
764
|
+
|
|
765
|
+
- **Unit Tests** (`tests/unit/`): Test core functionality using Vitest
|
|
766
|
+
- `glob-patterns.test.js`: Tests for glob pattern matching
|
|
767
|
+
- `plugin.test.js`: Tests for plugin core functionality
|
|
768
|
+
- `with-page-filter.test.js`: Tests for configuration wrapper
|
|
769
|
+
|
|
770
|
+
- **E2E Tests** (`tests/e2e/`): Test actual Next.js builds
|
|
771
|
+
- Verifies filtering works correctly in real builds
|
|
772
|
+
- Tests both Pages Router and App Router demos
|
|
773
|
+
|
|
774
|
+
### Test Coverage
|
|
775
|
+
|
|
776
|
+
The test suite covers:
|
|
777
|
+
- ✅ Glob pattern matching with various patterns
|
|
778
|
+
- ✅ Path normalization and route extraction
|
|
779
|
+
- ✅ Page file identification (Pages Router & App Router)
|
|
780
|
+
- ✅ Filtering logic (includedPages, excludedPages, patterns)
|
|
781
|
+
- ✅ Configuration options and defaults
|
|
782
|
+
- ✅ Webpack integration
|
|
783
|
+
- ✅ Actual build output verification
|
|
784
|
+
|
|
785
|
+
See `tests/README.md` for detailed testing documentation.
|
|
350
786
|
|
|
351
787
|
## Contributing
|
|
352
788
|
|
|
789
|
+
Contributions are welcome! When contributing:
|
|
790
|
+
|
|
791
|
+
1. Write tests for new features
|
|
792
|
+
2. Ensure all tests pass: `npm run test:all`
|
|
793
|
+
3. Update documentation as needed
|
|
794
|
+
4. Submit a pull request
|
|
795
|
+
|
|
353
796
|
Feel free to submit issues, feature requests, or pull requests to improve this plugin.
|
|
354
797
|
|
|
355
798
|
## License
|
package/index.d.ts
CHANGED
|
@@ -11,13 +11,24 @@ declare module 'next-build-filter' {
|
|
|
11
11
|
/** Apply filtering in development mode */
|
|
12
12
|
enableInDev?: boolean;
|
|
13
13
|
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Pages to include (if specified, only these will be built)
|
|
16
|
+
* Supports glob patterns: 'admin/**', 'blog/*', '*\/test'
|
|
17
|
+
* @example ['index', 'about', 'blog/**', 'products/*']
|
|
18
|
+
*/
|
|
15
19
|
includedPages?: string[];
|
|
16
20
|
|
|
17
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Pages to exclude from build
|
|
23
|
+
* Supports glob patterns: 'admin/**', 'dev/*', '*\/internal'
|
|
24
|
+
* @example ['admin/**', 'dev/**', '*\/test']
|
|
25
|
+
*/
|
|
18
26
|
excludedPages?: string[];
|
|
19
27
|
|
|
20
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Regex patterns for advanced page exclusion
|
|
30
|
+
* @example ['dev/.*', '.*admin.*', '^api/v[0-9]+/']
|
|
31
|
+
*/
|
|
21
32
|
excludePatterns?: string[];
|
|
22
33
|
|
|
23
34
|
/** Pages directory name (default: 'pages') */
|
package/lib/empty-module.js
CHANGED
|
@@ -1,29 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Empty module to replace filtered pages
|
|
3
|
+
*
|
|
4
|
+
* This module provides a custom 404 response with a detectable marker
|
|
5
|
+
* that can be verified in tests and provides clear feedback to users.
|
|
6
|
+
*
|
|
7
|
+
* Marker: NEXT_BUILD_FILTER_EXCLUDED_PAGE
|
|
8
|
+
*/
|
|
3
9
|
|
|
4
|
-
|
|
5
|
-
|
|
10
|
+
// Try to import notFound for App Router (will fail gracefully for Pages Router)
|
|
11
|
+
let notFound;
|
|
12
|
+
try {
|
|
13
|
+
notFound = require('next/navigation').notFound;
|
|
14
|
+
} catch (e) {
|
|
15
|
+
// Not in App Router context or Next.js not available
|
|
16
|
+
notFound = null;
|
|
6
17
|
}
|
|
7
18
|
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
module.exports.default = EmptyPage;
|
|
19
|
+
// Marker string to identify filtered pages
|
|
20
|
+
const FILTER_MARKER = 'NEXT_BUILD_FILTER_EXCLUDED_PAGE';
|
|
11
21
|
|
|
12
|
-
// For
|
|
13
|
-
|
|
14
|
-
|
|
22
|
+
// For Pages Router: Return a component that renders 404
|
|
23
|
+
function FilteredPage() {
|
|
24
|
+
// If we're in App Router and notFound is available, use it
|
|
25
|
+
if (notFound && typeof notFound === 'function') {
|
|
26
|
+
notFound();
|
|
27
|
+
return null; // notFound() throws, so this won't be reached
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// For Pages Router or fallback: Return a custom 404 component
|
|
31
|
+
// Using React.createElement to avoid JSX
|
|
32
|
+
const React = require('react');
|
|
33
|
+
return React.createElement(
|
|
34
|
+
'div',
|
|
35
|
+
{
|
|
36
|
+
style: {
|
|
37
|
+
display: 'flex',
|
|
38
|
+
flexDirection: 'column',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
justifyContent: 'center',
|
|
41
|
+
minHeight: '100vh',
|
|
42
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
43
|
+
backgroundColor: '#f5f5f5',
|
|
44
|
+
},
|
|
45
|
+
'data-filter-marker': FILTER_MARKER
|
|
46
|
+
},
|
|
47
|
+
[
|
|
48
|
+
React.createElement('h1', { key: 'title', style: { fontSize: '3rem', margin: '0' } }, '404'),
|
|
49
|
+
React.createElement(
|
|
50
|
+
'p',
|
|
51
|
+
{ key: 'message', style: { fontSize: '1.2rem', color: '#666', marginTop: '1rem' } },
|
|
52
|
+
'Page Not Available'
|
|
53
|
+
),
|
|
54
|
+
React.createElement(
|
|
55
|
+
'p',
|
|
56
|
+
{ key: 'detail', style: { fontSize: '0.9rem', color: '#999', marginTop: '0.5rem' } },
|
|
57
|
+
'This page has been filtered out during build.'
|
|
58
|
+
),
|
|
59
|
+
React.createElement(
|
|
60
|
+
'div',
|
|
61
|
+
{ key: 'marker', style: { display: 'none' } },
|
|
62
|
+
FILTER_MARKER
|
|
63
|
+
),
|
|
64
|
+
]
|
|
65
|
+
);
|
|
15
66
|
}
|
|
16
67
|
|
|
68
|
+
// Set status code for Pages Router
|
|
69
|
+
FilteredPage.getInitialProps = ({ res }) => {
|
|
70
|
+
if (res) {
|
|
71
|
+
res.statusCode = 404;
|
|
72
|
+
}
|
|
73
|
+
return {};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// For React components (Pages Router)
|
|
77
|
+
module.exports = FilteredPage;
|
|
78
|
+
module.exports.default = FilteredPage;
|
|
79
|
+
|
|
80
|
+
// Export the marker for testing
|
|
81
|
+
module.exports.FILTER_MARKER = FILTER_MARKER;
|
|
82
|
+
|
|
17
83
|
// Generate metadata for App Router if needed
|
|
18
84
|
module.exports.generateMetadata = () => ({
|
|
19
|
-
title: 'Page Not Available',
|
|
20
|
-
description: 'This page has been filtered out during build'
|
|
85
|
+
title: 'Page Not Available - 404',
|
|
86
|
+
description: 'This page has been filtered out during build',
|
|
21
87
|
});
|
|
22
88
|
|
|
23
89
|
// Generate static params for dynamic routes if needed
|
|
24
90
|
module.exports.generateStaticParams = () => [];
|
|
25
91
|
|
|
26
|
-
// Export all common App Router functions
|
|
92
|
+
// Export all common App Router functions
|
|
27
93
|
module.exports.generateViewport = () => ({});
|
|
28
|
-
module.exports.generateStaticParams = () => [];
|
|
29
94
|
module.exports.revalidate = false;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
+
const { minimatch } = require('minimatch');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Next.js Build Filter Plugin
|
|
6
7
|
*
|
|
7
8
|
* This plugin allows you to exclude specific pages from the build process
|
|
8
9
|
* without actually removing the files from your project.
|
|
10
|
+
* Supports glob patterns via minimatch for flexible filtering.
|
|
9
11
|
*/
|
|
10
12
|
class NextBuildFilterPlugin {
|
|
11
13
|
constructor(options = {}) {
|
|
@@ -64,11 +66,13 @@ class NextBuildFilterPlugin {
|
|
|
64
66
|
|
|
65
67
|
// Check if this is a page file
|
|
66
68
|
if (this.isPageFile(request, resolveData.context)) {
|
|
69
|
+
const normalizedRequest = this.normalizePath(request);
|
|
70
|
+
const routePath = this.extractRoutePath(normalizedRequest);
|
|
67
71
|
const shouldExclude = this.shouldExcludePage(request);
|
|
68
72
|
|
|
69
73
|
if (shouldExclude) {
|
|
70
74
|
if (this.options.verbose) {
|
|
71
|
-
console.log(`📄
|
|
75
|
+
console.log(`📄 Filtering out: ${routePath || request}`);
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
// Replace with empty module instead of blocking the request
|
|
@@ -152,6 +156,7 @@ class NextBuildFilterPlugin {
|
|
|
152
156
|
|
|
153
157
|
/**
|
|
154
158
|
* Determine if a page should be excluded from the build
|
|
159
|
+
* Supports glob patterns, exact matches, and regex patterns
|
|
155
160
|
*/
|
|
156
161
|
shouldExcludePage(request) {
|
|
157
162
|
const normalizedRequest = this.normalizePath(request);
|
|
@@ -164,6 +169,11 @@ class NextBuildFilterPlugin {
|
|
|
164
169
|
if (this.options.includedPages.length > 0) {
|
|
165
170
|
const isIncluded = this.options.includedPages.some(page => {
|
|
166
171
|
const normalizedPage = this.normalizePath(page);
|
|
172
|
+
// Try glob matching first (using minimatch)
|
|
173
|
+
if (minimatch(routePath, normalizedPage)) {
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
// Fallback to exact match or prefix match for backward compatibility
|
|
167
177
|
return routePath === normalizedPage || routePath.startsWith(normalizedPage + '/');
|
|
168
178
|
});
|
|
169
179
|
return !isIncluded;
|
|
@@ -173,12 +183,17 @@ class NextBuildFilterPlugin {
|
|
|
173
183
|
if (this.options.excludedPages.length > 0) {
|
|
174
184
|
const isExcluded = this.options.excludedPages.some(page => {
|
|
175
185
|
const normalizedPage = this.normalizePath(page);
|
|
186
|
+
// Try glob matching first (using minimatch)
|
|
187
|
+
if (minimatch(routePath, normalizedPage)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
// Fallback to exact match or prefix match for backward compatibility
|
|
176
191
|
return routePath === normalizedPage || routePath.startsWith(normalizedPage + '/');
|
|
177
192
|
});
|
|
178
193
|
if (isExcluded) return true;
|
|
179
194
|
}
|
|
180
195
|
|
|
181
|
-
// Check exclude patterns
|
|
196
|
+
// Check exclude patterns (regex patterns)
|
|
182
197
|
if (this.options.excludePatterns.length > 0) {
|
|
183
198
|
const isPatternExcluded = this.options.excludePatterns.some(pattern => {
|
|
184
199
|
try {
|
|
@@ -227,8 +242,8 @@ class NextBuildFilterPlugin {
|
|
|
227
242
|
|
|
228
243
|
// Remove file name and extension for App Router
|
|
229
244
|
if (this.options.supportAppRouter && normalizedRequest.includes(`/${this.options.appDir}/`)) {
|
|
230
|
-
// Remove /page.tsx, /page.js, etc.
|
|
231
|
-
routePath = routePath.replace(
|
|
245
|
+
// Remove /page.tsx, /page.js, etc. (with or without leading slash)
|
|
246
|
+
routePath = routePath.replace(/\/?page\.(tsx|ts|jsx|js)$/, '');
|
|
232
247
|
// Remove leading slash if present
|
|
233
248
|
routePath = routePath.replace(/^\//, '');
|
|
234
249
|
} else {
|
package/lib/with-page-filter.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const { minimatch } = require('minimatch');
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Next.js Page Filter Plugin
|
|
5
6
|
*
|
|
6
7
|
* Enhanced version that supports both Pages Router and App Router (Next.js 13+)
|
|
8
|
+
* Supports glob patterns for includedPages and excludedPages options
|
|
7
9
|
*/
|
|
8
10
|
function withPageFilter(options = {}) {
|
|
9
11
|
return (nextConfig = {}) => {
|
|
@@ -91,6 +93,11 @@ function shouldExcludePage(request, options) {
|
|
|
91
93
|
if (options.includedPages && options.includedPages.length > 0) {
|
|
92
94
|
const isIncluded = options.includedPages.some(page => {
|
|
93
95
|
const normalizedPage = normalizePath(page);
|
|
96
|
+
// Try glob matching first
|
|
97
|
+
if (minimatch(routePath, normalizedPage)) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
// Fallback to exact match or substring match for backward compatibility
|
|
94
101
|
return routePath === normalizedPage || routePath.includes(normalizedPage);
|
|
95
102
|
});
|
|
96
103
|
return !isIncluded;
|
|
@@ -100,12 +107,17 @@ function shouldExcludePage(request, options) {
|
|
|
100
107
|
if (options.excludedPages && options.excludedPages.length > 0) {
|
|
101
108
|
const isExcluded = options.excludedPages.some(page => {
|
|
102
109
|
const normalizedPage = normalizePath(page);
|
|
110
|
+
// Try glob matching first
|
|
111
|
+
if (minimatch(routePath, normalizedPage)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
// Fallback to exact match or substring match for backward compatibility
|
|
103
115
|
return routePath === normalizedPage || routePath.includes(normalizedPage);
|
|
104
116
|
});
|
|
105
117
|
if (isExcluded) return true;
|
|
106
118
|
}
|
|
107
119
|
|
|
108
|
-
// Check exclude patterns
|
|
120
|
+
// Check exclude patterns (regex patterns)
|
|
109
121
|
if (options.excludePatterns && options.excludePatterns.length > 0) {
|
|
110
122
|
const isPatternExcluded = options.excludePatterns.some(pattern => {
|
|
111
123
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-build-filter",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A Next.js plugin to exclude pages/routes during build without removing files. Supports both Pages Router and App Router (Next.js 13+).",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
"README.md"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"test:coverage": "vitest run --coverage",
|
|
17
|
+
"test:e2e": "node tests/e2e/run-e2e-tests.js",
|
|
18
|
+
"test:all": "npm run test && npm run test:e2e",
|
|
15
19
|
"prepublishOnly": "npm run build",
|
|
20
|
+
"postversion": "npm publish",
|
|
16
21
|
"build": "echo \"No build process needed for now\""
|
|
17
22
|
},
|
|
18
23
|
"keywords": [
|
|
@@ -26,26 +31,34 @@
|
|
|
26
31
|
"app-router",
|
|
27
32
|
"pages-router",
|
|
28
33
|
"optimization",
|
|
29
|
-
"bundle"
|
|
34
|
+
"bundle",
|
|
35
|
+
"glob",
|
|
36
|
+
"pattern-matching",
|
|
37
|
+
"wildcard"
|
|
30
38
|
],
|
|
31
|
-
"author": "",
|
|
39
|
+
"author": "banyudu <banyudu@gmail.com>",
|
|
32
40
|
"license": "MIT",
|
|
33
41
|
"peerDependencies": {
|
|
34
42
|
"next": ">=12.0.0",
|
|
35
43
|
"react": ">=17.0.0"
|
|
36
44
|
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"minimatch": "^9.0.0"
|
|
47
|
+
},
|
|
37
48
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^20.0.0"
|
|
49
|
+
"@types/node": "^20.0.0",
|
|
50
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
51
|
+
"vitest": "^1.0.0"
|
|
39
52
|
},
|
|
40
53
|
"repository": {
|
|
41
54
|
"type": "git",
|
|
42
|
-
"url": "git+https://github.com/
|
|
55
|
+
"url": "git+https://github.com/banyudu/next-build-filter.git"
|
|
43
56
|
},
|
|
44
57
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/
|
|
58
|
+
"url": "https://github.com/banyudu/next-build-filter/issues"
|
|
46
59
|
},
|
|
47
|
-
"homepage": "https://github.com/
|
|
60
|
+
"homepage": "https://github.com/banyudu/next-build-filter#readme",
|
|
48
61
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
62
|
+
"node": ">=18.0.0"
|
|
50
63
|
}
|
|
51
|
-
}
|
|
64
|
+
}
|