1 |
|
2 |
|
3 | <h1>@asset-pipe/client</h1>
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | <span class="badge-travisci"><a href="http://travis-ci.org/asset-pipe/asset-pipe-client" title="Check this project's build status on TravisCI"><img src="https://img.shields.io/travis/asset-pipe/asset-pipe-client/master.svg" alt="Travis CI Build Status" /></a></span>
|
11 | <span class="badge-npmversion"><a href="https://npmjs.org/package/@asset-pipe/client" title="View this project on NPM"><img src="https://img.shields.io/npm/v/@asset-pipe/client.svg" alt="NPM version" /></a></span>
|
12 | <span class="badge-daviddm"><a href="https://david-dm.org/asset-pipe/asset-pipe-client" title="View the status of this project's dependencies on DavidDM"><img src="https://img.shields.io/david/asset-pipe/asset-pipe-client.svg" alt="Dependency Status" /></a></span>
|
13 | <span class="badge-daviddmdev"><a href="https://david-dm.org/asset-pipe/asset-pipe-client#info=devDependencies" title="View the status of this project's development dependencies on DavidDM"><img src="https://img.shields.io/david/dev/asset-pipe/asset-pipe-client.svg" alt="Dev Dependency Status" /></a></span>
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | [![Greenkeeper badge](https://badges.greenkeeper.io/asset-pipe/asset-pipe-client.svg)](https://greenkeeper.io/)
|
19 |
|
20 | A client for reading an asset file entry point and uploading it as an asset feed
|
21 | to a [asset-pipe-build-server][asset-pipe-build-server] and for triggering
|
22 | builds of executable asset bundles in the said server.
|
23 |
|
24 | Creating asset bundles with [asset-pipe][asset-pipe] is a two step process. The
|
25 | first step is to upload an asset feed to the
|
26 | [asset-pipe-build-server][asset-pipe-build-server]. On upload the asset-feed
|
27 | will be persisted and the [asset-pipe-build-server][asset-pipe-build-server]
|
28 | will return the generated filename of the uploaded asset-feed.
|
29 |
|
30 | The second step is then to create a bundle out of one or multiple asset-feeds.
|
31 | This is done by providing the unique ID(s) of the asset-feeds one wants to use
|
32 | to build an asset bundle to the
|
33 | [asset-pipe-build-server][asset-pipe-build-server]. The build server will then
|
34 | create an executable asset bundle out of these asset-feeds and persist this. It
|
35 | will respond with the URL to the bundle.
|
36 |
|
37 | This client helps with remotely triggering these steps in the
|
38 | [asset-pipe-build-server][asset-pipe-build-server].
|
39 |
|
40 | ## Optimistic Bundling
|
41 |
|
42 | The asset server can produce asset bundles in what we call an "optimistic"
|
43 | fashion. This means that asset bundles will be automatically produced and
|
44 | reproduced any time an asset changes or any time the definition of which assets
|
45 | should be included in a bundle changes.
|
46 |
|
47 | This works in the following way:
|
48 |
|
49 | 1. Any number of assets are uploaded to the asset server using the
|
50 | `client.publishAssets` method.
|
51 | 2. Bundling instructions are uploaded to the asset server using the
|
52 | `client.publishInstructions` method.
|
53 |
|
54 | Steps 1 and 2 can be performed in any order and the asset server will
|
55 | automatically bundle and rebundle as needed to produce up to date bundles for
|
56 | any instructions that have been published to the server.
|
57 |
|
58 | **Examples**
|
59 |
|
60 | We might begin by first we publishing some bundling instructions. (Though we
|
61 | could just as easily publish assets first):
|
62 |
|
63 | ```js
|
64 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2']);
|
65 | ```
|
66 |
|
67 | At this point, the server will not have created any bundles as there are no
|
68 | corresponding assets for `podlet1` or `podlet2`.
|
69 |
|
70 | Next we upload the missing asset feeds for `podlet1` and `podlet2`.
|
71 |
|
72 | ```js
|
73 | const { uri, id } = await client.publishAssets('podlet1', ['/path/to/file.js']);
|
74 | const { uri, id } = await client.publishAssets('podlet2', ['/path/to/file.js']);
|
75 | ```
|
76 |
|
77 | Once both these asset feeds are in place, the asset server will generate a fresh
|
78 | bundle based on our earlier published instructions. Once finished, a new bundle
|
79 | file will be available from the asset server.
|
80 |
|
81 | ### Calculating the location of produced bundle files
|
82 |
|
83 | When `publishAssets` is successfully called, a unique asset hash `id` property
|
84 | will be available on the returned object. sha256 hashing all asset hashes
|
85 | together (in the same order they are defined in the publish instructions) and
|
86 | appending the correct file extension to the result will give you the filename of
|
87 | the resulting bundle.
|
88 |
|
89 | **Example**
|
90 |
|
91 | First publish assets and instructions
|
92 |
|
93 | ```js
|
94 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2']);
|
95 | const result1 = await client.publishAssets('podlet1', ['/path/to/file.js']);
|
96 | const result2 = await client.publishAssets('podlet2', ['/path/to/file.js']);
|
97 | ```
|
98 |
|
99 | Next, compute a hash and resulting filename
|
100 |
|
101 | ```js
|
102 | const hash = sha256Somehow(result1.id, result2.id);
|
103 | const bundleFilename = `${hash}.js`;
|
104 | ```
|
105 |
|
106 | Finally, the file can be retrieved from the asset server via the `/bundle`
|
107 | endpoint.
|
108 |
|
109 | ```bash
|
110 | GET http://<asset-server-url>/bundle/<hash>.js
|
111 | ```
|
112 |
|
113 | To make some of this a little easier, 2 helper methods exist on the client:
|
114 |
|
115 | - `bundleURL` - calculates the url location for a bundle based on a given array of asset hashes.
|
116 | - `bundlingComplete` - determines if bundling is complete for a given array of asset hashes.
|
117 |
|
118 | See API documentation below for more information.
|
119 |
|
120 | ## Installation
|
121 |
|
122 | ```bash
|
123 | $ npm install @asset-pipe/client
|
124 | ```
|
125 |
|
126 | ## Example I
|
127 |
|
128 | Read an [CommonJS module][commonjs] entry point and upload it as an asset-feed
|
129 | to the [asset-pipe-build-server][asset-pipe-build-server]:
|
130 |
|
131 | ```js
|
132 | const Client = require('@asset-pipe/client');
|
133 |
|
134 | const client = new Client({
|
135 | serverId: 'my-app-1',
|
136 | server: 'http://127.0.0.1:7100'
|
137 | });
|
138 |
|
139 | client
|
140 | .uploadFeed(['path/to/myFrontendCode.js'])
|
141 | .then(content => {
|
142 | // content contains filename of created the asset-feed
|
143 | console.log(content);
|
144 | })
|
145 | .catch(error => {
|
146 | console.log(error);
|
147 | });
|
148 | ```
|
149 |
|
150 | ## Example II
|
151 |
|
152 | Read a CSS file entry point and upload it as an asset-feed to the
|
153 | [asset-pipe-build-server][asset-pipe-build-server]:
|
154 |
|
155 | ```js
|
156 | const Client = require('@asset-pipe/client');
|
157 |
|
158 | const client = new Client({
|
159 | server: 'http://127.0.0.1:7100'
|
160 | });
|
161 |
|
162 | client
|
163 | .uploadFeed(['/path/to/styles.css'])
|
164 | .then(content => {
|
165 | // content contains filename of created the asset-feed
|
166 | console.log(content);
|
167 | })
|
168 | .catch(error => {
|
169 | console.log(error);
|
170 | });
|
171 | ```
|
172 |
|
173 | ## Example III
|
174 |
|
175 | Build a javascript bundle out of two asset feeds:
|
176 |
|
177 | ```js
|
178 | const Client = require('@asset-pipe/client');
|
179 | const client = new Client({
|
180 | serverId: 'my-app-2',
|
181 | server: 'http://127.0.0.1:7100'
|
182 | });
|
183 |
|
184 | bundle
|
185 | .createRemoteBundle(
|
186 | [
|
187 | 'f09a737b36b7ca19a224e0d78cc50222d636fd7af6f7913b01521590d0d7fe02.json',
|
188 | 'c50ca03a63650502e1b72baf4e493d2eaa0e4aa38aa2951825e101b1d6ddb68b.json'
|
189 | ],
|
190 | 'js'
|
191 | )
|
192 | .then(content => {
|
193 | // content contains URI to the created bundle
|
194 | console.log(content);
|
195 | })
|
196 | .catch(error => {
|
197 | console.log(error);
|
198 | });
|
199 | ```
|
200 |
|
201 | ## Example IIII
|
202 |
|
203 | Build a CSS bundle out of two asset feeds:
|
204 |
|
205 | ```js
|
206 | const Client = require('@asset-pipe/client');
|
207 | const client = new Client({
|
208 | server: 'http://127.0.0.1:7100'
|
209 | });
|
210 |
|
211 | bundle
|
212 | .createRemoteBundle(
|
213 | [
|
214 | 'f09a737b36b7ca19a224e0d78cc50222d636fd7af6f7913b01521590d0d7fe02.json',
|
215 | 'c50ca03a63650502e1b72baf4e493d2eaa0e4aa38aa2951825e101b1d6ddb68b.json'
|
216 | ],
|
217 | 'css'
|
218 | )
|
219 | .then(content => {
|
220 | // content contains URI to the created bundle
|
221 | console.log(content);
|
222 | })
|
223 | .catch(error => {
|
224 | console.log(error);
|
225 | });
|
226 | ```
|
227 |
|
228 | ## API
|
229 |
|
230 | Under the hood, when working with javascript, the [asset-pipe][asset-pipe]
|
231 | project builds on [browserify][browserify]. Multiple methods in this module are
|
232 | therefor underlaying Browserify methods where all features found in Browserify
|
233 | can be used. Such methods will in this documentation point to the related
|
234 | documentation in Browserify.
|
235 |
|
236 | When working with CSS the underlying POST CSS is used but the implementation is
|
237 | not exposed so there are no additional supported methods.
|
238 |
|
239 | This module has the following API:
|
240 |
|
241 | ### constructor(options)
|
242 |
|
243 | Supported arguments are:
|
244 |
|
245 | - `options.server` - Required URI to the
|
246 | [asset-pipe-build-server][asset-pipe-build-server]
|
247 | - `options.serverId` - An optional unique name to identify the deployed server
|
248 | (required for runtime optimistic bundling)
|
249 | - `options.minify` - Use minification (optimistic bundling only) `true|false` Not providing this option will result in server default being used.
|
250 | - `options.sourceMaps` - (experimental) Use sourceMaps (optimistic bundling only) `true|false` Not providing this option will result in server default being used.
|
251 | - `options.logger` - An optional log4js compatible logger. See [abslog](https://www.npmjs.com/package/abslog) for more information
|
252 | - `options.development` - Puts the client in development mode. For use with the client.middleware() function (see below). Default `false`
|
253 | - `options.tag` - Optionally define a tag to be used when publishing assets to an asset server. For use with the client.middleware() function (see below). Required when `publish` is `true`.
|
254 | - `options.js` - Optionally define the full path to a JavaScript file. For use with the client.middleware() function (see below)
|
255 | - `options.css` - Optionally define the full path to a CSS style file. For use with the client.middleware() function (see below)
|
256 |
|
257 | ### transform()
|
258 |
|
259 | Same as the [Browserify transform][browserify-transform] method. _NOTE:_ Only
|
260 | applicable when uploading javascript feeds.
|
261 |
|
262 | ### plugin()
|
263 |
|
264 | Same as the [Browserify plugin][browserify-plugin] method. _NOTE:_ Only
|
265 | applicable when uploading javascript feeds.
|
266 |
|
267 | ### uploadFeed(files)
|
268 |
|
269 | Read the [CommonJS module][commonjs] or CSS file entry point and uploads it as
|
270 | an asset feed to the [asset-pipe-build-server][asset-pipe-build-server].
|
271 |
|
272 | - `files` - Array - Either list of CommonJS module entry points - Same as
|
273 | `files` in the [Browserify constructor][browserify-opts] OR list of paths to
|
274 | CSS files
|
275 |
|
276 | Returns a promise.
|
277 |
|
278 | ### createRemoteBundle(feeds, type)
|
279 |
|
280 | Creates an asset bundle on the
|
281 | [asset-pipe-build-server][asset-pipe-build-server].
|
282 |
|
283 | - `feeds` - Array - List of asset-feed filenames.
|
284 | - `type` - string - Either 'js' or 'css'
|
285 |
|
286 | ### sync()
|
287 |
|
288 | Fetches centralised configuration information from the asset server.
|
289 | This should be called after creating a new client instance and before any calls to `.bundleURL()` or `.bundlingComplete()`
|
290 |
|
291 | **Example**
|
292 |
|
293 | ```js
|
294 | const client = new Client(options);
|
295 | await client.sync();
|
296 | ```
|
297 |
|
298 | ### publishAssets(tag, entrypoints, options)
|
299 |
|
300 | Publishes assets to the asset server for use in optimisitic bundling. Bundles
|
301 | will be created according to bundle instructions published using the
|
302 | `publishInstructions` method.
|
303 |
|
304 | - `tag` - `string` - Alphanumeric string identifying the publisher. Should be
|
305 | unique.
|
306 | - `entrypoints` - `Array|string` - Array of asset entrypoint filenames or single asset entrypoint filename string to be published to the asset server.
|
307 | - `options` - `object` - Bundling options. `{minify: true|false, sourceMaps: true|false}` Setting these options here will override the same options provided to the constructor
|
308 |
|
309 | `return` - `object` - An object with keys `id` (refering to the unique asset
|
310 | hash) and `uri` (referring to the location of the published asset on the
|
311 | server).
|
312 |
|
313 | **Examples**
|
314 |
|
315 | JavaScript
|
316 |
|
317 | ```js
|
318 | const { uri, id } = await client.publishAssets('podlet1', '/path/to/file.js');
|
319 | ```
|
320 |
|
321 | CSS
|
322 |
|
323 | ```js
|
324 | const { uri, id } = await client.publishAssets('podlet1', '/path/to/file.css');
|
325 | ```
|
326 |
|
327 | With minification
|
328 |
|
329 | ```js
|
330 | const { uri, id } = await client.publishAssets('podlet1', '/path/to/file.js', {
|
331 | minify: true
|
332 | });
|
333 | ```
|
334 |
|
335 | ### publishInstructions(tag, type, data, options)
|
336 |
|
337 | Publishes bundling instructions to the asset server for use in optimisitic
|
338 | bundling. Bundles are generated as specified by the `data` array. Anytime new
|
339 | instructions are published (via `publishInstructions`) or assets are published
|
340 | (via `publishAssets`), new bundles will be generated by the server.
|
341 |
|
342 | - `tag` - `string` - Alphanumeric string identifying the publisher. Should be
|
343 | unique.
|
344 | - `type` - `string` - Asset type. Valid values are 'js' and 'css'
|
345 | - `data` - `array` - Array of tags to bundle together. Each tag must refer to
|
346 | the tag property given when publishing assets using the `publishAssets`
|
347 | method.
|
348 | - `options` - `object` - Bundling options. `{minify: true|false, sourceMaps: true|false}` Setting these options here will override the same options provided to the constructor
|
349 |
|
350 | `return` - 204 No Content is returned when publishing has successfully completed.
|
351 |
|
352 | **Examples**
|
353 |
|
354 | JavaScript
|
355 |
|
356 | ```js
|
357 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2']);
|
358 | ```
|
359 |
|
360 | CSS
|
361 |
|
362 | ```js
|
363 | await client.publishInstructions('layout', 'css', ['podlet1', 'podlet2']);
|
364 | ```
|
365 |
|
366 | With minification
|
367 |
|
368 | ```js
|
369 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2'], {
|
370 | minify: true
|
371 | });
|
372 | ```
|
373 |
|
374 | ### bundleURL(feedHashes, options)
|
375 |
|
376 | Calculates a bundle url string based on a given array of hashes which are asset feed content hashes. Each time an asset feed is published using `client.publishAssets` the resolved object will contain an `id` property which is the hash of the feed content and can be used with this method.
|
377 |
|
378 | Calculation is done by sha256 hashing together the given `hashes` and dropping the resulting hash into a url template.
|
379 |
|
380 | As such, this method does not perform any requests to the server and therefore cannot guarantee that the bundle exists on the server.
|
381 |
|
382 | **Note:** You should call `await client.sync();` one time after creating the client instance, before calling `bundleURL` to ensure the client has update information about the public location of bundle files.
|
383 |
|
384 | - `hashes` - `string[]` - array of asset feed content hashes as returned by `client.publishAssets`
|
385 | - `options` - `object`
|
386 | - `options.prefix` - `string` url prefix to use when building bundle url. Defaults to `${client.server}/bundle/` which is the location on the asset server that a bundle can be located. Overwrite this if you use a CDN and need to point to that.
|
387 | - `options.type` - `string` (`js`|`css`) - file type. Defaults to `js`
|
388 |
|
389 | `return` - `Promise<string>` - url for asset bundle on asset server.
|
390 |
|
391 | **Example**
|
392 |
|
393 | ```js
|
394 | // publish instructions
|
395 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2']);
|
396 |
|
397 | // publish necessary assets
|
398 | const { uri, id1 } = await client.publishAssets('podlet1', [
|
399 | '/path/to/file.js'
|
400 | ]);
|
401 | const { uri, id2 } = await client.publishAssets('podlet2', [
|
402 | '/path/to/file.js'
|
403 | ]);
|
404 |
|
405 | // calculate the url of the finished bundle
|
406 | const url = await client.bundleURL([id1, id2]);
|
407 | ```
|
408 |
|
409 | ### bundlingComplete(feedhashes, options)
|
410 |
|
411 | Calculates whether a bundling for the given `feedHashes` has been completed. The rules for this method are as follows:
|
412 |
|
413 | **Note:** You should call `await client.sync();` one time after creating the client instance, before calling `bundleURL` to ensure the client has update information about the public location of bundle files.
|
414 |
|
415 | - If `feedHashes` is an empty array, this method resolves to `true` as no bundle needs to be built.
|
416 | - Otherwise, if `feedHashes` is not an empty array then a bundle url will be computed and a request made to check if the file exists on the server.
|
417 |
|
418 | - `hashes` - `string[]` - array of asset feed content hashes as returned by `client.publishAssets`
|
419 | - `options` - `object`
|
420 | - `options.prefix` - `string` url prefix to use when building bundle url. Defaults to `${client.server}/bundle/` which is the location on the asset server that a bundle can be located. Overwrite this if you use a CDN and need to point to that.
|
421 | - `options.type` - `string` (`js`|`css`) - file type. Defaults to `js`
|
422 |
|
423 | `return` - `Promise<boolean>` - resolves to a boolean representing whether the bundling process for the given `feedHashes` is considered to be complete.
|
424 |
|
425 | **Example**
|
426 |
|
427 | ```js
|
428 | // publish instructions
|
429 | await client.publishInstructions('layout', 'js', ['podlet1', 'podlet2']);
|
430 |
|
431 | // publish necessary assets
|
432 | const { uri, id1 } = await client.publishAssets('podlet1', [
|
433 | '/path/to/file.js'
|
434 | ]);
|
435 | const { uri, id2 } = await client.publishAssets('podlet2', [
|
436 | '/path/to/file.js'
|
437 | ]);
|
438 |
|
439 | // calculate the url of the finished bundle
|
440 | const isComplete = await client.bundlingComplete([id1, id2]);
|
441 | ```
|
442 |
|
443 | ### .middleware()
|
444 |
|
445 | This method returns a connect middleware that can be used to both support assets in local development and to ensure assets are published before the request completes.
|
446 |
|
447 | When `.middleware()` is called and the client flag `development` is set to `true` then assets
|
448 | will be provided at `/js` and `/css` on your app. Additionally, file system watching will be enabled for JavaScript.
|
449 |
|
450 | **N.B.** You must call `.publish()` and provide `js` and/or `css` options for development mode to work.
|
451 |
|
452 | _Example_
|
453 |
|
454 | ```js
|
455 | const client = new Client({
|
456 | ...
|
457 | development: true,
|
458 | ...
|
459 | });
|
460 |
|
461 | client.publish({
|
462 | js: '/path/to/script.js',
|
463 | css: '/path/to/style.js',
|
464 | });
|
465 |
|
466 | app.use(client.middleware());
|
467 |
|
468 | // curl http:<address>:<port>/js => bundled js scripts
|
469 | // curl http:<address>:<port>/css => bundled css styles
|
470 | ```
|
471 |
|
472 | When `.middleware()` is called and the client flag `development` is `false` then the middleware will force requests to wait until `client.ready()` resolves to `true`. This will ensure that any publishing or bundling has completed before route handlers are invoked.
|
473 |
|
474 | _Example_
|
475 |
|
476 | ```js
|
477 | const client = new Client({
|
478 | ...
|
479 | server: 'http://asset-server.com:1234',
|
480 | tag: 'uniqueLabel',
|
481 | development: false,
|
482 | ...
|
483 | });
|
484 |
|
485 | client.publish({ ... });
|
486 | client.bundle({ ... });
|
487 |
|
488 | app.use(client.middleware());
|
489 |
|
490 | app.get('/', (req, res) => {
|
491 | // publishing and bundling have completed before we get
|
492 | // here
|
493 | })
|
494 | ```
|
495 |
|
496 | ### .js()
|
497 |
|
498 | Method for retrieving the id hash for JavaScript assets uploaded to an asset server
|
499 |
|
500 | ```js
|
501 | const client = new Client({
|
502 | ...
|
503 | server: 'http://asset-server.com:1234',
|
504 | tag: 'uniqueLabel',
|
505 | development: false,
|
506 | ...
|
507 | })
|
508 |
|
509 | client.publish({ ... });
|
510 | client.js() // => null
|
511 |
|
512 | app.use(client.middleware());
|
513 |
|
514 | app.get('/', (req, res) => {
|
515 | client.js() // a2b2ab2a2b2b3bab4ab4aa22babab2ba2
|
516 | })
|
517 | ```
|
518 |
|
519 | ### .css()
|
520 |
|
521 | Method for retrieving the id hash for CSS assets uploaded to an asset server
|
522 |
|
523 | ```js
|
524 | const client = new Client({
|
525 | ...
|
526 | server: 'http://asset-server.com:1234',
|
527 | tag: 'uniqueLabel',
|
528 | development: false,
|
529 | ...
|
530 | })
|
531 |
|
532 | client.publish({ ... });
|
533 | client.css() // => null
|
534 |
|
535 | app.use(client.middleware());
|
536 |
|
537 | app.get('/', (req, res) => {
|
538 | client.css() // b2b2ac2a2b4b3bab4ab2aa22babab2ba2
|
539 | })
|
540 | ```
|
541 |
|
542 | ### .ready()
|
543 |
|
544 | Method for waiting until assets have finished publishing to or bundling on an asset server.
|
545 |
|
546 | ```js
|
547 | const client = new Client({
|
548 | ...
|
549 | server: 'http://asset-server.com:1234',
|
550 | tag: 'uniqueLabel',
|
551 | development: false,
|
552 | ...
|
553 | });
|
554 |
|
555 | client.publish({ ... });
|
556 |
|
557 | client.css() // => null
|
558 |
|
559 | await client.ready();
|
560 |
|
561 | client.js() // a2b2ab2a2b2b3bab4ab4aa22babab2ba2
|
562 | client.css() // b2b2ac2a2b4b3bab4ab2aa22babab2ba2
|
563 | ```
|
564 |
|
565 | ### .publish()
|
566 |
|
567 | Method to publish JavaScript and/or CSS assets to an asset server. Returns a promise which resolves when publishing is done.
|
568 |
|
569 | ```js
|
570 | const client = new Client({
|
571 | server: 'http://asset-server.com:1234',
|
572 | tag: 'uniqueLabel'
|
573 | });
|
574 |
|
575 | const { js, css } = await client.publish({
|
576 | js: '/path/to/script.js',
|
577 | css: '/path/to/styles.css'
|
578 | });
|
579 | // js => a2b2ab2a2b2b3bab4ab4aa22babab2ba2
|
580 | // css => b2b2ac2a2b4b3bab4ab2aa22babab2ba2
|
581 | ```
|
582 |
|
583 | It is not necessary to wait for publish to complete. You can also call publish to kick off publishing and then wait for the `.ready()` method to resolve to know when publishing is complete.
|
584 |
|
585 | ```js
|
586 | const client = new Client({
|
587 | server: 'http://asset-server.com:1234',
|
588 | tag: 'uniqueLabel'
|
589 | });
|
590 |
|
591 | client.publish({
|
592 | js: '/path/to/script.js',
|
593 | css: '/path/to/styles.css'
|
594 | });
|
595 |
|
596 | await client.ready();
|
597 | ```
|
598 |
|
599 | If you use `.middleware()` in your connect based applications, waiting for publish completion will happen automatically.
|
600 |
|
601 | ```js
|
602 | const client = new Client({
|
603 | server: 'http://asset-server.com:1234',
|
604 | tag: 'uniqueLabel'
|
605 | });
|
606 |
|
607 | client.publish({
|
608 | js: '/path/to/script.js',
|
609 | css: '/path/to/styles.css'
|
610 | });
|
611 |
|
612 | app.use(client.middleware());
|
613 | ```
|
614 |
|
615 | ### .bundle()
|
616 |
|
617 | Method to instruct an asset server to bundle JavaScript and/or CSS assets. Returns a promise which resolves when bundling is done.
|
618 |
|
619 | ```js
|
620 | const client = new Client({
|
621 | server: 'http://asset-server.com:1234',
|
622 | tag: 'uniqueLabel'
|
623 | });
|
624 |
|
625 | await client.bundle({ js: ['tag1', 'tag2'], css: ['tag1', 'tag2'] });
|
626 | ```
|
627 |
|
628 | It is not necessary to wait for bundle to complete. You can also call bundle to kick off bundling and then wait for the `.ready()` method to resolve to know when bundling is complete.
|
629 |
|
630 | ```js
|
631 | const client = new Client({
|
632 | server: 'http://asset-server.com:1234',
|
633 | tag: 'uniqueLabel'
|
634 | });
|
635 |
|
636 | client.bundle({ js: ['tag1', 'tag2'], css: ['tag1', 'tag2'] });
|
637 |
|
638 | await client.ready();
|
639 | ```
|
640 |
|
641 | If you use `.middleware()` in your connect based applications, waiting for bundle completion will happen automatically.
|
642 |
|
643 | ```js
|
644 | const client = new Client({
|
645 | server: 'http://asset-server.com:1234',
|
646 | tag: 'uniqueLabel'
|
647 | });
|
648 |
|
649 | client.bundle({ js: ['tag1', 'tag2'], css: ['tag1', 'tag2'] });
|
650 |
|
651 | app.use(client.middleware());
|
652 | ```
|
653 |
|
654 | ### .scripts(hashes)
|
655 |
|
656 | Method to retrieve JavaScript bundle URLs once publishing and bundling are complete. Includes a best effort algorithm to try to return an optimally bundled solution, falling back to multiple individual bundles when an optimal bundle is not available.
|
657 |
|
658 | _Example: Requesting a bundling for 2 tags when only 1 has been published_
|
659 |
|
660 | ```js
|
661 | const client = new Client({
|
662 | server: 'http://asset-server.com:1234',
|
663 | tag: 'tag1'
|
664 | });
|
665 |
|
666 | const { js } = await client.publish({ ... });
|
667 | await client.bundle({ js: ['tag1', 'tag2'] });
|
668 |
|
669 | const scripts = client.scripts([js]);
|
670 | // scripts => [http://<asset-server-url>/bundle/${js}.js]
|
671 | ```
|
672 |
|
673 | This method will always return an array so you can iterate over it in your templates and create script tags
|
674 |
|
675 | ```njk
|
676 | {% for script in scripts %}
|
677 | <script src={{ script }}></script>
|
678 | {% endfor %}
|
679 | ```
|
680 |
|
681 | ### .styles()
|
682 |
|
683 | Method to retrieve css bundle URLs once publishing and bundling are complete. Includes a best effort algorithm to try to return an optimally bundled solution, falling back to multiple individual bundles when an optimal bundle is not available.
|
684 |
|
685 | _Example: Requesting a bundling for 2 tags when only 1 has been published_
|
686 |
|
687 | ```js
|
688 | const client = new Client({
|
689 | server: 'http://asset-server.com:1234',
|
690 | tag: 'tag1'
|
691 | });
|
692 |
|
693 | const { css } = await client.publish({ ... });
|
694 | await client.bundle({ css: ['tag1', 'tag2'] });
|
695 |
|
696 | const styles = client.styles([css]);
|
697 | // styles => [http://<asset-server-url>/bundle/${css}.css]
|
698 | ```
|
699 |
|
700 | This method will always return an array so you can iterate over it in your templates and create style tags
|
701 |
|
702 | ```njk
|
703 | {% for style in styles %}
|
704 | <link rel="stylesheet" href={{ style }} />
|
705 | {% endfor %}
|
706 | ```
|
707 |
|
708 | ### .metrics
|
709 |
|
710 | This module uses [@metrics/client](https://www.npmjs.com/package/@metrics/client) to expose metric objects for consumption via a stream.
|
711 |
|
712 | Available metric names are:
|
713 |
|
714 | - publish_assets_timer
|
715 | - publish_instructions_timer
|
716 | - asset_server_sync_timer
|
717 |
|
718 | **Example: piping metrics stream into a consumer**
|
719 |
|
720 | ```js
|
721 | client.metrics.pipe(consumer);
|
722 | ```
|
723 |
|
724 | See [@metrics/client](https://www.npmjs.com/package/@metrics/client) for more details including how to implement a consumer.
|
725 |
|
726 | ## Transpilers
|
727 |
|
728 | Since [asset-pipe][asset-pipe] is built on [browserify][browserify] under the
|
729 | hood, its fully possible to take advantage of the different transpiers available
|
730 | for [browserify][browserify] when working with javascript.
|
731 |
|
732 | As an example, here is how Babel is applied:
|
733 |
|
734 | ```js
|
735 | const babelify = require('babelify');
|
736 | const Client = require('@asset-pipe/client');
|
737 |
|
738 | const client = new Client({ server: 'http://127.0.0.1:7100' });
|
739 |
|
740 | client.transform(babelify, { presets: ['es2015'] });
|
741 |
|
742 | const { uri, id } = await client.publishAssets('podlet1', ['/path/to/file.js']);
|
743 | ```
|
744 |
|
745 | ## Contributing
|
746 |
|
747 | The contribution process is as follows:
|
748 |
|
749 | - Fork this repository.
|
750 | - Make your changes as desired.
|
751 | - Run the tests using `npm test`. This will also check to ensure that 100% code
|
752 | coverage is maintained. If not you may need to add additional tests.
|
753 | - Stage your changes.
|
754 | - Run `git commit` or, if you are not familiar with [semantic commit
|
755 | messages](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit),
|
756 | please run `npm run cm` and follow the prompts instead which will help you
|
757 | write a correct semantic commit message.
|
758 | - Push your changes and submit a PR.
|
759 |
|
760 | [commonjs]: https://nodejs.org/docs/latest/api/modules.html
|
761 | [asset-pipe]: https://github.com/asset-pipe
|
762 | [asset-pipe-build-server]: https://github.com/asset-pipe/asset-pipe-build-server
|
763 | [browserify]: https://github.com/substack/node-browserify
|
764 | [browserify-opts]: https://github.com/substack/node-browserify#browserifyfiles--opts
|
765 | [browserify-plugin]: https://github.com/substack/node-browserify#bpluginplugin-opts
|
766 | [browserify-transform]: https://github.com/substack/node-browserify#btransformtr-opts
|