st-bundle
Version:
CLI for watching and bundling SpringType projects.
166 lines (165 loc) • 5.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const utils_1 = require("../utils/utils");
const bundleStrings_1 = require("./bundleStrings");
/**
* Bundle types with priorities
* The numbers should not be changed
*/
var BundleType;
(function (BundleType) {
BundleType[BundleType["CSS"] = 1] = "CSS";
BundleType[BundleType["DEV"] = 2] = "DEV";
BundleType[BundleType["VENDOR_JS"] = 3] = "VENDOR_JS";
BundleType[BundleType["PROJECT_JS"] = 4] = "PROJECT_JS";
BundleType[BundleType["PROJECT_ENTRY"] = 5] = "PROJECT_ENTRY";
BundleType[BundleType["SERVER_ENTRY"] = 6] = "SERVER_ENTRY";
BundleType[BundleType["SPLIT_JS"] = 7] = "SPLIT_JS";
})(BundleType = exports.BundleType || (exports.BundleType = {}));
/**
* Mapped bundle names
* Those could be changed it's mainly used for development
*/
exports.BundleNames = {
[BundleType.CSS]: 'styles',
[BundleType.DEV]: 'dev',
[BundleType.PROJECT_JS]: 'app',
[BundleType.PROJECT_ENTRY]: 'entry',
[BundleType.VENDOR_JS]: 'vendor',
};
/**
* If a bundle doesn't exist in the collection it creates a new one
* @param collection
* @param ctx
* @param type
*/
function getBundleByType(collection, ctx, type, webIndexed) {
const bundleName = `${ctx.getUniqueEntryHash()}${exports.BundleNames[type]}`;
collection[bundleName] = collection[bundleName]
? collection[bundleName]
: createBundle({ ctx: ctx, name: bundleName, type: type, priority: type, webIndexed: webIndexed });
return collection[bundleName];
}
exports.getBundleByType = getBundleByType;
/**
* Creates a bundle set for convenience of creationing new bundes by type
* @param ctx
*/
function createBundleSet(ctx) {
const collection = {};
return {
collection: collection,
getBundle: (type) => {
return getBundleByType(collection, ctx, type, true);
},
};
}
exports.createBundleSet = createBundleSet;
class Bundle {
constructor(props) {
this.props = props;
this.packages = [];
this.name = props.name;
this.contents = utils_1.createConcat(true, this.name, '\n');
}
flush() {
this.contents = utils_1.createConcat(true, this.name, '\n');
}
prependContent(contents, sm) {
const prev = this.contents;
this.contents = utils_1.createConcat(true, this.name, '\n');
this.contents.add(null, contents, sm);
this.contents.add(null, prev.content, prev.sourceMap);
}
setCustomName(name) {
this.name = name;
this.useCustomGenerator = true;
}
addContent(contents, sm) {
this.contents.add(null, contents, sm);
}
addConcat(concat) {
this.contents.add(null, concat.content, concat.sourceMap);
}
override(contents, sm) {
this.contents = utils_1.createConcat(true, this.name, '\n');
this.contents.add(null, contents, sm);
}
addPackage(pkg) {
this.packages.push(pkg);
}
isJavascriptType() {
return (this.props.type === BundleType.PROJECT_JS ||
this.props.type === BundleType.VENDOR_JS ||
this.props.type === BundleType.SPLIT_JS);
}
needsSourceMaps() {
if (this.props.type === BundleType.PROJECT_JS || this.props.type === BundleType.SPLIT_JS) {
return this.props.ctx.config.sourceMap.project;
}
if (this.props.type === BundleType.VENDOR_JS) {
return this.props.ctx.config.sourceMap.vendor;
}
if (this.props.type === BundleType.CSS) {
return this.props.ctx.config.sourceMap.css;
}
return true;
}
generateSourceMapFileName() {
if (this.props.type === BundleType.CSS) {
return `${this.name}.css.map`;
}
return `${this.name}.js.map`;
}
getFileName() {
if (this.props.type === BundleType.CSS) {
return `${this.name}.css`;
}
return `${this.name}.js`;
}
/**
* Write bundle with sourcemaps if needed
* @param withSourceMaps
*/
async write(withSourceMaps) {
const ctx = this.props.ctx;
const ict = this.props.ctx.ict;
ict.sync('before_bundle_write', { bundle: this });
let writeBundles = true;
if (!ctx.webIndex.isDisabled) {
if (ctx.config.webIndex && ctx.config.webIndex.embedIndexedBundles && ctx.config.production) {
withSourceMaps = false;
writeBundles = this.props.webIndexed ? false : true;
}
}
if (withSourceMaps && this.contents.sourceMap) {
const smData = ctx.writer.generate(this.generateSourceMapFileName(), this.contents.sourceMap);
await smData.write();
const file = path.basename(smData.relBrowserPath);
this.contents.add(null, this.props.type === BundleType.CSS ? bundleStrings_1.sourceMapsCSSURL(file) : bundleStrings_1.sourceMapsURL(file));
}
const bundleData = ctx.writer.generate(this.getFileName(), this.contents.content.toString(), this.noHash || this.props.skipHash);
if (writeBundles)
await bundleData.write();
ict.sync('after_bundle_write', { bundle: this });
return { bundle: this, stat: bundleData };
}
/**
* Generates a function that writes contents with sourcemaps
*/
generate() {
const addSourceMaps = this.needsSourceMaps(); //shouldAddSourcemaps(this.props.type, config);
const content = this.contents.content.toString();
return {
write: () => this.write(addSourceMaps),
contents: content,
sourceMap: this.contents.sourceMap,
};
}
}
exports.Bundle = Bundle;
function createBundle(props) {
return new Bundle(props);
}
exports.createBundle = createBundle;