Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Zero cost web apps
'use strict';
module.exports = function(environment) {
let ENV = {
modulePrefix: 'zero-cost-web-app',
environment,
rootURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
},
fastboot: {
hostWhitelist: [/^localhost:\d+$/, /cloudfunctions\.net$/]
}
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
ENV.APP.autoboot = false;
}
if (environment === 'production') {
// here you can enable a production-specific feature
}
return ENV;
};
'use strict';
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
let app = new EmberApp(defaults, {
// Add options here
"ember-welcome-page": {
enabled: true
}
});
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
return app.toTree();
};
{
"database": {
"rules": "database.rules.json"
},
"storage": {
"rules": "storage.rules"
},
"functions": {
"ignore": [
"**/.*",
"**/node_modules/**"
]
},
"hosting": {
"public": "dist",
"cleanUrls": true,
"trailingSlash": false,
"ignore": [
"**/.*",
"firebase.json",
"**/node_modules/**"
],
"rewrites": [{
"source": "**",
"function": "ssr"
}],
"headers": [{
"source": "**",
"headers": [{
"key": "Cache-Control",
"value": "max-age=300"
}]
}, {
"source": "**/*.@(jpg|jpeg|gif|png)",
"headers": [{
"key": "Cache-Control",
"value": "max-age=7200"
}]
}, {
"source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)",
"headers": [{
"key": "Access-Control-Allow-Origin",
"value": "*"
}]
}]
}
}
const express = require('express');
const Fastboot = require('fastboot');
const { https } = require('firebase-functions');
const { existsSync, readFileSync } = require('fs');
const app = express();
const errorResponse = (res, error, tag) => {
let errorString = error && error.toString && error.toString();
errorString = tag ? `[${tag}] ${errorString}` : errorString;
console.error(error);
return !res.headersSent
&& res.status(500).send(errorString);
}
const success = (result, res) => {
result.html().then((html) => {
let { headers } = result;
Array.from(headers.entries())
.forEach(([key, value]) => res.set(key, value));
if (result.error) {
return failure(result.error, res);
}
res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.status(result.statusCode).send(html);
});
};
const failure = (error, res) => {
console.error('[FastBoot Failure]', error);
errorResponse(res, error, 'FastBoot Failure');
};
const initializeApplication = (fastBoot) => {
app.get('*', (request, response) => {
let { url, path } = request;
console.info('SSR Request Path:', path);
return fastBoot.visit(path, {
request,
response
}).then(
(result) => success(result, response),
(error) => failure(error, response)
);
});
return app;
};
const initializeFastBoot = (distPath = `${process.cwd()}/dist`) => {
const fastBoot = new Fastboot({
distPath,
resilient: false,
disableShoebox: false,
destroyAppInstanceInMs: '60000'
});
return { fastBoot };
};
const ssr = (distPath) => {
let { fastBoot } = initializeFastBoot(distPath);
let app = initializeApplication(fastBoot);
return https.onRequest(app);
};
module.exports.ssr = ssr();
{
"name": "zero-cost-web-app",
"version": "0.0.0",
"private": true,
"description": "Small description for zero-cost-web-app goes here",
"repository": "",
"license": "MIT",
"author": "",
"directories": {
"doc": "doc",
"test": "tests"
},
"scripts": {
"test": "ember test",
"lint:js": "eslint .",
"build": "ember build",
"start": "ember serve",
"lint:hbs": "ember-template-lint .",
"build:client": "ember build -prod",
"start:firebase": "npm run build:firebase && firebase serve",
"build:firebase": "npm run build:client && npm run copy:server",
"deploy:firebase": "npm run build:firebase && npm run run:deploy",
"run:deploy": "cd functions && FIREBASE=true firebase deploy && cd ..",
"copy:server": "rm -rf functions/dist && cp -R dist functions/dist && mv dist/index.html dist/app.html"
},
"devDependencies": {
"@ember/jquery": "^0.6.0",
"@ember/optional-features": "^0.7.0",
"broccoli-asset-rev": "^3.0.0",
"ember-ajax": "^5.0.0",
"ember-cli": "~3.10.1",
"ember-cli-app-version": "^3.2.0",
"ember-cli-babel": "^7.7.3",
"ember-cli-dependency-checker": "^3.1.0",
"ember-cli-eslint": "^5.1.0",
"ember-cli-fastboot": "^2.1.1",
"ember-cli-htmlbars": "^3.0.1",
"ember-cli-htmlbars-inline-precompile": "^2.1.0",
"ember-cli-inject-live-reload": "^1.8.2",
"ember-cli-sri": "^2.1.1",
"ember-cli-template-lint": "^1.0.0-beta.1",
"ember-cli-uglify": "^2.1.0",
"ember-data": "~3.10.0",
"ember-export-application-global": "^2.0.0",
"ember-fetch": "^6.5.1",
"ember-load-initializers": "^2.0.0",
"ember-maybe-import-regenerator": "^0.1.6",
"ember-qunit": "^4.4.1",
"ember-resolver": "^5.0.1",
"ember-source": "~3.10.0",
"ember-welcome-page": "^4.0.0",
"eslint-plugin-ember": "^6.2.0",
"eslint-plugin-node": "^9.0.1",
"loader.js": "^4.7.0",
"qunit-dom": "^0.8.4"
},
"engines": {
"node": "8.* || >= 10.*"
},
"fastbootDependencies": [
"node-fetch"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment