1 | [![Build Status](https://travis-ci.org/Polymer/polymer-bundler.svg?branch=master)](https://travis-ci.org/Polymer/polymer-bundler)
|
2 | [![NPM version](http://img.shields.io/npm/v/polymer-bundler.svg)](https://www.npmjs.com/package/polymer-bundler)
|
3 |
|
4 | # Polymer Bundler
|
5 |
|
6 | polymer-bundler is a library for packaging project assets for production to minimize network round-trips.
|
7 |
|
8 |
|
9 | ## Relationship to Polymer CLI
|
10 |
|
11 | The [Polymer CLI](https://github.com/Polymer/polymer-cli) uses [polymer-build](https://github.com/Polymer/polymer-build), which uses polymer-bundler, so you can think of the CLI's build pre-configured polymer-build pipeline including polymer-bundler. Setting this up for you makes the CLI easy to use, but as a command-line wrapper its customization options are more limited. polymer-bundler allows you to completely customize your bundle strategy.
|
12 |
|
13 | ## Usage
|
14 |
|
15 | Web pages that use multiple [HTML Imports](http://www.html5rocks.com/en/tutorials/webcomponents/imports/), external scripts, and stylesheets to load dependencies may end up making lots of network round-trips. In many cases, this can lead to long initial load times and unnecessary bandwidth usage. The polymer-bundler tool follows HTML Imports, external script and stylesheet references, inlining these external assets into "bundles", to be used in production.
|
16 |
|
17 | In the future, technologies such as [HTTP/2](http://en.wikipedia.org/wiki/HTTP/2) and [Server Push](https://http2.github.io/faq/#whats-the-benefit-of-server-push) will likely obsolete the need for a tool like polymer-bundler for web deployment uses.
|
18 |
|
19 |
|
20 | ## Installation
|
21 |
|
22 | `polymer-bundler` is available on npm. For maximium utility, `polymer-bundler` should be installed globally.
|
23 |
|
24 | npm install -g polymer-bundler
|
25 |
|
26 | This will install `polymer-bundler` to `/usr/local/bin/polymer-bundler` (you may need `sudo`
|
27 | for this step).
|
28 |
|
29 | ## Options
|
30 | - `-h`|`--help`: Print this message
|
31 | - `-v`|`--version`: Print version number
|
32 | - `-r`|`--root`: The root of the package/project being bundled. Defaults to the current working folder.
|
33 | - `--exclude <path>`: Exclude a subpath from root. Use multiple times to exclude multiple paths. Tags (imports/scripts/etc) that reference an excluded path are left in-place, meaning the resources are not inlined. ex: `--exclude=elements/x-foo.html --exclude=elements/x-bar.html`
|
34 | - `--inline-scripts`: External scripts will only be inlined if this flag is provided.
|
35 | - `--inline-css`: External stylesheets will only be inlined if this flag is provided.
|
36 | - `--manifest-out <path>`: If specified, the bundle manifest will be written out to `<path>`.
|
37 | - `--redirect <prefix>|<path>`: Routes URLs with arbitrary `<prefix>`, possibly including a protocol, hostname, and/or path prefix to a `<path>` on local filesystem. For example `--redirect "myapp://|src"` would route `myapp://main/home.html` to `./src/main/home.html`. Multiple redirects may be specified; the earliest ones have the highest priority.
|
38 | - `--rewrite-urls-in-templates`: Fix URLs found inside `<style>` tags and certain element attributes (`action`, `assetpath`, `href`, `src`, and `style`) when inside `<template>` tags. This may be necessary to bundle some Polymer 1.x projects with components that ues relative image urls in their styles, as Polymer 1.x did not use the `assetpath` of `<dom-module>` to resolve urls in styles like Polymer 2.x does.
|
39 | - `--shell`: Uses a bundling strategy which puts inlines shared dependencies into a specified html app "shell".
|
40 | - `--strip-comments`: Strips all HTML comments from the document which do not contain an `@license`, or start with `<!--#` or `<!--!`.
|
41 | - `--sourcemaps`: Honor (or create) sourcemaps for inline script tags.
|
42 | - `--out-html <path>`: If specified, output will be written to <path> instead of stdout.
|
43 | - `--out-dir <path>`: If specified, output will be written to <path>. Necessary if bundling multiple files.
|
44 |
|
45 | ## Usage
|
46 | The command
|
47 |
|
48 | polymer-bundler target.html
|
49 |
|
50 | will inline the HTML Imports of `target.html` and print the resulting HTML to standard output.
|
51 |
|
52 | The command
|
53 |
|
54 | polymer-bundler target.html --rewrite-urls-in-templates
|
55 |
|
56 | will inline the HTML Imports of `target.html` and rewrite relative urls encountered in style tags and element attributes to support Polymer 1.x projects which may rely on it.
|
57 |
|
58 | The command
|
59 |
|
60 | polymer-bundler target.html > build.html
|
61 |
|
62 | will inline the HTML Imports of `target.html` and print the result to `build.html`.
|
63 |
|
64 | The command
|
65 |
|
66 | polymer-bundler -p "path/to/target/" /target.html
|
67 |
|
68 | will inline the HTML Imports of `target.html`, treat `path/to/target/` as the webroot of target.html, and make all urls absolute to the provided webroot.
|
69 |
|
70 | The command
|
71 |
|
72 | polymer-bundler --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html
|
73 |
|
74 | will inline the HTML Imports of `target.html` that are not in the directory `path/to/target/subpath` nor `path/to/target/subpath2`.
|
75 |
|
76 | The command
|
77 |
|
78 | polymer-bundler --inline-scripts target.html
|
79 |
|
80 | will inline scripts in `target.html` as well as HTML Imports. Exclude flags will apply to both Imports and Scripts.
|
81 |
|
82 | The command
|
83 |
|
84 | polymer-bundler --inline-css target.html
|
85 |
|
86 | will inline Polymerized stylesheets, `<link rel="import" type="css">`
|
87 |
|
88 | The command
|
89 |
|
90 | polymer-bundler --strip-comments target.html
|
91 |
|
92 | will remove HTML comments, except for those containing `@license` or starting with `<!--#` or `<!--!`. License comments will be deduplicated.
|
93 |
|
94 | The command
|
95 |
|
96 | polymer-bundler --redirect "myapp://|src" target.html
|
97 |
|
98 | will route all URLs with prefix `myapp://` to the `src` folder. So a url like `myapp://main/index.html` would actually resolve to a file in `./src/main/index.html` relative to the package root.
|
99 |
|
100 | ## Using polymer-bundler programmatically
|
101 |
|
102 | polymer-bundler as a library has two exported function.
|
103 |
|
104 | `polymer-bundler` constructor takes an object of options similar to the command line options:
|
105 |
|
106 | - `analyzer`: An instance of `polymer-analyzer` which provides analysis of and access to files to bundle. Bundler will create its own instance if this is not given.
|
107 | - `excludes`: URLs to exclude from inlining. URLs may represent files or folders. HTML tags referencing excluded URLs are preserved.
|
108 | - `sourcemaps`: Honor (or create) sourcemaps for inline scripts
|
109 | - `inlineCss`: Will inline content of external stylesheets into the bundle html. Defaults to `true`.
|
110 | - `inlineScripts`: Inline content of external scripts into the bundled html. Defaults to `true`.
|
111 | - `rewriteUrlsInTemplates`: Fix URLs found inside `<style>` tags and certain element attributes (`action`, `assetpath`, `href`, `src`, and `style`) when inside `<template>` tags. This may be necessary to bundle some Polymer 1.x projects with components that ues relative image urls in their styles, as Polymer 1.x did not use the `assetpath` of `<dom-module>` to resolve urls in styles like Polymer 2.x does. Defaults to `false`.
|
112 | - `sourcemaps`: Honor (or create) sourcemaps for inline scripts. Defaults to `false`.
|
113 | - `stripComments`: Remove all HTML comments, except for `@license`, which are merely de-duplicated, server-side include directives like `<!--# ... -->`, and other important comments of the form `<!--! ... -->`. Defaults to `false`.
|
114 | - `strategy`: A function that takes an array of bundles and returns an array of bundles. There are a strategy factory functions available in [bundle-manifest](https://github.com/Polymer/polymer-bundler/blob/master/src/bundle-manifest.ts).
|
115 | - `urlMapper`: A function that takes bundles and returns a Map of urls to bundles. This determines the location of generated bundles. There are url mapper factory functions available in [bundle-manifest](https://github.com/Polymer/polymer-bundler/blob/master/src/bundle-manifest.ts)
|
116 |
|
117 | `.generateManifest()` takes a collection of entrypoint urls and promises a `BundleManifest` which describes all the bundles it will produce.
|
118 |
|
119 | `.bundle()` takes a `BundleManifest` and returns a `Promise` for a `BundleResult`, which contains a map of the generated bundle html files and an updated manifest containing information on what imports were inlined for each `Bundle`.
|
120 |
|
121 | A simple example:
|
122 | ```js
|
123 | const parse5 = require('parse5');
|
124 | const bundler = new require('polymer-bundler').Bundler();
|
125 | bundler.generateManifest(['my-app.html']).then((manifest) => {
|
126 | bundler.bundle(manifest).then((result) => {
|
127 | console.log('<!-- BUNDLED VERSION OF my-app.html: -->');
|
128 | console.log(parse5.serialize(result.documents.get('my-app.html').ast));
|
129 | });
|
130 | });
|
131 | ```
|
132 |
|
133 | An example with a customized sharding strategy and output layout:
|
134 | ```js
|
135 | const {Analyzer, FSUrlLoader} = require('polymer-analyzer');
|
136 | const analyzer = new Analyzer({
|
137 | urlLoader: new FSUrlLoader(path.resolve('.'))
|
138 | });
|
139 |
|
140 | const {Bundler,
|
141 | generateSharedDepsMergeStrategy,
|
142 | generateCountingSharedBundleUrlMapper} = require('polymer-bundler');
|
143 | const bundler = new Bundler({
|
144 | analyzer: analyzer,
|
145 | excludes: [],
|
146 | inlineScripts: true,
|
147 | inlineCss: true,
|
148 | rewriteUrlsInTemplates: false,
|
149 | stripComments: true,
|
150 | // Merge shared dependencies into a single bundle when
|
151 | // they have at least three dependents.
|
152 | strategy: generateSharedDepsMergeStrategy(3),
|
153 | // Shared bundles will be named:
|
154 | // `shared/bundle_1.html`, `shared/bundle_2.html`, etc...
|
155 | urlMapper: generateCountingSharedBundleUrlMapper('shared/bundle_')
|
156 | });
|
157 |
|
158 | // Provide the strategy and the url mapper to produce a
|
159 | // manifest using custom behavior.
|
160 | bundler.generateManifest(['item.html', 'cart.html']).then((manifest) => {
|
161 | bundler.bundle(manifest).then((result) => {
|
162 | // do stuff here with your BundleResult
|
163 | });
|
164 | });
|
165 | ```
|
166 |
|
167 | ## Caveats
|
168 |
|
169 | In order to inlining the contents of HTML Import documents into the bundle, `polymer-bundler` has to make a few compromises to preserve valid HTML structure, script execution and style rule order:
|
170 |
|
171 | 1. Contents of all HTML Import documents will be moved to `<body>`
|
172 |
|
173 | 1. Any scripts or styles, inline or linked, which occur after a `<link rel="import">` node in `<head>` will be moved to `<body>` after the contents of the HTML Import.
|