@userfrosting/gulp-bundle-assets
Advanced tools
Comparing version 3.0.0-rc.1 to 3.0.0-rc.2
@@ -10,2 +10,14 @@ # Changelog | ||
## [3.0.0-rc.2] - 2019-02-10 | ||
This release focused on internal refactoring and improving test coverage. Many discoverd bugs have been fixed. | ||
### Fixed | ||
- Potential deadlock in bundles processor. | ||
- Swallowing of exceptions raised within bundler factory and bundler factory streams. | ||
- Virtual path rules in a config not being correctly checked for duplicate matchers. | ||
- Fixed edge case where if the first file in a bundle failed to a resolve a file the resulting exception would never bubble up due to the source stream never being unpaused. #21 | ||
- Fixed issue where bundles using both `scripts` and `styles` would result in only files emitted as part of `styles` bundling appearing in the results callback data. #22 | ||
- Other undocumented assorted edge cases. | ||
## [3.0.0-rc.1] - 2019-01-09 | ||
@@ -12,0 +24,0 @@ |
import Vinyl from "vinyl"; | ||
import { BundlerStreamFactory } from "./main"; | ||
import { LogLevel } from "./config"; | ||
import { LogLevel } from "./log-levels"; | ||
/** | ||
@@ -5,0 +5,0 @@ * Processes provided bundle definitions. |
import { isVinyl } from "vinyl"; | ||
import { Catcher } from "./catcher"; | ||
import { Readable } from "stream"; | ||
import { LogLevel } from "./config"; | ||
import { LogLevel } from "./log-levels"; | ||
/** | ||
@@ -12,2 +12,3 @@ * Processes provided bundle definitions. | ||
export async function BundlesProcessor(files, bundles, bundleStreamFactory, logger) { | ||
const Logger = (msg, lvl) => logger(`BundlesProcessor > ${msg}`, lvl); | ||
try { | ||
@@ -19,12 +20,34 @@ // Track results | ||
for (const [name, paths] of bundles) { | ||
logger(`Building bundle "${name}"`, LogLevel.Normal); | ||
// Create catcher | ||
const catcher = new Catcher(logger); | ||
Logger(`Building bundle "${name}"`, LogLevel.Normal); | ||
// Build bundler with source and bundle name | ||
logger("Invoking provided bundler", LogLevel.Silly); | ||
bundleStreamFactory(new BundleSource(files, paths), name) | ||
.pipe(catcher); | ||
Logger("Invoking provided bundler", LogLevel.Silly); | ||
// Wrap to permit catching and reporting of errors | ||
const chunks = await new Promise(async (resolve, reject) => { | ||
try { | ||
// Create catcher | ||
const catcher = new Catcher(Logger); | ||
// Create bundle source (and handle errors) | ||
const source = new BundleSource(files, paths, Logger) | ||
.on("error", (e) => { | ||
// Bundle stream will be unpiped automatically | ||
Logger("Error emitted by bundle source", LogLevel.Scream); | ||
reject(e); | ||
}); | ||
// Run provided transform stream factory | ||
bundleStreamFactory(source, name) | ||
.on("error", (e) => { | ||
// Catcher will be unpiped automatically. | ||
Logger("Error emitted by provided joiner", LogLevel.Scream); | ||
reject(e); | ||
}) | ||
.pipe(catcher); | ||
// Resolve on catcher completion | ||
resolve(await catcher.Collected); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
// Catch results | ||
logger("Catching outputs", LogLevel.Silly); | ||
const chunks = await catcher.Collected; | ||
Logger("Catching outputs", LogLevel.Silly); | ||
// Add to resultPaths and resultChunks | ||
@@ -39,2 +62,4 @@ const resultFiles = []; | ||
} | ||
else | ||
Logger("Non-Vinyl or Vinyl without path chunk was recieved from bundle factory. Information was not captured.", LogLevel.Complain); | ||
// Store the chunk | ||
@@ -46,7 +71,7 @@ resultChunks.push(chunk); | ||
} | ||
logger("Returning bundling results", LogLevel.Silly); | ||
Logger("Returning bundling results", LogLevel.Silly); | ||
return [resultChunks, resultFileInfo]; | ||
} | ||
catch (error) { | ||
logger("BundlesProcessor completed with error", LogLevel.Scream); | ||
Logger("BundlesProcessor completed with error", LogLevel.Scream); | ||
throw error; | ||
@@ -63,3 +88,3 @@ } | ||
*/ | ||
constructor(files, paths) { | ||
constructor(files, paths, logger) { | ||
super({ | ||
@@ -71,2 +96,6 @@ objectMode: true | ||
this.paths = paths.slice(0); | ||
// Prevent Catcher from becoming stuck when nothing will be coming through | ||
if (this.paths.length === 0) | ||
this.resume(); | ||
this.Logger = (msg, lvl) => logger(`BundleSource > ${msg}`, lvl); | ||
} | ||
@@ -79,10 +108,19 @@ /** | ||
const path = this.paths.shift(); | ||
if (this.files.has(path)) | ||
this.push(this.files.get(path)[0].clone()); | ||
else | ||
new Error(`No file could be resolved for ${path}.`); | ||
this.Logger(`Locating "${path}"...`, LogLevel.Silly); | ||
if (this.files.has(path)) { | ||
const file = this.files.get(path)[0].clone(); | ||
this.Logger(`Found, pushing "${file.path}" on through.`, LogLevel.Silly); | ||
this.push(file); | ||
} | ||
else { | ||
this.Logger(`Couldn't find "${path}"!`, LogLevel.Silly); | ||
this.emit("error", new Error(`No file could be resolved for "${path}".`)); | ||
} | ||
} | ||
else | ||
else { | ||
this.Logger("Nothing left to send", LogLevel.Silly); | ||
this.push(null); | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=bundles-processor.js.map |
/// <reference types="node" /> | ||
import { Transform, TransformCallback } from "stream"; | ||
import { LogLevel } from "./config"; | ||
import { LogLevel } from "./log-levels"; | ||
/** | ||
* All this does is collect all stream data and once all read resolves a promise with the collected chunks. | ||
* TODO Handle when the stream source has no chunks to pass | ||
*/ | ||
@@ -25,2 +24,5 @@ export declare class Catcher extends Transform { | ||
private Resolve?; | ||
/** | ||
* @param logger Used for logging events and errors. | ||
*/ | ||
constructor(logger: (value: string, level: LogLevel) => void); | ||
@@ -27,0 +29,0 @@ /** |
import { Transform } from "stream"; | ||
import { LogLevel } from "./config"; | ||
import { LogLevel } from "./log-levels"; | ||
/** | ||
* All this does is collect all stream data and once all read resolves a promise with the collected chunks. | ||
* TODO Handle when the stream source has no chunks to pass | ||
*/ | ||
export class Catcher extends Transform { | ||
/** | ||
* @param logger Used for logging events and errors. | ||
*/ | ||
constructor(logger) { | ||
@@ -16,3 +18,3 @@ super({ | ||
this.Results = []; | ||
this.Logger = logger; | ||
this.Logger = (msg, lvl) => logger(`Catcher > ${msg}`, lvl); | ||
// Set promise | ||
@@ -41,3 +43,5 @@ this.Logger("Creating promise with external completion source", LogLevel.Silly); | ||
this.Logger("Starting resolution of catcher promise", LogLevel.Silly); | ||
// Ensure promise has had chance to run | ||
const resolver = () => { | ||
/* istanbul ignore else */ | ||
if (this.Resolve) { | ||
@@ -56,1 +60,2 @@ this.Resolve(this.Results); | ||
} | ||
//# sourceMappingURL=catcher.js.map |
@@ -6,1 +6,2 @@ require = require("esm")(module, { | ||
module.exports = require("./main"); | ||
//# sourceMappingURL=index.js.map |
/// <reference types="node" /> | ||
import { Readable, Transform, TransformCallback } from "stream"; | ||
import { Readable, Transform, TransformCallback, Stream } from "stream"; | ||
import Vinyl from "vinyl"; | ||
import { Config } from "./config"; | ||
export { MergeRawConfigs, ValidateRawConfig } from "./config"; | ||
import { Config } from "./config/config"; | ||
export { default as MergeRawConfigs } from "./config/merge-configs"; | ||
export { default as ValidateRawConfig } from "./config/validate-config"; | ||
/** | ||
@@ -93,3 +94,3 @@ * Assists in orchastrating bundle operations. | ||
*/ | ||
(src: Readable, name: string): Transform; | ||
(src: Readable, name: string): Stream; | ||
} |
@@ -7,6 +7,7 @@ import Extend from "just-extend"; | ||
import { BundlesProcessor } from "./bundles-processor"; | ||
import { LogLevel } from "./config"; | ||
import { LogLevel } from "./log-levels"; | ||
import { PluginName } from "./plugin-details"; | ||
// Foward public exports | ||
export { MergeRawConfigs, ValidateRawConfig } from "./config"; | ||
export { default as MergeRawConfigs } from "./config/merge-configs"; | ||
export { default as ValidateRawConfig } from "./config/validate-config"; | ||
/** | ||
@@ -82,3 +83,3 @@ * Assists in orchastrating bundle operations. | ||
const resolvedPath = resolvePath(config.BundlesVirtualBasePath + "/" + path); | ||
this.Logger(`Resolved path: ${resolvePath}`, LogLevel.Silly); | ||
this.Logger(`Resolved path: "${resolvedPath}"`, LogLevel.Silly); | ||
paths.push(resolvedPath); | ||
@@ -96,3 +97,3 @@ } | ||
const resolvedPath = resolvePath(config.BundlesVirtualBasePath + "/" + path); | ||
this.Logger(`Resolved path: ${resolvePath}`, LogLevel.Silly); | ||
this.Logger(`Resolved path: ${resolvedPath}`, LogLevel.Silly); | ||
paths.push(resolvedPath); | ||
@@ -168,4 +169,5 @@ } | ||
catch (error) { | ||
// Shouldn't ever hit this, but ensures errors are piped properly in the worst case scenario. | ||
/* istanbul ignore next: Applying coverage here is out of scope as errors produced cannot yet be predicted. */ | ||
this.Logger("_transform completed with error", LogLevel.Scream); | ||
/* istanbul ignore next */ | ||
callback(new PluginError(PluginName, error)); | ||
@@ -195,4 +197,11 @@ } | ||
} | ||
for (const [name, paths] of resultsMap) | ||
this.BundleResultsMap.set(name, paths); | ||
for (const [name, paths] of resultsMap) { | ||
if (this.BundleResultsMap.has(name)) { | ||
const allPaths = this.BundleResultsMap.get(name); | ||
allPaths.push(...paths); | ||
this.BundleResultsMap.set(name, allPaths); | ||
} | ||
else | ||
this.BundleResultsMap.set(name, paths); | ||
} | ||
this.Logger("Completed bundling of styles", LogLevel.Normal); | ||
@@ -216,3 +225,3 @@ this.Logger("All bundles have been built", LogLevel.Normal); | ||
catch (error) { | ||
// Shouldn't ever hit this, but ensures errors are piped properly in the worst case scenario. | ||
// Ideally this shouldn't ever be needed, however we *are* dealing with external data. | ||
this.Logger("_flush completed with error", LogLevel.Scream); | ||
@@ -223,1 +232,2 @@ callback(new PluginError(PluginName, error)); | ||
} | ||
//# sourceMappingURL=main.js.map |
@@ -5,1 +5,2 @@ /** | ||
export const PluginName = "gulp-uf-bundle-assets"; | ||
//# sourceMappingURL=plugin-details.js.map |
{ | ||
"name": "@userfrosting/gulp-bundle-assets", | ||
"version": "3.0.0-rc.1", | ||
"version": "3.0.0-rc.2", | ||
"description": "Fork of Chris Montgomery's gulp-bundle-assets, striped back and rewritten for use with UserFrosting.", | ||
@@ -44,3 +44,3 @@ "main": "./dist/index.js", | ||
"dependencies": { | ||
"esm": "^3.0.84", | ||
"esm": "^3.2.3", | ||
"just-extend": "^4.0.2", | ||
@@ -52,7 +52,7 @@ "plugin-error": "^1.0.1", | ||
"@types/just-extend": "^1.1.0", | ||
"@types/node": "^10.12.9", | ||
"@types/node": "^10.12.21", | ||
"@types/vinyl": "^2.0.2", | ||
"ava": "^1.0.1", | ||
"ava": "^1.2.1", | ||
"changelog-updater": "^1.1.0", | ||
"typescript": "^3.1.6" | ||
"typescript": "^3.3.3" | ||
}, | ||
@@ -59,0 +59,0 @@ "engines": { |
@@ -5,7 +5,9 @@ # [gulp](https://github.com/gulpjs/gulp)-bundle-assets | ||
| ------ | ------ | | ||
| master | [![Build Status](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets.svg?branch=master)](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets) | | ||
| develop | [![Build Status](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets.svg?branch=develop)](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets) | | ||
| master | [![Build Status](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets.svg?branch=master)](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets) [![codecov](https://codecov.io/gh/userfrosting/gulp-uf-bundle-assets/branch/master/graph/badge.svg)](https://codecov.io/gh/userfrosting/gulp-uf-bundle-assets/branch/master) | | ||
| develop | [![Build Status](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets.svg?branch=develop)](https://travis-ci.org/userfrosting/gulp-uf-bundle-assets) [![codecov](https://codecov.io/gh/userfrosting/gulp-uf-bundle-assets/branch/develop/graph/badge.svg)](https://codecov.io/gh/userfrosting/gulp-uf-bundle-assets/branch/develop) | | ||
Orchastrates JS and CSS bundle creation in a highly efficient and configurable manner. | ||
**CAUTION** The implementation currently produces a great deal backpressure. This can result in signficiant RAM usage. Projects dealing with a significant number resources are better off not using this tool until the custom stream source is implemented in v4. | ||
## Install | ||
@@ -12,0 +14,0 @@ |
Sorry, the diff of this file is not supported yet
98818
44
925
99
Updatedesm@^3.2.3