Asynchronous JavaScript loader and dependency manager for dynamic script loading
npx @tessl/cli install tessl/npm-scriptjs@2.5.00
# $script.js
1
2
$script.js is an asynchronous JavaScript loader and dependency manager with an impressively lightweight footprint. It allows you to load script resources on-demand from any URL without blocking other resources (CSS and images), while providing sophisticated dependency management capabilities for complex web applications.
3
4
## Package Information
5
6
- **Package Name**: scriptjs
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install scriptjs`
10
11
## Core Imports
12
13
For ES modules:
14
```javascript
15
import $script from "scriptjs";
16
```
17
18
For CommonJS:
19
```javascript
20
const $script = require("scriptjs");
21
```
22
23
For browser (global):
24
```html
25
<script src="https://cdn.jsdelivr.net/npm/scriptjs@2.5.9/dist/script.js"></script>
26
```
27
28
When using Ender.js:
29
```javascript
30
// Access via ender methods
31
$.script(/* ... */);
32
$.require(/* ... */);
33
$.ready(/* ... */);
34
$.getScript(/* ... */);
35
```
36
37
## Basic Usage
38
39
```javascript
40
// Load a single script
41
$script('path/to/script.js', function() {
42
// Script is loaded and ready
43
});
44
45
// Load multiple scripts in parallel
46
$script(['jquery.js', 'plugin.js'], function() {
47
// Both scripts are loaded
48
});
49
50
// Load scripts with dependency management
51
$script(['jquery.js', 'plugin.js'], 'bundle');
52
$script('app.js').ready('bundle', function() {
53
// App runs after bundle is ready
54
});
55
```
56
57
## Architecture
58
59
$script.js is built around several key concepts:
60
61
- **Asynchronous Loading**: Scripts load in parallel without blocking page rendering
62
- **Dependency Management**: Named bundles allow complex dependency relationships
63
- **State Tracking**: Internal state management tracks loading progress and readiness
64
- **Chainable API**: Most methods return the $script object for method chaining
65
- **Path Configuration**: Global path and URL argument configuration for easier project management
66
67
## Capabilities
68
69
### Script Loading
70
71
Core functionality for loading JavaScript files asynchronously.
72
73
```javascript { .api }
74
/**
75
* Load JavaScript files asynchronously
76
* @param paths - Single path string or array of paths
77
* @param idOrDone - Bundle ID string or completion callback function
78
* @param optDone - Optional completion callback when idOrDone is an ID
79
* @returns $script object for chaining
80
*/
81
function $script(
82
paths: string | string[],
83
idOrDone?: string | (() => void),
84
optDone?: () => void
85
): typeof $script;
86
```
87
88
**Usage Examples:**
89
90
```javascript
91
// Load single script with callback
92
$script('app.js', function() {
93
console.log('App loaded');
94
});
95
96
// Load multiple scripts
97
$script(['utils.js', 'config.js'], function() {
98
console.log('Utils and config loaded');
99
});
100
101
// Load with bundle ID
102
$script(['jquery.js', 'plugin.js'], 'bundle');
103
104
// Load with ID and callback
105
$script('critical.js', 'critical', function() {
106
console.log('Critical script loaded');
107
});
108
```
109
110
### Direct Script Creation
111
112
Bypass path configuration and load scripts directly.
113
114
```javascript { .api }
115
/**
116
* Create and load a script element directly (bypasses path configuration)
117
* @param path - Script URL
118
* @param callback - Completion callback
119
*/
120
$script.get(path: string, callback: () => void): void;
121
```
122
123
**Usage Example:**
124
125
```javascript
126
$script.get('https://cdn.example.com/library.js', function() {
127
console.log('External library loaded');
128
});
129
```
130
131
### Sequential Loading
132
133
Load scripts in a specific order (synchronous dependency chain).
134
135
```javascript { .api }
136
/**
137
* Load scripts in sequential order
138
* @param scripts - Array of script paths to load in order
139
* @param id - Bundle identifier for the ordered group
140
* @param done - Completion callback
141
*/
142
$script.order(scripts: string[], id: string, done?: () => void): void;
143
```
144
145
**Usage Example:**
146
147
```javascript
148
$script.order(['base.js', 'extension.js', 'app.js'], 'ordered', function() {
149
console.log('All scripts loaded in order');
150
});
151
```
152
153
### Path Configuration
154
155
Set a base path for relative script URLs.
156
157
```javascript { .api }
158
/**
159
* Set base path for relative script URLs
160
* @param basePath - Base path to prepend to relative URLs
161
*/
162
$script.path(basePath: string): void;
163
```
164
165
**Usage Example:**
166
167
```javascript
168
$script.path('/js/modules/');
169
$script(['dom', 'event'], function() {
170
// Loads /js/modules/dom.js and /js/modules/event.js
171
});
172
```
173
174
### URL Arguments
175
176
Add query string parameters to all script URLs for cache-busting.
177
178
```javascript { .api }
179
/**
180
* Set URL arguments to append to all script URLs
181
* @param queryString - Query string to append (without leading ?)
182
*/
183
$script.urlArgs(queryString: string): void;
184
```
185
186
**Usage Example:**
187
188
```javascript
189
$script.urlArgs('v=1.2.3&bust=' + Date.now());
190
$script('app.js'); // Loads app.js?v=1.2.3&bust=1234567890
191
```
192
193
### Dependency Management
194
195
Wait for named dependencies before executing callbacks.
196
197
```javascript { .api }
198
/**
199
* Execute callback when dependencies are ready
200
* @param deps - Single dependency ID or array of IDs
201
* @param ready - Callback to execute when dependencies are ready
202
* @param req - Optional error callback with missing dependencies
203
* @returns $script object for chaining
204
*/
205
$script.ready(
206
deps: string | string[],
207
ready: () => void,
208
req?: (missing: string[]) => void
209
): typeof $script;
210
```
211
212
**Usage Examples:**
213
214
```javascript
215
// Wait for single dependency
216
$script.ready('jquery', function() {
217
// jQuery is ready
218
});
219
220
// Wait for multiple dependencies
221
$script.ready(['jquery', 'utils'], function() {
222
// Both jQuery and utils are ready
223
});
224
225
// With error handling
226
$script.ready(['required', 'optional'], function() {
227
console.log('All dependencies ready');
228
}, function(missing) {
229
console.log('Missing dependencies:', missing);
230
// Load missing dependencies
231
missing.forEach(dep => $script(dep + '.js', dep));
232
});
233
234
// Chaining ready calls
235
$script
236
.ready('jquery', function() {
237
console.log('jQuery ready');
238
})
239
.ready('bootstrap', function() {
240
console.log('Bootstrap ready');
241
});
242
```
243
244
### Manual Completion
245
246
Manually mark a dependency as complete without loading a file.
247
248
```javascript { .api }
249
/**
250
* Manually mark a dependency as complete
251
* @param id - Dependency identifier to mark complete
252
*/
253
$script.done(id: string): void;
254
```
255
256
**Usage Example:**
257
258
```javascript
259
// In a plugin file that depends on jQuery
260
$script.ready('jquery', function() {
261
// Define plugin here
262
window.MyPlugin = { /* ... */ };
263
264
// Mark this plugin as done
265
$script.done('my-plugin');
266
});
267
268
// In main app
269
$script('jquery.js', 'jquery');
270
$script('my-plugin.js'); // Will call $script.done('my-plugin') internally
271
$script.ready('my-plugin', function() {
272
// Use MyPlugin
273
});
274
```
275
276
## Advanced Usage Patterns
277
278
### Complex Dependency Management
279
280
```javascript
281
// Load core libraries
282
$script('jquery.js', 'jquery');
283
$script('lodash.js', 'lodash');
284
285
// Load plugins that depend on core libraries
286
$script('jquery-plugin.js').ready('jquery', function() {
287
// jQuery plugin code here
288
$script.done('jquery-plugin');
289
});
290
291
// Load app that depends on everything
292
$script('app.js').ready(['jquery', 'lodash', 'jquery-plugin'], function() {
293
// Start the application
294
});
295
```
296
297
### Lazy Loading with Error Handling
298
299
```javascript
300
const dependencyMap = {
301
charts: 'charts.js',
302
analytics: 'analytics.js',
303
social: 'social-widgets.js'
304
};
305
306
$script.ready(['charts', 'analytics'], function() {
307
// Both charts and analytics are ready
308
initDashboard();
309
}, function(missing) {
310
// Load missing dependencies
311
missing.forEach(function(dep) {
312
if (dependencyMap[dep]) {
313
$script(dependencyMap[dep], dep);
314
}
315
});
316
});
317
```
318
319
### Configuration for Large Projects
320
321
```javascript
322
// Set up base configuration
323
$script.path('/assets/js/');
324
$script.urlArgs('v=' + window.APP_VERSION);
325
326
// Load core modules
327
$script(['core/utils', 'core/config', 'core/api'], 'core');
328
329
// Load feature modules
330
$script(['features/dashboard', 'features/reports'], 'features');
331
332
// Initialize application
333
$script.ready(['core', 'features'], function() {
334
window.App.init();
335
});
336
```
337
338
## Browser Compatibility
339
340
- Internet Explorer 6+
341
- Opera 10+
342
- Safari 3+
343
- Chrome 1+
344
- Firefox 2+
345
346
## Error Handling
347
348
$script.js handles loading errors gracefully:
349
350
- Failed script loads still trigger callbacks
351
- `onerror` events are handled to prevent hanging
352
- Duplicate file requests are deduplicated automatically
353
- Missing dependencies can be detected and handled via `$script.ready` error callbacks