Skip to content

Commit

Permalink
Convert to new build system.
Browse files Browse the repository at this point in the history
  • Loading branch information
richardgaunt committed Dec 31, 2024
1 parent 51d56ba commit ba4ebe7
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 331 deletions.
127 changes: 91 additions & 36 deletions web/themes/contrib/civictheme_base/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ Notes:
- Watch does not trigger on a directory change, only on a (scss, twig, js) file change.
*/

const fs = require('fs')
const path = require('path')
const { globSync } = require('glob')
const { execSync } = require('child_process')
const sass = require('sass')
import fs from 'fs'
import path from 'path'
import { globSync } from 'glob'
import { execSync, spawn } from 'child_process'
import * as sass from 'sass'

import scssVariables from './.storybook/importer.scss_variables.js'
import iconUtils from './components/00-base/icon/icon.utils.js'
import backgroundUtils from './components/00-base/background/background.utils.js'
import logoUtils from './components/02-molecules/logo/logo.utils.js'

// ----------------------------------------------------------------------------- UTILITIES

Expand Down Expand Up @@ -66,6 +71,10 @@ function loadStyle(path, cwd) {
return result.join('\n')
}

function stripJS(js) {
return js.replace(/\/\/# sourceMappingURL=.*\.(map|json)/gi, '')
}

function fullPath(filepath) {
return path.resolve(PATH, filepath)
}
Expand All @@ -74,6 +83,7 @@ function fullPath(filepath) {
const config = {
build: false,
watch: false,
cli: false,
combine: false,
styles: false,
styles_editor: false,
Expand All @@ -82,35 +92,42 @@ const config = {
styles_variables: false,
js: false,
assets: false,
constants: false,
base: false,
storybook: false,
}

const flags = process.argv.slice(2)
const buildType = ['build', 'watch']
const buildWatchFlagCount = flags.filter(f => buildType.indexOf(f) >= 0).length

if (flags.length <= 2 && buildWatchFlagCount <= 2) {
// If build and/or watch, or neither..
config.build = buildWatchFlagCount === 0 || flags.indexOf('build') >= 0
config.watch = flags.indexOf('watch') >= 0
config.combine = true
config.styles = true
config.styles_editor = true
config.styles_variables = true
config.js = true
config.assets = true
if (flags[0] !== 'cli') {
const buildType = ['build', 'watch']
const buildWatchFlagCount = flags?.filter(f => buildType.indexOf(f) >= 0).length

if (flags.length <= 2 && buildWatchFlagCount <= 2) {
// If build and/or watch, or neither..
config.build = buildWatchFlagCount === 0 || flags.indexOf('build') >= 0
config.watch = flags.indexOf('watch') >= 0
config.combine = true
config.styles = true
config.styles_editor = true
config.styles_variables = true
config.js = true
config.assets = true
} else {
// Fully configured from command line - everything disabled by default.
flags.forEach((flag) => {
config[flag] = true
})
}
} else {
// Fully configured from command line - everything disabled by default.
flags.forEach((flag) => {
config[flag] = true
})
config.cli = true
}

// ----------------------------------------------------------------------------- PATHS

const PATH = __dirname
const PATH = import.meta.dirname

const THEME_NAME = PATH.split('/').reverse()[0]
const DIR_CIVICTHEME = fullPath('../../contrib/civictheme/')
const DIR_COMPONENTS_IN = fullPath('./components/')
const DIR_COMPONENTS_OUT = fullPath('./components_combined/')
const DIR_UIKIT_COMPONENTS_IN = './lib/uikit/components/'
Expand All @@ -119,12 +136,13 @@ const DIR_OUT = fullPath('./dist/')
const DIR_ASSETS_IN = fullPath('./assets/')
const DIR_ASSETS_OUT = fullPath('./dist/assets/')

const COMPONENT_DIR = config.base ? DIR_COMPONENTS_IN : DIR_COMPONENTS_OUT
const STYLE_NAME = config.base ? 'civictheme' : 'styles'
const SCRIPT_NAME = config.base ? 'civictheme' : 'scripts'
const COMPONENT_DIR = config.base || config.storybook ? DIR_COMPONENTS_IN : DIR_COMPONENTS_OUT
const STYLE_NAME = config.base || config.storybook ? 'civictheme' : 'styles'
const SCRIPT_NAME = config.base || config.storybook ? 'civictheme' : 'scripts'

const STYLE_FILE_IN = `${COMPONENT_DIR}/style.scss`
const STYLE_VARIABLE_FILE_IN = `${COMPONENT_DIR}/style.css_variables.scss`
const STYLE_STORIES_FILE_IN = `${COMPONENT_DIR}/style.stories.scss`
const STYLE_THEME_FILE_IN = `${DIR_ASSETS_IN}/sass/theme.scss`
const STYLE_EDITOR_FILE_IN = `${DIR_ASSETS_IN}/sass/theme.editor.scss`
const STYLE_ADMIN_FILE_IN = `${DIR_ASSETS_IN}/sass/theme.admin.scss`
Expand All @@ -134,13 +152,15 @@ const STYLE_EDITOR_FILE_OUT = `${DIR_OUT}/${STYLE_NAME}.editor.css`
const STYLE_VARIABLE_FILE_OUT = `${DIR_OUT}/${STYLE_NAME}.variables.css`
const STYLE_ADMIN_FILE_OUT = `${DIR_OUT}/${STYLE_NAME}.admin.css`
const STYLE_LAYOUT_FILE_OUT = `${DIR_OUT}/${STYLE_NAME}.layout.css`
const STYLE_STORIES_FILE_OUT = `${DIR_OUT}/${STYLE_NAME}.stories.css`

const VAR_CT_ASSETS_DIRECTORY = `$ct-assets-directory: '/themes/custom/${THEME_NAME}/dist/assets/';`

const JS_FILE_OUT = `${DIR_OUT}/${SCRIPT_NAME}.js`
const JS_CIVIC_IMPORTS = `${COMPONENT_DIR}/**/!(*.stories|*.component|*.min|*.test|*.script|*.utils).js`
const JS_CIVIC_IMPORTS = `${COMPONENT_DIR}/**/!(*.stories|*.stories.data|*.component|*.min|*.test|*.script|*.utils).js`
const JS_LIB_IMPORTS = [fullPath('./node_modules/@popperjs/core/dist/umd/popper.js')]
const JS_ASSET_IMPORTS = [
`${DIR_CIVICTHEME}/assets/js/**/*.js`,
`${DIR_ASSETS_IN}/js/**/*.js`,
]

Expand All @@ -153,7 +173,7 @@ function build() {
}

// --------------------------------------------------------------------------- COMBINED FOLDER
if (config.combine && !config.base) {
if (config.combine && !config.base && !config.storybook) {
runCommand(`rsync -a --delete ${DIR_UIKIT_COMPONENTS_IN}/ ${DIR_UIKIT_COPY_OUT}/`)
runCommand(`rsync -a --delete ${DIR_UIKIT_COPY_OUT}/ ${DIR_COMPONENTS_OUT}/`)
runCommand(`rsync -a ${DIR_COMPONENTS_IN}/ ${DIR_COMPONENTS_OUT}/`)
Expand All @@ -165,16 +185,20 @@ function build() {
const stylecss = [
VAR_CT_ASSETS_DIRECTORY,
loadStyle(STYLE_FILE_IN, COMPONENT_DIR),
getStyleImport(STYLE_VARIABLE_FILE_IN, COMPONENT_DIR),
config.styles_variables ? getStyleImport(STYLE_VARIABLE_FILE_IN, COMPONENT_DIR) : '',
getStyleImport(STYLE_THEME_FILE_IN, PATH),
config.base ? [
getStyleImport(STYLE_ADMIN_FILE_IN, PATH),
loadStyle(STYLE_LAYOUT_FILE_IN, PATH),
].join('\n') : ''
config.styles_admin ? getStyleImport(STYLE_ADMIN_FILE_IN, PATH) : '',
config.styles_layout ? loadStyle(STYLE_LAYOUT_FILE_IN, PATH) : '',
].join('\n') : '',
config.storybook ? [
loadStyle(STYLE_STORIES_FILE_IN, COMPONENT_DIR)
].join('\n') : '',
].join('\n')

const compiled = sass.compileString(stylecss, { loadPaths: [COMPONENT_DIR, PATH] })
fs.writeFileSync(STYLE_FILE_OUT, compiled.css, 'utf-8')
const compiledImportAtTop = compiled.css.split('\n').sort(a => a.indexOf('@import') === 0 ? -1 : 0).join('\n')
fs.writeFileSync(STYLE_FILE_OUT, compiledImportAtTop, 'utf-8')
console.log(`Saved: Component styles`)
}

Expand Down Expand Up @@ -218,19 +242,24 @@ function build() {

// Third party imports.
JS_LIB_IMPORTS.forEach(filename => {
jsOutData.push(fs.readFileSync(filename, 'utf-8'))
jsOutData.push(stripJS(fs.readFileSync(filename, 'utf-8')))
})

// Civictheme asset imports.
globSync(JS_ASSET_IMPORTS).forEach(filename => {
jsOutData.push(fs.readFileSync(filename, 'utf-8'))
jsOutData.push(stripJS(fs.readFileSync(filename, 'utf-8')))
})

// Civictheme component imports.
globSync(JS_CIVIC_IMPORTS).forEach(filename => {
const name = `${THEME_NAME}_${filename.split('/').reverse()[0].replace('.js', '').replace(/-/g, '_')}`
const body = fs.readFileSync(filename, 'utf-8')
const outBody = `Drupal.behaviors.${name} = {attach: function (context, settings) {\n${body}\n}};`
let outBody = ''
if (config.storybook) {
outBody = `document.addEventListener('DOMContentLoaded', () => {\n${body}\n});`
} else {
outBody = `Drupal.behaviors.${name} = {attach: function (context, settings) {\n${body}\n}};`
}
jsOutData.push(outBody)
})

Expand All @@ -243,6 +272,18 @@ function build() {
runCommand(`rsync -a --delete --exclude js --exclude sass ${DIR_ASSETS_IN}/ ${DIR_ASSETS_OUT}/`)
}

// --------------------------------------------------------------------------- CONSTANTS
if (config.constants) {
const constants = {
BACKGROUNDS: backgroundUtils.getBackgrounds(),
ICONS: iconUtils.getIcons(),
LOGOS: logoUtils.getLogos(),
SCSS_VARIABLES: scssVariables.getVariables(),
}
fs.writeFileSync('./dist/constants.json', JSON.stringify(constants, null, 2), 'utf-8')
console.log(`Saved: Compiled constants`)
}

// --------------------------------------------------------------------------- FINISH
console.log(`Time taken: ${new Date().getTime() - startTime} ms`)
}
Expand All @@ -263,3 +304,17 @@ if (config.watch) {
}
})
}

// ----------------------------------------------------------------------------- PARALLEL CLI
if (config.cli) {
const scripts = flags.slice(1)
console.log(`Running npm commands: ${scripts.join(' && ')}`)
scripts.forEach((script, idx) => {
const child = spawn('npm', ['run', script])
child.stdout.on('data', (data) => {
const color = `\x1b[3${Math.min(idx, 3) + 3}m`
const sData = data.toString().replaceAll(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '') // strip ANSI colours
process.stdout.write(`${color}${sData}`)
});
});
}
3 changes: 2 additions & 1 deletion web/themes/contrib/civictheme_base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,6 @@
"twig-testing-library": "^1.2.0",
"vite": "^5.4.8",
"vite-plugin-twig-drupal": "^1.4.2"
}
},
"type": "module"
}
31 changes: 31 additions & 0 deletions web/themes/contrib/civictheme_base/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineConfig } from 'vite';
import { resolve } from 'path';
import twig from 'vite-plugin-twig-drupal';

