zengenti-buildstartup-package
Version:
Post-build scripts to generate the startup scripts for any configured environments
167 lines (148 loc) • 5.3 kB
JavaScript
const fs = require("fs");
const dotenv = require("dotenv");
const path = require("path");
const _module = path.basename(__filename);
let projects = (env) => [
{
id: env.PROJECT,
publicUri: env.PUBLIC_URL,
},
];
// Try to resolve a path provided as an argument to a define-config
// file containing an exported function called 'projects'
// which returns an array of specified projects
try {
try {
projects = __non_webpack_require__(
path.resolve("./webpack/define-config")
).projects;
} catch (e) {
projects = require(path.resolve("./webpack/define-config")).projects;
}
} catch (ex) {
console.log(ex);
}
function loadConfig(env) {
console.log('Found environment in: "' + env + '"');
// read values from .env file and set process.env.*
var envConfig = dotenv.parse(fs.readFileSync(env));
console.log(projects(envConfig));
process.env.dotenv = env;
return envConfig;
}
function readModuleFileSync(filePath) {
try {
return fs.readFileSync(filePath, "utf8");
} catch (e) {
console.log(e);
}
}
function makeReplacements(config, template, isClient) {
// replace template with stringified values from .env.*
// finally map all entries to context.* variables and write them out
const builtTemplate = template
.replace(/_PROJECTS_/g, JSON.stringify(projects(config)))
.replace(/_ALIAS_/g, JSON.stringify(config.ALIAS))
.replace(
/_INTERNAL_VIP_/g,
isClient ? '""' : JSON.stringify(config.INTERNAL_VIP)
)
.replace(/_ACCESS_TOKEN_/g, JSON.stringify(config.ACCESS_TOKEN))
.replace(/_PROJECT_/g, JSON.stringify(config.PROJECT))
.replace(/_PUBLIC_URL_/g, JSON.stringify(config.PUBLIC_URL))
.replace(/_CLIENT_ID_/g, JSON.stringify(config.CLIENT_ID))
.replace(/_CLIENT_SECRET_/g, JSON.stringify(config.CLIENT_SECRET))
.replace(
/_ALL_ENV_VARS_;/,
Object.entries(config)
.map(([k, v]) =>
["INTERNAL_VIP"].includes(k)
? null
: `context.${k} = ${JSON.stringify(v)};`
)
.filter((v) => v)
.join("\n")
);
return isClient
? builtTemplate.substring(0, builtTemplate.indexOf("_SERVER_ONLY_"))
: builtTemplate.replace("_SERVER_ONLY_;", "");
}
function mkdirp(filepath) {
var dirname = path.dirname(filepath);
if (!fs.existsSync(dirname)) {
mkdirp(dirname);
}
if (!fs.existsSync(filepath)) {
fs.mkdirSync(filepath);
}
}
function writeModuleFileSync(filename, contents) {
try {
mkdirp(path.dirname(filename));
fs.writeFileSync(filename, contents);
console.log("--", 'Created "' + filename + '"');
} catch (e) {
console.log("--", 'Problem writing file: "' + filename + '"', e);
}
}
function buildStartupRuntime({ alias, projectId, accessToken }) {
try {
console.log("/* ", _module, "- Building server start script for dynamic environment", "*/");
// the base startup template we are going to make environment specific
// replacements on
var template = readModuleFileSync(__dirname + "/startup.template.js");
var config = loadConfig(".env");
//load in a default env config
//use the passed in vars, if any, to set the loaded config
config.ALIAS = alias || config.ALIAS;
config.PROJECT = projectId || config.PROJECT;
config.ACCESS_TOKEN = accessToken || config.ACCESS_TOKEN;
console.log(config);
var serverStartup = makeReplacements(config, template);
// write a startup.projectId.alias.js file for the environment alias read from
// the .env.* file so the script can be used to start the server
// and serve the bundle configuration for that specific environment
writeModuleFileSync(
`dist/server/start.${config.PROJECT.toLowerCase()}.${config.ALIAS.toLowerCase()}.js`,
serverStartup
);
console.log("/* 👏 ", _module, "completed successfully", "*/");
} catch (e) {
console.log("/* !! ", _module, "encountered a problem: ", "*/", e.stack);
}
}
module.exports = {
setDefaults: function (currentScript, staticPath = "static") {
// in a server context check if we are using a standard or
// targeted start script and write new defaults for a targeted startup
var defaultScript = path.dirname(currentScript) + "/start.js";
if (path.resolve(currentScript) != path.resolve(defaultScript)) {
try {
console.log('[launcher set default]', currentScript);
// in a server context we copy the current (targeted) start script
// to be the default so we can serve a static startup bundle to the client
// and start the server with default scripts pre-targeted
fs.copyFileSync(
currentScript,
path.dirname(path.dirname(currentScript)) +
"/" +
staticPath +
"/startup.js"
);
fs.copyFileSync(
currentScript,
path.dirname(currentScript) + "/start.js"
);
} catch (err) {
console.log(err);
}
}
},
buildStartupRuntime,
buildUtils: {
loadConfig,
makeReplacements,
readModuleFileSync,
writeModuleFileSync,
},
};