Changing up how the static assets are compiled, making a 'css' directory in which individual assets CSS is written and then bundled together meaning that not all assets need to be sent up at once for css bundle to be built.

This commit is contained in:
mike12345567 2020-11-23 16:56:35 +00:00
parent 8ff9635cd1
commit b1bb7abdef
4 changed files with 48 additions and 52 deletions

View File

@ -199,19 +199,19 @@ const createEmptyAppPackage = async (ctx, app) => {
fs.mkdirpSync(newAppFolder) fs.mkdirpSync(newAppFolder)
const bulkDocs = [] let screensAndLayouts = []
for (let layout of BASE_LAYOUTS) { for (let layout of BASE_LAYOUTS) {
const cloned = cloneDeep(layout) const cloned = cloneDeep(layout)
cloned._id = generateLayoutID() cloned._id = generateLayoutID()
cloned.title = app.name cloned.title = app.name
bulkDocs.push(recurseMustache(cloned, app)) screensAndLayouts.push(recurseMustache(cloned, app))
} }
const homeScreen = cloneDeep(HOME_SCREEN) const homeScreen = cloneDeep(HOME_SCREEN)
homeScreen._id = generateScreenID() homeScreen._id = generateScreenID()
bulkDocs.push(homeScreen) screensAndLayouts.push(homeScreen)
await db.bulkDocs(bulkDocs)
await compileStaticAssets(app._id) screensAndLayouts = await compileStaticAssets(app._id, screensAndLayouts)
await db.bulkDocs(screensAndLayouts)
return newAppFolder return newAppFolder
} }

View File

@ -4,12 +4,10 @@ const compileStaticAssets = require("../../utilities/builder/compileStaticAssets
exports.save = async function(ctx) { exports.save = async function(ctx) {
const db = new CouchDB(ctx.user.appId) const db = new CouchDB(ctx.user.appId)
const appPackage = ctx.request.body let layout = ctx.request.body
// remove special doc props which couch will complain about layout._id = layout._id || generateLayoutID()
delete appPackage.layout._css layout = await compileStaticAssets(ctx.user.appId, layout)
appPackage.layout._id = appPackage.layout._id || generateLayoutID() ctx.body = await db.put(layout)
ctx.body = await db.put(appPackage.layout)
await compileStaticAssets(ctx.user.appId)
ctx.status = 200 ctx.status = 200
} }

View File

@ -1,5 +1,6 @@
const CouchDB = require("../../db") const CouchDB = require("../../db")
const { getScreenParams, generateScreenID } = require("../../db/utils") const { getScreenParams, generateScreenID } = require("../../db/utils")
const compileStaticAssets = require("../../utilities/builder/compileStaticAssets")
const { AccessController } = require("../../utilities/security/accessLevels") const { AccessController } = require("../../utilities/security/accessLevels")
exports.fetch = async ctx => { exports.fetch = async ctx => {
@ -23,12 +24,12 @@ exports.fetch = async ctx => {
exports.save = async ctx => { exports.save = async ctx => {
const appId = ctx.user.appId const appId = ctx.user.appId
const db = new CouchDB(appId) const db = new CouchDB(appId)
const screen = ctx.request.body let screen = ctx.request.body
if (!screen._id) { if (!screen._id) {
screen._id = generateScreenID() screen._id = generateScreenID()
} }
delete screen._css screen = await compileStaticAssets(ctx.user.appId, screen)
const response = await db.put(screen) const response = await db.put(screen)
ctx.message = `Screen ${screen.name} saved.` ctx.message = `Screen ${screen.name} saved.`

View File

@ -1,66 +1,63 @@
const { ensureDir, constants, copyFile, writeFile } = require("fs-extra") const {
ensureDir,
constants,
copyFile,
writeFile,
readdir,
readFile,
} = require("fs-extra")
const { join } = require("../centralPath") const { join } = require("../centralPath")
const { budibaseAppsDir } = require("../budibaseDir") const { budibaseAppsDir } = require("../budibaseDir")
const CouchDB = require("../../db")
const { getScreenParams, getLayoutParams } = require("../../db/utils")
async function getAppPackage(appId) { const CSS_DIRECTORY = "css"
const db = new CouchDB(appId)
let params = {
include_docs: true,
}
let [screens, layouts] = await Promise.all([
db.allDocs(getScreenParams(null, params)),
db.allDocs(getLayoutParams(null, params)),
])
screens = screens.rows.map(row => row.doc)
layouts = layouts.rows.map(row => row.doc)
if (!screens) {
screens = []
}
if (!layouts) {
layouts = []
}
return { screens, layouts }
}
/** /**
* Compile all the non-db static web assets that are required for the running of * Compile all the non-db static web assets that are required for the running of
* a budibase application. This includes CSS, the JSON structure of the DOM and * a budibase application. This includes CSS, the JSON structure of the DOM and
* the client library, a script responsible for reading the JSON structure * the client library, a script responsible for reading the JSON structure
* and rendering the application. * and rendering the application.
* @param {string} appId - id of the application we want to compile static assets for * @param {string} appId id of the application we want to compile static assets for
* @param {array|object} assets a list of screens or screen layouts for which the CSS should be extracted and stored.
*/ */
module.exports = async appId => { module.exports = async (appId, assets) => {
const publicPath = join(budibaseAppsDir(), appId, "public") const publicPath = join(budibaseAppsDir(), appId, "public")
const pkg = await getAppPackage(appId)
await ensureDir(publicPath) await ensureDir(publicPath)
await buildCssBundle(publicPath, pkg) for (let asset of Array.isArray(assets) ? assets : [assets]) {
await buildCssBundle(publicPath, asset)
await copyClientLib(publicPath) await copyClientLib(publicPath)
// remove props that shouldn't be present when written to DB
if (asset._css) {
delete asset._css
}
}
return assets
} }
/** /**
* Reads the _css property of all screens and the screen layouts, and creates a singular CSS * Reads the _css property of all screens and the screen layouts, and creates a singular CSS
* bundle for the app at <appId>/public/bundle.css * bundle for the app at <appId>/public/bundle.css
* @param {String} publicPath - path to the public assets directory of the budibase application * @param {String} publicPath - path to the public assets directory of the budibase application
* @param {Object} pkg - app package information * @param {Object} asset a single screen or screen layout which is being updated
*/ */
const buildCssBundle = async (publicPath, pkg) => { const buildCssBundle = async (publicPath, asset) => {
const cssPath = join(publicPath, CSS_DIRECTORY)
let cssString = "" let cssString = ""
for (let screen of pkg.screens || []) { // create a singular CSS file for this asset
if (!screen._css) continue const assetCss = asset._css ? asset._css.trim() : ""
if (screen._css.trim().length === 0) { if (assetCss.length !== 0) {
delete screen._css await ensureDir(cssPath)
continue await writeFile(join(cssPath, asset._id), assetCss)
}
cssString += screen._css
} }
if (pkg.layout._css) cssString += pkg.layout._css // bundle up all the CSS in the directory into one top level CSS file
const cssFiles = await readdir(cssPath)
for (let filename of cssFiles) {
const css = await readFile(filename)
cssString += css
}
writeFile(join(publicPath, "bundle.css"), cssString) await writeFile(join(publicPath, "bundle.css"), cssString)
} }
/** /**