Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby-plugin-eufemia-theme-handler): support Gatsby > v4.24 #1623

Merged
merged 1 commit into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions packages/dnb-design-system-portal/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ const path = require('path')
const { isCI } = require('repo-utils')
const getCurrentBranchName = require('current-git-branch')
const { init } = require('./scripts/version.js')
const {
defineSrcAddition,
} = require('gatsby-plugin-eufemia-theme-handler/collectThemes')

let prebuildExists = false
const currentBranch = getCurrentBranchName()
Expand All @@ -21,7 +18,6 @@ exports.onPreInit = async () => {
} catch (e) {
//
}
defineSrcAddition(isCI && prebuildExists ? 'build/' : 'src/')

if (process.env.NODE_ENV === 'production') {
await init()
Expand Down
93 changes: 64 additions & 29 deletions packages/gatsby-plugin-eufemia-theme-handler/collectThemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,82 @@ const path = require('path')
const fs = require('fs')
const globby = require('globby')

function createThemesImport(pluginOptions) {
/**
* We want to run this in sync,
* because we need to create a import file,
* before Gatsby does import our app source.
*
* @param {object} param0 Options
* @property {object} reporter Gatsby Reporter
* @property {object} pluginOptions Gatsby pluginOptions
*/
function createThemesImport({ reporter, pluginOptions }) {
const limitThemes = Object.keys(pluginOptions.themes || [])
const packageRoot = path.dirname(require.resolve('@dnb/eufemia'))
const selector = 'style/themes/**/dnb-theme-*.{scss,css}'
const themesFiles = globby
.sync([
path.join(packageRoot, selector),
path.join(packageRoot, '**/' + selector),
])
.filter((file) => {
return !file.includes('/build/style/')
})
const globbyPaths = [
path.join(packageRoot, selector),
path.join(packageRoot, '**', selector),
]

const rawThemesFiles = globby.sync(globbyPaths)
const hasSRC = rawThemesFiles.some((file) =>
file.includes('/src/style/themes')
)
const themesFiles = rawThemesFiles.filter((file) => {
/** Never source minified files */
if (file.endsWith('.min.css')) {
return false
}

/**
* If a src folder with our styles exists locally/or on CI,
* then only use e.g. this file: dnb-theme-ui.scss
* With that, we ensure that /build can exists locally as well.
*/
if (hasSRC) {
return file.includes('/src/style/themes') && file.endsWith('.scss')
}

return file.endsWith('.css')
})

const themes = themesFiles
.map((file) => {
const themeName = (file.match(/\/dnb-theme-([^.]*)\./) || [])?.[1]
return themeName
return { file, themeName }
})
.filter((themeName) => {
.filter(({ themeName }) => {
return limitThemes.length === 0 || limitThemes.includes(themeName)
})
const srcAddition = globalThis.eufemiaThemeImportAddition
? globalThis.eufemiaThemeImportAddition
: themesFiles.some((file) => file.includes('/src/'))
? 'src/'
: ''

const imports = themes.map((themeName) => {
return `import '@dnb/eufemia/${srcAddition}style/themes/${themeName}'`
})

fs.writeFileSync(
path.resolve(__dirname, 'load-eufemia-themes.js'),
imports.join('\n')
)
const writeThemesImports = () => {
const imports = themes.map(({ file }) => {
return `import '${file}'`
})

return themes
}
fs.writeFileSync(
path.resolve(__dirname, 'load-eufemia-themes.js'),
imports.join('\n')
)
}

writeThemesImports()

const showReports = () => {
const themeNames = themes.reduce((acc, { themeName }) => {
acc.push(themeName)
return acc
}, [])

if (themeNames.length > 0) {
reporter.success(`✨ Eufemia themes: ${themeNames.join(', ')}`)
} else {
reporter.warn('Could not find any Eufemia themes!')
}
}

function defineSrcAddition(srcAddition) {
globalThis.eufemiaThemeImportAddition = srcAddition
showReports()
}

exports.defineSrcAddition = defineSrcAddition
exports.createThemesImport = createThemesImport
22 changes: 19 additions & 3 deletions packages/gatsby-plugin-eufemia-theme-handler/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,30 @@

const { createThemesImport } = require('./collectThemes')

global.themeNames = []

exports.pluginOptionsSchema = ({ Joi }) => {
return Joi.object({
themes: Joi.object().required(),
defaultTheme: Joi.string().required(),
})
}

exports.onPreBootstrap = (_, pluginOptions) => {
exports.onPreBootstrap = ({ reporter }, pluginOptions) => {
// ensure to run this after the main app has run onPreInit
createThemesImport(pluginOptions)
createThemesImport({ reporter, pluginOptions })
}

exports.onPostBuild = ({ reporter }) => {
if (global.themeNames.length > 0) {
reporter.success(
`Eufemia themes successfully extracted: ${global.themeNames.join(
', '
)}`
)
} else {
reporter.warn('No Eufemia themes found!')
}
}

exports.onCreateWebpackConfig = (
Expand All @@ -38,10 +52,12 @@ exports.onCreateWebpackConfig = (
config.optimization.splitChunks.cacheGroups.styles = {
...config.optimization.splitChunks.cacheGroups.styles,
name(module) {
if (module.context.includes('/style/themes/')) {
if (module.context.includes('/style/themes')) {
const match = module.context.match(/\/([^/]*)$/)
const moduleName = match[1].replace('theme-', '')

global.themeNames.push(moduleName)

return moduleName
}

Expand Down
11 changes: 5 additions & 6 deletions packages/gatsby-plugin-eufemia-theme-handler/themeHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,18 @@ export const onPreRenderHTML = ({
if (!isDev) {
let defaultElement
for (const element of headComponents) {
if (element.type === 'style' && element.props['data-href']) {
const href = element.props['data-href']
if (href && href.includes('.css')) {
if (
availableThemesArray.some((name) => {
return element.props['data-href'].includes(`/${name}.`)
return href.includes(`/${name}.`)
})
) {
const themeName = (element.props['data-href'].match(
/\/([^.]*)\./
) || [])?.[1]
const themeName = (href.match(/\/([^.]*)\./) || [])?.[1]

// Collect all theme CSS file paths
if (availableThemes[themeName]) {
availableThemes[themeName].file = element.props['data-href']
availableThemes[themeName].file = href

// Store the default inline styles,
// and place it below data-href="/commons.*.css"
Expand Down