Get a list of the files to add from a folder into an npm package
npx @tessl/cli install tessl/npm-npm-packlist@10.0.00
# npm-packlist
1
2
npm-packlist analyzes npm package directories to determine which files should be included when creating package tarballs. It implements npm's file inclusion and exclusion rules by analyzing package.json files lists, .npmignore files, .gitignore files, and applying default exclusion patterns.
3
4
## Package Information
5
6
- **Package Name**: npm-packlist
7
- **Package Type**: npm
8
- **Language**: JavaScript (Node.js)
9
- **Installation**: `npm install npm-packlist`
10
11
## Core Imports
12
13
```javascript
14
const packlist = require('npm-packlist');
15
const { Walker } = require('npm-packlist');
16
```
17
18
ES modules (if supported by environment):
19
20
```javascript
21
import packlist, { Walker } from 'npm-packlist';
22
```
23
24
## Basic Usage
25
26
npm-packlist requires an [Arborist](https://github.com/npm/cli/tree/latest/workspaces/arborist) tree object representing the package structure:
27
28
```javascript
29
const Arborist = require('@npmcli/arborist');
30
const packlist = require('npm-packlist');
31
32
// Load package tree
33
const arborist = new Arborist({ path: '/path/to/package' });
34
const tree = await arborist.loadActual();
35
36
// Get list of files to include in package
37
const files = await packlist(tree);
38
console.log(files); // Array of file paths relative to package root
39
40
// Use with tar to create package
41
const tar = require('tar');
42
tar.create({
43
prefix: 'package/',
44
cwd: '/path/to/package',
45
file: '/path/to/package.tgz',
46
gzip: true
47
}, files);
48
```
49
50
## Architecture
51
52
npm-packlist is built around several key components:
53
54
- **PackWalker Class**: Extends ignore-walk's Walker to implement npm-specific file inclusion rules
55
- **Rule System**: Uses synthetic rule sets (defaultRules, strictRules) and file-based rules (.npmignore, .gitignore, package.json)
56
- **Bundle Support**: Handles bundled dependencies by recursively walking their file trees
57
- **Workspace Integration**: Supports npm workspaces and monorepo structures
58
- **Ignore Precedence**: Implements npm's ignore file precedence order
59
60
## Capabilities
61
62
### Package File Discovery
63
64
Main function that walks a package tree and returns files to include in the npm package tarball.
65
66
```javascript { .api }
67
/**
68
* Walk a package tree and return list of files to include
69
* @param {Object} tree - Arborist tree object representing the package
70
* @param {Object} [options] - Configuration options
71
* @param {Function} [callback] - Optional callback for callback-style usage
72
* @returns {Promise<string[]>} Array of file paths relative to package root
73
*/
74
function packlist(tree, options, callback);
75
```
76
77
**Usage Examples:**
78
79
```javascript
80
const Arborist = require('@npmcli/arborist');
81
const packlist = require('npm-packlist');
82
83
// Promise-based usage
84
const arborist = new Arborist({ path: './my-package' });
85
const tree = await arborist.loadActual();
86
const files = await packlist(tree);
87
88
// With options
89
const files = await packlist(tree, {
90
ignoreFiles: ['.npmignore', '.gitignore'],
91
requiredFiles: ['README.md', 'CHANGELOG.md']
92
});
93
94
// Callback-based usage
95
packlist(tree, (err, files) => {
96
if (err) throw err;
97
console.log('Files to include:', files);
98
});
99
```
100
101
### Advanced Walker Interface
102
103
Direct access to the PackWalker class for advanced use cases and custom configurations.
104
105
```javascript { .api }
106
/**
107
* PackWalker class for advanced package file walking
108
* Extends ignore-walk's Walker with npm-specific behavior
109
*/
110
class Walker extends IgnoreWalker {
111
/**
112
* Create a new PackWalker instance
113
* @param {Object} tree - Arborist tree object
114
* @param {Object} opts - Walker options
115
*/
116
constructor(tree, opts);
117
}
118
```
119
120
**Walker Options:**
121
122
```javascript { .api }
123
interface WalkerOptions {
124
/** Path to walk (defaults to tree.path) */
125
path?: string;
126
/** Whether this walker represents a package root */
127
isPackage?: boolean;
128
/** Array of ignore file names to respect */
129
ignoreFiles?: string[];
130
/** Files that must be included regardless of ignore rules */
131
requiredFiles?: string[];
132
/** Set of already seen nodes (for circular dependency prevention) */
133
seen?: Set<Object>;
134
/** Workspace root prefix path */
135
prefix?: string;
136
/** Array of workspace directory paths */
137
workspaces?: string[];
138
}
139
```
140
141
**Usage Examples:**
142
143
```javascript
144
const { Walker } = require('npm-packlist');
145
const Arborist = require('@npmcli/arborist');
146
147
// Create custom walker
148
const arborist = new Arborist({ path: './my-package' });
149
const tree = await arborist.loadActual();
150
151
const walker = new Walker(tree, {
152
isPackage: true,
153
ignoreFiles: ['.mynpmignore', '.gitignore'],
154
requiredFiles: ['important-file.txt']
155
});
156
157
// Use event-driven interface
158
const files = await new Promise((resolve, reject) => {
159
walker
160
.on('done', resolve)
161
.on('error', reject)
162
.start();
163
});
164
```
165
166
### File Inclusion Rules
167
168
npm-packlist implements npm's file inclusion rules in the following precedence order:
169
170
1. **package.json files array**: If present, only include files listed (plus required files)
171
2. **.npmignore**: If no files array, use .npmignore rules
172
3. **.gitignore**: If no files array or .npmignore, use .gitignore rules
173
4. **Default exclusions**: Always exclude common cruft files unless explicitly included
174
175
**Always Included Files:**
176
- package.json (root only)
177
- README files (readme, readme.*, copying, copying.*, license, license.*, licence, licence.*)
178
- Files specified in package.json main, browser, and bin fields
179
180
**Always Excluded Files:**
181
- .git directories and contents
182
- node_modules (unless bundled dependencies)
183
- .DS_Store files
184
- Editor temporary files (*.swp, ._*, *.orig)
185
- .npmrc files
186
- Lock files (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb)
187
188
### Bundled Dependencies
189
190
Automatic handling of bundled dependencies specified in package.json.
191
192
```javascript { .api }
193
/**
194
* Bundled dependency handling is automatic when using packlist()
195
* Dependencies listed in bundleDependencies are included with their files
196
* For non-root packages, all production and optional dependencies are bundled
197
*/
198
```
199
200
The walker automatically:
201
- Identifies bundled dependencies from package.json
202
- Recursively walks bundled dependency file trees
203
- Applies appropriate ignore rules for linked vs regular dependencies
204
- Prevents infinite loops in circular dependency graphs
205
206
### Workspace Support
207
208
Built-in support for npm workspaces and monorepo structures.
209
210
```javascript { .api }
211
/**
212
* Workspace support is automatic when workspace information is present in the tree
213
* Use workspace-specific options for custom behavior
214
*/
215
interface WorkspaceOptions {
216
/** Root directory of the workspace */
217
prefix: string;
218
/** Array of workspace directory paths */
219
workspaces: string[];
220
}
221
```
222
223
**Usage Examples:**
224
225
```javascript
226
// Workspace support is automatic with Arborist
227
const arborist = new Arborist({
228
path: '/workspace/root',
229
workspaces: ['packages/*']
230
});
231
const tree = await arborist.loadActual();
232
233
// Package files for workspace root
234
const rootFiles = await packlist(tree);
235
236
// Package files for specific workspace
237
const workspaceArborist = new Arborist({ path: '/workspace/root/packages/my-package' });
238
const workspaceTree = await workspaceArborist.loadActual();
239
const workspaceFiles = await packlist(workspaceTree);
240
```
241
242
## Types
243
244
```javascript { .api }
245
/**
246
* Main packlist function signature
247
*/
248
declare function packlist(
249
tree: ArboristNode,
250
options?: PacklistOptions,
251
callback?: (err: Error | null, files: string[]) => void
252
): Promise<string[]>;
253
254
/**
255
* Arborist tree node (simplified interface)
256
*/
257
interface ArboristNode {
258
path: string;
259
package: {
260
name?: string;
261
version?: string;
262
files?: string[];
263
main?: string;
264
browser?: string;
265
bin?: { [key: string]: string } | string;
266
bundleDependencies?: string[];
267
dependencies?: { [key: string]: string };
268
optionalDependencies?: { [key: string]: string };
269
};
270
isProjectRoot: boolean;
271
workspaces?: Map<string, string>;
272
edgesOut?: Map<string, Edge>;
273
}
274
275
/**
276
* Arborist edge (dependency link)
277
*/
278
interface Edge {
279
to: ArboristNode;
280
peer: boolean;
281
dev: boolean;
282
}
283
284
/**
285
* Configuration options for packlist
286
*/
287
interface PacklistOptions {
288
/** Path to walk (overrides tree.path) */
289
path?: string;
290
/** Array of ignore file names to respect */
291
ignoreFiles?: string[];
292
/** Files that must be included regardless of ignore rules */
293
requiredFiles?: string[];
294
/** Workspace root prefix path */
295
prefix?: string;
296
/** Array of workspace directory paths */
297
workspaces?: string[];
298
}
299
```
300
301
## Error Handling
302
303
npm-packlist handles several error conditions gracefully:
304
305
- **Missing files**: Files listed in package.json files array that don't exist are silently skipped
306
- **Permission errors**: File system permission errors are propagated as exceptions
307
- **Invalid trees**: Missing or malformed Arborist tree objects throw errors
308
- **Circular dependencies**: Prevented using seen node tracking
309
310
**Common Error Patterns:**
311
312
```javascript
313
try {
314
const files = await packlist(tree);
315
} catch (error) {
316
if (error.code === 'ENOENT') {
317
console.error('Package directory not found');
318
} else if (error.code === 'EACCES') {
319
console.error('Permission denied reading package files');
320
} else {
321
console.error('Unexpected error:', error.message);
322
}
323
}
324
```