Skip to content

Commit

Permalink
Merge pull request #1901 from SUI-Components/sui-ssr-multisite-statics
Browse files Browse the repository at this point in the history
sui-ssr must serve multisite statics folder
  • Loading branch information
ivanmlaborda authored Feb 24, 2025
2 parents ad0fba1 + c6645b3 commit b74a0c2
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 10 deletions.
12 changes: 9 additions & 3 deletions packages/sui-ssr/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import TYPES from '../hooks-types.js'
import {hooksFactory} from './hooksFactory/index.js'
import staticCriticalCss from './middlewares/criticalCss.js'
import ssr from './middlewares/ssr.js'
import {hostFromReq, isMultiSite, readHtmlTemplate, useStaticsByHost} from './utils/index.js'
import {
hostFromReq,
isMultiSite,
readHtmlTemplate,
usePublicFolderByHost,
useStaticsFolderByHost
} from './utils/index.js'
import ssrConf from './config.js'
noOPConsole(console)

Expand Down Expand Up @@ -57,10 +63,10 @@ const _memoizedHtmlTemplatesMapping = {}
app.post(`/${TYPES.CSP_REPORT}`, bodyParser.json({type: 'application/csp-report'}), hooks[TYPES.CSP_REPORT])

runningUnderAuth && app.use(basicAuth(AUTH_DEFINITION))
app.use(express.static('statics'))
app.use(useStaticsFolderByHost(express.static))

app.use(hooks[TYPES.PRE_STATIC_PUBLIC])
app.use(useStaticsByHost(express.static))
app.use(usePublicFolderByHost(express.static))

app.use(hooks[TYPES.APP_CONFIG_SETUP])

Expand Down
36 changes: 34 additions & 2 deletions packages/sui-ssr/server/utils/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const DEFAULT_SITE_HEADER = 'X-Serve-Site'
const DEFAULT_PUBLIC_FOLDER = 'public'
const DEFAULT_DEV_PUBLIC_FOLDER = '.sui/public'
const DEFAULT_MULTI_SITE_KEY = 'default'
const DEFAULT_STATICS_FOLDER = 'statics'
const EXPRESS_STATIC_CONFIG = {index: false}

let cachedCriticalManifest
Expand All @@ -28,6 +29,14 @@ export default ({path, fs, config: ssrConf = {}, assetsManifest}) => {
return site.includes(publicFolderPrefix) ? site : `${publicFolderPrefix}${site}`
}

const multiSiteStaticsFolder = siteValue => {
const publicFolderPrefix = `${DEFAULT_PUBLIC_FOLDER}-`
// Keep compatibility with those multi site configurations
// that already define the public folder.
const site = siteValue.replace(publicFolderPrefix, '')
return `${DEFAULT_STATICS_FOLDER}-${site}`
}