export default defineConfig(({ mode }) => ({
plugins: [
twig({
namespaces: {
'base': resolve(import.meta.dirname, './components/00-base'),
'atoms': resolve(import.meta.dirname, './components/01-atoms'),
'molecules': resolve(import.meta.dirname, './components/02-molecules'),
'organisms': resolve(import.meta.dirname, './components/03-organisms'),
'templates': resolve(import.meta.dirname, './components/04-templates'),
},
}),
// This plugin allow watching files in the ./dist folder.
{
name: 'watch-dist',
configureServer: (server) => {
server.watcher.options = {
...server.watcher.options,
ignored: [
'**/.git/**',
'**/node_modules/**',
'**/.logs/**',
]
}
}
}
],
}));
5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/admin_css.js

This file was deleted.

5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/assets.js

This file was deleted.

This file was deleted.

6 changes: 0 additions & 6 deletions web/themes/contrib/civictheme_base/webpack/components_css.js

This file was deleted.

5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/css_variables.js

This file was deleted.

5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/editor_css.js

This file was deleted.

5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/layout_css.js

This file was deleted.

6 changes: 0 additions & 6 deletions web/themes/contrib/civictheme_base/webpack/libraries.js

This file was deleted.

5 changes: 0 additions & 5 deletions web/themes/contrib/civictheme_base/webpack/theme_css.js

This file was deleted.

10 changes: 0 additions & 10 deletions web/themes/contrib/civictheme_base/webpack/theme_js.js

This file was deleted.

Loading

0 comments on commit ba4ebe7

Please sign in to comment.