mirror of
https://github.com/vale981/Vulcan
synced 2025-03-09 12:16:37 -04:00
102 lines
3 KiB
JavaScript
102 lines
3 KiB
JavaScript
import { readFile } from 'fs';
|
|
|
|
import WebBrowserTemplate from './template-web.browser';
|
|
import WebCordovaTemplate from './template-web.cordova';
|
|
|
|
// Copied from webapp_server
|
|
const readUtf8FileSync = filename => Meteor.wrapAsync(readFile)(filename, 'utf8');
|
|
|
|
export class Boilerplate {
|
|
constructor(arch, manifest, options = {}) {
|
|
this.template = _getTemplate(arch);
|
|
this.baseData = null;
|
|
|
|
this._generateBoilerplateFromManifest(
|
|
manifest,
|
|
options
|
|
);
|
|
}
|
|
|
|
// The 'extraData' argument can be used to extend 'self.baseData'. Its
|
|
// purpose is to allow you to specify data that you might not know at
|
|
// the time that you construct the Boilerplate object. (e.g. it is used
|
|
// by 'webapp' to specify data that is only known at request-time).
|
|
toHTML(extraData) {
|
|
if (!this.baseData || !this.template) {
|
|
throw new Error('Boilerplate did not instantiate correctly.');
|
|
}
|
|
|
|
return "<!DOCTYPE html>\n" +
|
|
this.template({ ...this.baseData, ...extraData });
|
|
}
|
|
|
|
// XXX Exported to allow client-side only changes to rebuild the boilerplate
|
|
// without requiring a full server restart.
|
|
// Produces an HTML string with given manifest and boilerplateSource.
|
|
// Optionally takes urlMapper in case urls from manifest need to be prefixed
|
|
// or rewritten.
|
|
// Optionally takes pathMapper for resolving relative file system paths.
|
|
// Optionally allows to override fields of the data context.
|
|
_generateBoilerplateFromManifest(manifest, {
|
|
urlMapper = _.identity,
|
|
pathMapper = _.identity,
|
|
baseDataExtension,
|
|
inline,
|
|
} = {}) {
|
|
|
|
const boilerplateBaseData = {
|
|
css: [],
|
|
js: [],
|
|
head: '',
|
|
body: '',
|
|
meteorManifest: JSON.stringify(manifest),
|
|
...baseDataExtension,
|
|
};
|
|
|
|
_.each(manifest, item => {
|
|
const urlPath = urlMapper(item.url);
|
|
const itemObj = { url: urlPath };
|
|
|
|
if (inline) {
|
|
itemObj.scriptContent = readUtf8FileSync(
|
|
pathMapper(item.path));
|
|
itemObj.inline = true;
|
|
}
|
|
|
|
if (item.type === 'css' && item.where === 'client') {
|
|
boilerplateBaseData.css.push(itemObj);
|
|
}
|
|
|
|
if (item.type === 'js' && item.where === 'client' &&
|
|
// Dynamic JS modules should not be loaded eagerly in the
|
|
// initial HTML of the app.
|
|
!item.path.startsWith('dynamic/')) {
|
|
boilerplateBaseData.js.push(itemObj);
|
|
}
|
|
|
|
if (item.type === 'head') {
|
|
boilerplateBaseData.head =
|
|
readUtf8FileSync(pathMapper(item.path));
|
|
}
|
|
|
|
if (item.type === 'body') {
|
|
boilerplateBaseData.body =
|
|
readUtf8FileSync(pathMapper(item.path));
|
|
}
|
|
});
|
|
|
|
this.baseData = boilerplateBaseData;
|
|
}
|
|
};
|
|
|
|
// Returns a template function that, when called, produces the boilerplate
|
|
// html as a string.
|
|
const _getTemplate = arch => {
|
|
if (arch === 'web.browser') {
|
|
return WebBrowserTemplate;
|
|
} else if (arch === 'web.cordova') {
|
|
return WebCordovaTemplate;
|
|
} else {
|
|
throw new Error('Unsupported arch: ' + arch);
|
|
}
|
|
};
|