Skip to content

Commit

Permalink
Merge pull request #70 from Polymer/add-bundler
Browse files Browse the repository at this point in the history
Import the bundler into the monorepo
  • Loading branch information
rictic authored Apr 7, 2018
2 parents 0aa2be6 + e21d73f commit d3547e1
Show file tree
Hide file tree
Showing 195 changed files with 12,353 additions and 0 deletions.
10 changes: 10 additions & 0 deletions packages/bundler/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BasedOnStyle: Google
AlignAfterOpenBracket: AlwaysBreak
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BinPackArguments: false
BinPackParameters: false
19 changes: 19 additions & 0 deletions packages/bundler/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
# This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
# The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
# The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
# Code distributed by Google as part of the polymer project is also
# subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt

# Polymer EditorConfig

root = true

[*]
charset = utf-8
indent_size = 2
indent_style = space
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions packages/bundler/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
16 changes: 16 additions & 0 deletions packages/bundler/.github/PULL_REQUEST_TEMPLATE
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--
Thanks for the PR!

If this change has a user visible change (including
bug fixes, new features, etc) please describe the change in
CHANGELOG.md.

If the change is an entirely package-internal reshuffling/refactoring
should the change not be described in the CHANGELOG.

Consider also updating the README.

More info: http://keepachangelog.com/en/0.3.0/
-->