const publicFolder = req => {
if (process.env.DEV_SERVER === 'true') {
return DEFAULT_DEV_PUBLIC_FOLDER
Expand All @@ -46,7 +55,7 @@ export default ({path, fs, config: ssrConf = {}, assetsManifest}) => {

const siteByHost = req => siteByHostPattern(hostPattern(req))

const useStaticsByHost = expressStatic => {
const usePublicFolderByHost = expressStatic => {
let middlewares
if (isMultiSite) {
middlewares = multiSiteKeys.reduce((acc, hostPattern) => {
Expand All @@ -68,6 +77,28 @@ export default ({path, fs, config: ssrConf = {}, assetsManifest}) => {
}
}

const useStaticsFolderByHost = expressStatic => {
let middlewares
if (isMultiSite) {
middlewares = multiSiteKeys.reduce((acc, hostPattern) => {
const site = siteByHostPattern(hostPattern)
if (acc[site]) return acc

return {
...acc,
[site]: expressStatic(multiSiteStaticsFolder(site))
}
}, {})
}

return function serveStaticByHost(req, res, next) {
const site = siteByHost(req)
const middleware = isMultiSite ? middlewares[site] : expressStatic(DEFAULT_STATICS_FOLDER)

middleware(req, res, next)
}
}

const readHtmlTemplate = req => {
const filePath = path.join(process.cwd(), publicFolder(req), 'index.html')
return fs.readFileSync(filePath, 'utf8')
Expand Down Expand Up @@ -159,7 +190,8 @@ export default ({path, fs, config: ssrConf = {}, assetsManifest}) => {
publicFolder,
readHtmlTemplate,
siteByHost,
useStaticsByHost,
usePublicFolderByHost,
useStaticsFolderByHost,
criticalDir,
criticalManifest
}
Expand Down
6 changes: 4 additions & 2 deletions packages/sui-ssr/server/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const {
publicFolder,
readHtmlTemplate,
siteByHost,
useStaticsByHost,
usePublicFolderByHost,
useStaticsFolderByHost,
criticalDir,
criticalManifest
} = utilsFactory({path, fs, config})
Expand All @@ -27,7 +28,8 @@ export {
publicFolder,
readHtmlTemplate,
siteByHost,
useStaticsByHost,
usePublicFolderByHost,
useStaticsFolderByHost,
criticalDir,
criticalManifest
}
20 changes: 18 additions & 2 deletions packages/sui-ssr/test/server/fixtures/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ import fs from 'fs'
import path from 'path'

import utilsFactory from '../../../server/utils/factory.js'
import {ssrMultiSiteConfig} from './index.js'
import {ssrConfig, ssrMultiSiteConfig} from './index.js'

const {publicFolder: publicFolderWithMultiSiteConfig} = utilsFactory({
path,
fs,
config: ssrMultiSiteConfig
})

export {publicFolderWithMultiSiteConfig}
const {useStaticsFolderByHost: staticsFolderByHostWithMultiSiteConfig} = utilsFactory({
path,
fs,
config: ssrMultiSiteConfig
})

const {useStaticsFolderByHost: staticsFolderByHostWithSingleSiteConfig} = utilsFactory({
path,
fs,
config: ssrConfig
})

export {
publicFolderWithMultiSiteConfig,
staticsFolderByHostWithMultiSiteConfig,
staticsFolderByHostWithSingleSiteConfig
}
62 changes: 61 additions & 1 deletion packages/sui-ssr/test/server/utilsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import fs from 'fs'
import path from 'path'

import {expect} from 'chai'
import sinon from 'sinon'

import utilsFactory from '../../server/utils/factory.js'
import {publicFolder} from '../../server/utils/index.js'
import {getMockedRequest} from './fixtures/index.js'
import {publicFolderWithMultiSiteConfig} from './fixtures/utils.js'
import {
publicFolderWithMultiSiteConfig,
staticsFolderByHostWithMultiSiteConfig,
staticsFolderByHostWithSingleSiteConfig
} from './fixtures/utils.js'

const ASYNC_CSS_ATTRS = 'rel="stylesheet" media="only x" as="style" onload="this.media=\'all\';'

Expand All @@ -27,6 +32,61 @@ describe('[sui-ssr] Utils', () => {
})
})

describe('Statics folder', () => {
describe('In a multi site project', () => {
it('Should serve the "statics-site" folder properly', () => {
const FOLDER_SITE_PLACEHOLDER = '$site'
const FOLDER_PATTERN = `statics-${FOLDER_SITE_PLACEHOLDER}`

const middlewareList = {}
const expressStaticSpy = (...args) => {
const [folderName] = args
middlewareList[folderName] = sinon.spy()

return (...rest) => {
return middlewareList[folderName](...rest)
}
}
const middleware = staticsFolderByHostWithMultiSiteConfig(expressStaticSpy)
const fakeReq = getMockedRequest('www.trucks.com')
const fakeRes = {}
const fakeNext = () => {}

middleware(fakeReq, fakeRes, fakeNext)

const expectedSite = 'trucks'
const expectedMultisiteStaticFolder = FOLDER_PATTERN.replace(FOLDER_SITE_PLACEHOLDER, expectedSite)

expect(middlewareList[expectedMultisiteStaticFolder].calledWith(fakeReq, fakeRes, fakeNext)).to.be.true
})
})

describe('In a single site project', () => {
it('Should serve the "statics" folder properly', () => {
const FOLDER_NAME = `statics`

const middlewareList = {}
const expressStaticSpy = (...args) => {
const [folderName] = args
middlewareList[folderName] = sinon.spy()

return (...rest) => {
return middlewareList[folderName](...rest)
}
}

const middleware = staticsFolderByHostWithSingleSiteConfig(expressStaticSpy)
const fakeReq = getMockedRequest('www.bikes.com')
const fakeRes = {}
const fakeNext = () => {}

middleware(fakeReq, fakeRes, fakeNext)

expect(middlewareList[FOLDER_NAME].calledWith(fakeReq, fakeRes, fakeNext)).to.be.true
})
})
})

describe('Create styles for', () => {
it('Should do nothing if has no config', () => {
const {createStylesFor} = utilsFactory({fs, path})
Expand Down

0 comments on commit b74a0c2

Please sign in to comment.