Removing the static CSS bundling from the server as it is no longer required.

This commit is contained in:
mike12345567 2020-12-09 12:30:21 +00:00
parent 22932d7b52
commit 3959a18406
9 changed files with 6 additions and 200 deletions

View File

@ -32,7 +32,6 @@ const {
} = require("../../constants/screens") } = require("../../constants/screens")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const { recurseMustache } = require("../../utilities/mustache") const { recurseMustache } = require("../../utilities/mustache")
const { generateAssetCss } = require("../../utilities/builder/generateCss")
const { USERS_TABLE_SCHEMA } = require("../../constants") const { USERS_TABLE_SCHEMA } = require("../../constants")
const APP_PREFIX = DocumentTypes.APP + SEPARATOR const APP_PREFIX = DocumentTypes.APP + SEPARATOR
@ -131,12 +130,6 @@ exports.fetchAppPackage = async function(ctx) {
const application = await db.get(ctx.params.appId) const application = await db.get(ctx.params.appId)
const [layouts, screens] = await Promise.all([getLayouts(db), getScreens(db)]) const [layouts, screens] = await Promise.all([getLayouts(db), getScreens(db)])
for (let layout of layouts) {
layout._css = generateAssetCss([layout.props])
}
for (let screen of screens) {
screen._css = generateAssetCss([screen.props])
}
ctx.body = { ctx.body = {
application, application,
screens, screens,
@ -230,10 +223,6 @@ const createEmptyAppPackage = async (ctx, app) => {
screensAndLayouts.push(loginScreen) screensAndLayouts.push(loginScreen)
await db.bulkDocs(screensAndLayouts) await db.bulkDocs(screensAndLayouts)
// at the end add CSS to all the structures await compileStaticAssets(app._id)
for (let asset of screensAndLayouts) {
asset._css = generateAssetCss([asset.props])
}
await compileStaticAssets(app._id, screensAndLayouts)
return newAppFolder return newAppFolder
} }

View File

@ -7,8 +7,6 @@ const { budibaseAppsDir } = require("../../../utilities/budibaseDir")
const PouchDB = require("../../../db") const PouchDB = require("../../../db")
const env = require("../../../environment") const env = require("../../../environment")
const EXCLUDED_DIRECTORIES = ["css"]
/** /**
* Finalises the deployment, updating the quota for the user API key * Finalises the deployment, updating the quota for the user API key
* The verification process returns the levels to update to. * The verification process returns the levels to update to.
@ -140,15 +138,9 @@ exports.uploadAppAssets = async function({ appId, bucket, accountId }) {
let uploads = [] let uploads = []
// Upload HTML, CSS and JS of the web app // Upload HTML and JS of the web app
walkDir(appAssetsPath, function(filePath) { walkDir(appAssetsPath, function(filePath) {
const filePathParts = filePath.split("/") const filePathParts = filePath.split("/")
const publicIndex = filePathParts.indexOf("public")
const directory = filePathParts[publicIndex + 1]
// don't include these top level directories
if (EXCLUDED_DIRECTORIES.indexOf(directory) !== -1) {
return
}
const appAssetUpload = prepareUploadForS3({ const appAssetUpload = prepareUploadForS3({
file: { file: {
path: filePath, path: filePath,

View File

@ -1,8 +1,6 @@
const CouchDB = require("../../db") const CouchDB = require("../../db")
const { getScreenParams, generateScreenID } = require("../../db/utils") const { getScreenParams, generateScreenID } = require("../../db/utils")
const { AccessController } = require("../../utilities/security/roles") const { AccessController } = require("../../utilities/security/roles")
const { generateAssetCss } = require("../../utilities/builder/generateCss")
const compileStaticAssets = require("../../utilities/builder/compileStaticAssets")
exports.fetch = async ctx => { exports.fetch = async ctx => {
const appId = ctx.user.appId const appId = ctx.user.appId
@ -32,10 +30,6 @@ exports.save = async ctx => {
} }
const response = await db.put(screen) const response = await db.put(screen)
// update CSS so client doesn't need to make a call directly after
screen._css = generateAssetCss([screen.props])
await compileStaticAssets(appId, screen)
ctx.message = `Screen ${screen.name} saved.` ctx.message = `Screen ${screen.name} saved.`
ctx.body = { ctx.body = {
...screen, ...screen,

View File

@ -16,19 +16,10 @@ const CouchDB = require("../../../db")
const setBuilderToken = require("../../../utilities/builder/setBuilderToken") const setBuilderToken = require("../../../utilities/builder/setBuilderToken")
const fileProcessor = require("../../../utilities/fileProcessor") const fileProcessor = require("../../../utilities/fileProcessor")
const env = require("../../../environment") const env = require("../../../environment")
const { generateAssetCss } = require("../../../utilities/builder/generateCss")
const compileStaticAssets = require("../../../utilities/builder/compileStaticAssets")
// this was the version before we started versioning the component library // this was the version before we started versioning the component library
const COMP_LIB_BASE_APP_VERSION = "0.2.5" const COMP_LIB_BASE_APP_VERSION = "0.2.5"
exports.generateCss = async function(ctx) {
const structure = ctx.request.body
structure._css = generateAssetCss([structure.props])
await compileStaticAssets(ctx.appId, structure)
ctx.body = { css: structure._css }
}
exports.serveBuilder = async function(ctx) { exports.serveBuilder = async function(ctx) {
let builderPath = resolve(__dirname, "../../../../builder") let builderPath = resolve(__dirname, "../../../../builder")
if (ctx.file === "index.html") { if (ctx.file === "index.html") {

View File

@ -10,7 +10,6 @@ const router = Router()
function generateSaveValidation() { function generateSaveValidation() {
// prettier-ignore // prettier-ignore
return joiValidator.body(Joi.object({ return joiValidator.body(Joi.object({
_css: Joi.string().allow(""),
name: Joi.string().required(), name: Joi.string().required(),
routing: Joi.object({ routing: Joi.object({
route: Joi.string().required(), route: Joi.string().required(),

View File

@ -5,22 +5,6 @@ const env = require("../../environment")
const authorized = require("../../middleware/authorized") const authorized = require("../../middleware/authorized")
const { BUILDER } = require("../../utilities/security/permissions") const { BUILDER } = require("../../utilities/security/permissions")
const usage = require("../../middleware/usageQuota") const usage = require("../../middleware/usageQuota")
const joiValidator = require("../../middleware/joi-validator")
const Joi = require("joi")
function generateCssValidator() {
return joiValidator.body(
Joi.object({
_id: Joi.string().required(),
_rev: Joi.string().required(),
props: Joi.object()
.required()
.unknown(true),
})
.required()
.unknown(true)
)
}
const router = Router() const router = Router()
@ -40,12 +24,6 @@ if (env.NODE_ENV !== "production") {
} }
router router
.post(
"/api/css/generate",
authorized(BUILDER),
generateCssValidator(),
controller.generateCss
)
.post( .post(
"/api/attachments/process", "/api/attachments/process",
authorized(BUILDER), authorized(BUILDER),

View File

@ -1,46 +0,0 @@
const { generateAssetCss, generateCss } = require("../../../utilities/builder/generateCss")
describe("generate_css", () => {
it("Check how array styles are output", () => {
expect(generateCss({ margin: ["0", "10", "0", "15"] })).toBe("margin: 0 10 0 15;")
})
it("Check handling of an array with empty string values", () => {
expect(generateCss({ padding: ["", "", "", ""] })).toBe("")
})
it("Check handling of an empty array", () => {
expect(generateCss({ margin: [] })).toBe("")
})
it("Check handling of valid font property", () => {
expect(generateCss({ "font-size": "10px" })).toBe("font-size: 10px;")
})
})
describe("generate_screen_css", () => {
const normalComponent = { _id: "123-456", _component: "@standard-components/header", _children: [], _styles: { normal: { "font-size": "16px" }, hover: {}, active: {}, selected: {} } }
it("Test generation of normal css styles", () => {
expect(generateAssetCss([normalComponent])).toBe(".header-123-456 {\nfont-size: 16px;\n}")
})
const hoverComponent = { _id: "123-456", _component: "@standard-components/header", _children: [], _styles: { normal: {}, hover: {"font-size": "16px"}, active: {}, selected: {} } }
it("Test generation of hover css styles", () => {
expect(generateAssetCss([hoverComponent])).toBe(".header-123-456:hover {\nfont-size: 16px;\n}")
})
const selectedComponent = { _id: "123-456", _component: "@standard-components/header", _children: [], _styles: { normal: {}, hover: {}, active: {}, selected: { "font-size": "16px" } } }
it("Test generation of selection css styles", () => {
expect(generateAssetCss([selectedComponent])).toBe(".header-123-456::selection {\nfont-size: 16px;\n}")
})
const emptyComponent = { _id: "123-456", _component: "@standard-components/header", _children: [], _styles: { normal: {}, hover: {}, active: {}, selected: {} } }
it("Testing handling of empty component styles", () => {
expect(generateAssetCss([emptyComponent])).toBe("")
})
})

View File

@ -1,66 +1,18 @@
const { const { ensureDir, constants, copyFile } = require("fs-extra")
ensureDir,
constants,
copyFile,
writeFile,
readdir,
readFile,
existsSync,
} = require("fs-extra")
const { join } = require("../centralPath") const { join } = require("../centralPath")
const { budibaseAppsDir } = require("../budibaseDir") const { budibaseAppsDir } = require("../budibaseDir")
const CSS_DIRECTORY = "css"
/** /**
* 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 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, assets) => { module.exports = async appId => {
const publicPath = join(budibaseAppsDir(), appId, "public") const publicPath = join(budibaseAppsDir(), appId, "public")
await ensureDir(publicPath) await ensureDir(publicPath)
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
* bundle for the app at <appId>/public/bundle.css
* @param {String} publicPath - path to the public assets directory of the budibase application
* @param {Object} asset a single screen or screen layout which is being updated
*/
const buildCssBundle = async (publicPath, asset) => {
const cssPath = join(publicPath, CSS_DIRECTORY)
let cssString = ""
// create a singular CSS file for this asset
const assetCss = asset._css ? asset._css.trim() : ""
if (assetCss.length !== 0) {
await ensureDir(cssPath)
await writeFile(join(cssPath, asset._id), assetCss)
}
// bundle up all the CSS in the directory into one top level CSS file
if (existsSync(cssPath)) {
const cssFiles = await readdir(cssPath)
for (let filename of cssFiles) {
const css = await readFile(join(cssPath, filename))
cssString += css
}
}
await writeFile(join(publicPath, "bundle.css"), cssString)
} }
/** /**

View File

@ -1,43 +0,0 @@
exports.generateAssetCss = component_arr => {
let styles = ""
for (const { _styles, _id, _children, _component } of component_arr) {
let [componentName] = _component.match(/[a-z]*$/)
Object.keys(_styles).forEach(selector => {
const cssString = exports.generateCss(_styles[selector])
if (cssString) {
styles += exports.applyClass(_id, componentName, cssString, selector)
}
})
if (_children && _children.length) {
styles += exports.generateAssetCss(_children) + "\n"
}
}
return styles.trim()
}
exports.generateCss = style => {
let cssString = Object.entries(style).reduce((str, [key, value]) => {
if (typeof value === "string") {
if (value) {
return (str += `${key}: ${value};\n`)
}
} else if (Array.isArray(value)) {
if (value.length > 0 && !value.every(v => v === "")) {
return (str += `${key}: ${value.join(" ")};\n`)
}
}
return str
}, "")
return (cssString || "").trim()
}
exports.applyClass = (id, name = "element", styles, selector) => {
if (selector === "normal") {
return `.${name}-${id} {\n${styles}\n}`
} else {
let sel = selector === "selected" ? "::selection" : `:${selector}`
return `.${name}-${id}${sel} {\n${styles}\n}`
}
}