- [ ] CHANGELOG.md has been updated
5 changes: 5 additions & 0 deletions packages/bundler/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
example/bower_components
**/.DS_Store
typings
lib
7 changes: 7 additions & 0 deletions packages/bundler/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
# npmignore
example
CHANGELOG.md
README.md
util
test
5 changes: 5 additions & 0 deletions packages/bundler/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: node_js
node_js:
- "6"
- "node"
sudo: false
14 changes: 14 additions & 0 deletions packages/bundler/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"clang-format.style": "file",
"editor.detectIndentation": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true,
"editor.tabSize": 2,
"files.insertFinalNewline": true,
"search.exclude": {
"node_modules/": true,
"lib/": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}
774 changes: 774 additions & 0 deletions packages/bundler/CHANGELOG.md

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions packages/bundler/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2014 The Polymer Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
172 changes: 172 additions & 0 deletions packages/bundler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
[![Build Status](https://travis-ci.org/Polymer/polymer-bundler.svg?branch=master)](https://travis-ci.org/Polymer/polymer-bundler)
[![NPM version](http://img.shields.io/npm/v/polymer-bundler.svg)](https://www.npmjs.com/package/polymer-bundler)

# Polymer Bundler

polymer-bundler is a library for packaging project assets for production to minimize network round-trips.


## Relationship to Polymer CLI

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.

## Usage

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.

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.


## Installation

`polymer-bundler` is available on npm. For maximium utility, `polymer-bundler` should be installed globally.

npm install -g polymer-bundler

This will install `polymer-bundler` to `/usr/local/bin/polymer-bundler` (you may need `sudo`
for this step).

## Options
- `-h`|`--help`: Print this message
- `-v`|`--version`: Print version number
- `-r`|`--root`: The root of the package/project being bundled. Defaults to the current working folder.
- `--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`
- `--inline-scripts`: External scripts will only be inlined if this flag is provided.
- `--inline-css`: External stylesheets will only be inlined if this flag is provided.
- `--manifest-out <path>`: If specified, the bundle manifest will be written out to `<path>`.
- `--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.
- `--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.
- `--shell`: Uses a bundling strategy which puts inlines shared dependencies into a specified html app "shell".
- `--strip-comments`: Strips all HTML comments from the document which do not contain an `@license`, or start with `<!--#` or `<!--!`.
- `--sourcemaps`: Honor (or create) sourcemaps for inline script tags.
- `--out-file <path>`: If specified, output will be written to <path> instead of stdout.
- `--out-dir <path>`: If specified, output will be written to <path>. Necessary if bundling multiple files.

## Usage
The command

polymer-bundler target.html

will inline the HTML Imports of `target.html` and print the resulting HTML to standard output.

The command

polymer-bundler target.html --rewrite-urls-in-templates

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.

The command

polymer-bundler target.html > build.html

will inline the HTML Imports of `target.html` and print the result to `build.html`.

The command

polymer-bundler -p "path/to/target/" /target.html

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.

The command

polymer-bundler --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html

will inline the HTML Imports of `target.html` that are not in the directory `path/to/target/subpath` nor `path/to/target/subpath2`.

The command

polymer-bundler --inline-scripts target.html

will inline scripts in `target.html` as well as HTML Imports. Exclude flags will apply to both Imports and Scripts.

The command

polymer-bundler --inline-css target.html

will inline Polymerized stylesheets, `<link rel="import" type="css">`

The command

polymer-bundler --strip-comments target.html

will remove HTML comments, except for those containing `@license` or starting with `<!--#` or `<!--!`. License comments will be deduplicated.

The command

polymer-bundler --redirect "myapp://|src" target.html

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.

## Using polymer-bundler programmatically

polymer-bundler as a library has two exported function.

`polymer-bundler` constructor takes an object of options similar to the command line options:

- `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.
- `excludes`: URLs to exclude from inlining. URLs may represent files or folders. HTML tags referencing excluded URLs are preserved.
- `sourcemaps`: Honor (or create) sourcemaps for inline scripts
- `inlineCss`: Will inline content of external stylesheets into the bundle html. Defaults to `true`.
- `inlineScripts`: Inline content of external scripts into the bundled html. Defaults to `true`.
- `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`.
- `sourcemaps`: Honor (or create) sourcemaps for inline scripts. Defaults to `false`.
- `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`.
- `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).
- `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)

`.generateManifest()` takes a collection of entrypoint URLs and promises a `BundleManifest` which describes all the bundles it will produce.

`.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`.

A simple example:
```js
const bundler = new require('polymer-bundler').Bundler();
bundler.generateManifest(['my-app.html']).then((manifest) => {
bundler.bundle(manifest).then((result) => {
console.log('<!-- BUNDLED VERSION OF my-app.html: -->');
console.log(result.documents.get('my-app.html').content));
});
});
```

An example with a customized sharding strategy and output layout:
```js
const {Analyzer, FsUrlLoader} = require('polymer-analyzer');
const analyzer = new Analyzer({
urlLoader: new FsUrlLoader(path.resolve('.'))
});

const {Bundler,
generateSharedDepsMergeStrategy,
generateCountingSharedBundleUrlMapper} = require('polymer-bundler');
const bundler = new Bundler({
analyzer: analyzer,
excludes: [],
inlineScripts: true,
inlineCss: true,
rewriteUrlsInTemplates: false,
stripComments: true,
// Merge shared dependencies into a single bundle when
// they have at least three dependents.
strategy: generateSharedDepsMergeStrategy(3),
// Shared bundles will be named:
// `shared/bundle_1.html`, `shared/bundle_2.html`, etc...
urlMapper: generateCountingSharedBundleUrlMapper('shared/bundle_')
});

// Provide the strategy and the URL mapper to produce a
// manifest using custom behavior.
bundler.generateManifest(['item.html', 'cart.html']).then((manifest) => {
bundler.bundle(manifest).then((result) => {
// do stuff here with your BundleResult
});
});
```

## Caveats

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:

1. Contents of all HTML Import documents will be moved to `<body>`

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.
21 changes: 21 additions & 0 deletions packages/bundler/appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Test against this version of Node.js
environment:
nodejs_version: "6"

# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
# install modules
- npm install

# Post-install test scripts.
test_script:
# Output useful info for debugging.
- node --version
- npm --version
# run tests
- npm test

# Don't actually build.
build: off
25 changes: 25 additions & 0 deletions packages/bundler/custom_typings/command-line-args.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
declare module 'command-line-args' {
function commandLineArgs(args: commandLineArgs.ArgDescriptor[])
: any;

module commandLineArgs {
interface ArgDescriptor {
name: string;
alias?: string;
description?: string;
defaultValue?: any;
type?: Object;
multiple?: boolean;
defaultOption?: boolean;
group?: string;
}
interface UsageOpts {
title?: string;
header?: string;
description?: string;
groups?: any;
}
}

export = commandLineArgs;
}
8 changes: 8 additions & 0 deletions packages/bundler/custom_typings/command-line-usage.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'command-line-usage' {
function commandLineUsage(args: any)
: string;
module commandLineUsage {

}
export = commandLineUsage;
}
26 changes: 26 additions & 0 deletions packages/bundler/custom_typings/espree.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
declare module 'espree' {
interface ParseOpts2 {
ecmaVersion?: number;
loc?: boolean;
sourceType?: 'script' | 'module';
}

interface Token {
type: string,
value: string,
start: number,
end: number,
loc: {
start: {
line: number,
column: number
},
end: {
line: number,
column: number
}
}
}

export function tokenize(text: string, opts?: ParseOpts2): Token[];
}
8 changes: 8 additions & 0 deletions packages/bundler/custom_typings/mkdirp.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module 'mkdirp' {
function mkdirp(args: any)
: string;
module mkdirp {
function sync(dir: string, opts?: {}): void;
}
export = mkdirp;
}
Loading

0 comments on commit d3547e1

Please sign in to comment.