UNPKG

5.3 kBPlain TextView Raw
1/**
2 * @license
3 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4 * This code may only be used under the BSD style license found at
5 * http://polymer.github.io/LICENSE.txt
6 * The complete set of authors may be found at
7 * http://polymer.github.io/AUTHORS.txt
8 * The complete set of contributors may be found at
9 * http://polymer.github.io/CONTRIBUTORS.txt
10 * Code distributed by Google as part of the polymer project is also
11 * subject to an additional IP rights grant found at
12 * http://polymer.github.io/PATENTS.txt
13 */
14
15import * as logging from 'plylog';
16import {PackageRelativeUrl} from 'polymer-analyzer';
17import {ProjectConfig, ProjectOptions} from 'polymer-project-config';
18import {src as vinylSrc} from 'vinyl-fs';
19
20import {BuildAnalyzer} from './analyzer';
21import {BaseTagUpdater} from './base-tag-updater';
22import {BuildBundler, Options as BuildBundlerOptions} from './bundle';
23import {CustomElementsEs5AdapterInjector} from './custom-elements-es5-adapter';
24import {BabelHelpersInjector} from './inject-babel-helpers';
25import {LocalFsPath} from './path-transformers';
26import {AddPrefetchLinks} from './prefetch-links';
27import {AddPushManifest} from './push-manifest';
28
29const logger = logging.getLogger('polymer-project');
30
31
32export class PolymerProject {
33 config: ProjectConfig;
34
35 /**
36 * A `Transform` stream that uses polymer-analyzer to analyze the files. It
37 * can be used to get information on dependencies and fragments for the
38 * project once the source & dependency streams have been piped into it.
39 */
40 analyzer: BuildAnalyzer;
41
42 constructor(config: ProjectConfig|ProjectOptions|string) {
43 if (config.constructor.name === 'ProjectConfig') {
44 this.config = <ProjectConfig>config;
45 } else if (typeof config === 'string') {
46 const maybeConfig = ProjectConfig.loadConfigFromFile(config);
47 if (maybeConfig == null) {
48 throw new Error(`Unable to load config from file: ${config}`);
49 }
50 this.config = maybeConfig;
51 } else {
52 this.config = new ProjectConfig(config);
53 }
54
55 logger.debug(`build config loaded:`, this.config);
56
57 this.analyzer = new BuildAnalyzer(this.config);
58 }
59
60 /**
61 * Returns a `Transform` stream that modifies the files that pass through it
62 * based on the dependency analysis done by the `analyzer` transform. It
63 * "bundles" a project by injecting its dependencies into the application
64 * fragments themselves, so that a minimum number of requests need to be made
65 * to load.
66 *
67 * (NOTE: The analyzer stream must be in the pipeline somewhere before this.)
68 */
69 bundler(options?: BuildBundlerOptions): BuildBundler {
70 return new BuildBundler(this.config, this.analyzer, options);
71 }
72
73 /**
74 * Returns the analyzer's stream of this project's source files - files
75 * matched by the project's `config.sources` value.
76 */
77 sources(): NodeJS.ReadableStream {
78 return this.analyzer.sources();
79 }
80
81 /**
82 * Returns the analyzer's stream of this project's dependency files - files
83 * loaded inside the analyzed project that are not considered source files.
84 */
85 dependencies(): NodeJS.ReadableStream {
86 let dependenciesStream: NodeJS.ReadableStream =
87 this.analyzer.dependencies();
88
89 // If we need to include additional dependencies, create a new vinyl
90 // source stream and pipe our default dependencyStream through it to
91 // combine.
92 if (this.config.extraDependencies.length > 0) {
93 const includeStream = vinylSrc(this.config.extraDependencies, {
94 cwdbase: true,
95 nodir: true,
96 passthrough: true,
97 });
98 dependenciesStream = dependenciesStream.pipe(includeStream);
99 }
100
101 return dependenciesStream;
102 }
103
104 /**
105 * Returns a stream transformer that injects 'prefetch' link tags into HTML
106 * documents based on the transitive dependencies of the document.
107 * For entrypoint documents without `<base>` tag, absolute urls are used in
108 * prefetch link hrefs. In all other cases, link hrefs will be relative urls.
109 */
110 addPrefetchLinks(): NodeJS.ReadWriteStream {
111 return new AddPrefetchLinks(this.config);
112 }
113
114 /**
115 * Returns a stream transformer that adds a push manifest file to the set
116 * of all input files that pass through.
117 */
118 addPushManifest(outPath?: LocalFsPath, basePath?: PackageRelativeUrl):
119 NodeJS.ReadWriteStream {
120 return new AddPushManifest(this.config, outPath, basePath);
121 }
122
123 /**
124 * Returns a stream transformer that injects `custom-elements-es5-adapter.js`
125 * into the entry point HTML file. This adapter is needed when serving ES5
126 * to browsers that support the native Custom Elements API.
127 */
128 addCustomElementsEs5Adapter(): NodeJS.ReadWriteStream {
129 return new CustomElementsEs5AdapterInjector();
130 }
131
132 addBabelHelpersInEntrypoint(entrypoint: string = this.config.entrypoint):
133 NodeJS.ReadWriteStream {
134 return new BabelHelpersInjector(entrypoint);
135 }
136
137 /**
138 * Return a stream transformer that updates the `<base>` tag of the project's
139 * entrypoint HTML file with the given new value. No change is made if a
140 * `<base>` tag does not already exist.
141 */
142 updateBaseTag(baseHref: string): NodeJS.ReadWriteStream {
143 return new BaseTagUpdater(this.config.entrypoint as LocalFsPath, baseHref);
144 }
145}