From fcedf75cf2218348cebc78e1eb63fb026fc235ed Mon Sep 17 00:00:00 2001 From: fiadone Date: Wed, 16 Mar 2022 22:50:18 +0100 Subject: [PATCH] refactor: simplified scaffolding and dependencies, theme optimizations, windicss integration and views ejection prototype --- .eslintrc | 2 +- README.md | 15 +- bin/eject-views/index.js | 27 + bin/eject-views/utils.js | 24 + index.html | 5 +- jsconfig.json | 1 + package-lock.json | 1635 +++++++++++++---- package.json | 14 +- src/assets/fonts/icons/icons.svg | 11 - src/assets/fonts/icons/icons.ttf | Bin 1516 -> 0 bytes .../components/button/index.scss | 26 +- src/components/button/template.twig | 17 + src/{library => }/components/icon/index.scss | 10 +- .../components/icon/template.twig | 2 +- src/config/index.js | 11 - src/helpers/device.js | 44 + src/library/components/button/template.twig | 20 - src/library/helpers/device.js | 34 - src/main.js | 23 +- .../default/components/footer/index.scss | 4 - .../default/components/footer/template.twig | 7 - .../default/components/header/index.scss | 4 - .../default/components/header/template.twig | 5 - src/pages/default/index.js | 39 - src/pages/default/style.scss | 12 - src/pages/default/transition.js | 35 - src/pages/home/index.js | 6 - src/pages/home/style.scss | 17 - src/pages/home/template.twig | 17 - src/pages/index.js | 10 - .../template.twig => templates/base.twig} | 31 +- src/templates/home.twig | 15 + src/theme/_layout.scss | 60 +- src/theme/_tokens.scss | 27 - src/theme/_typography.scss | 24 +- src/theme/_utils.scss | 23 +- src/theme/_variables.scss | 28 + src/theme/core.scss | 5 +- src/theme/index.scss | 7 - src/theme/style.scss | 19 + twig.config.js | 3 +- vite.config.js | 36 +- windi.config.js | 26 + 43 files changed, 1540 insertions(+), 841 deletions(-) create mode 100644 bin/eject-views/index.js create mode 100644 bin/eject-views/utils.js delete mode 100644 src/assets/fonts/icons/icons.svg delete mode 100644 src/assets/fonts/icons/icons.ttf rename src/{library => }/components/button/index.scss (59%) create mode 100644 src/components/button/template.twig rename src/{library => }/components/icon/index.scss (81%) rename src/{library => }/components/icon/template.twig (50%) delete mode 100644 src/config/index.js create mode 100644 src/helpers/device.js delete mode 100644 src/library/components/button/template.twig delete mode 100644 src/library/helpers/device.js delete mode 100644 src/pages/default/components/footer/index.scss delete mode 100644 src/pages/default/components/footer/template.twig delete mode 100644 src/pages/default/components/header/index.scss delete mode 100644 src/pages/default/components/header/template.twig delete mode 100644 src/pages/default/index.js delete mode 100644 src/pages/default/style.scss delete mode 100644 src/pages/default/transition.js delete mode 100644 src/pages/home/index.js delete mode 100644 src/pages/home/style.scss delete mode 100644 src/pages/home/template.twig delete mode 100644 src/pages/index.js rename src/{pages/default/template.twig => templates/base.twig} (66%) create mode 100644 src/templates/home.twig delete mode 100644 src/theme/_tokens.scss create mode 100644 src/theme/_variables.scss delete mode 100644 src/theme/index.scss create mode 100644 src/theme/style.scss create mode 100644 windi.config.js diff --git a/.eslintrc b/.eslintrc index 38dd16c..58da831 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,3 +1,3 @@ { - "extends": "@fiad" + "extends": "@fiad" } \ No newline at end of file diff --git a/README.md b/README.md index 087b350..ec9e62b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A nostalgic but modern front-end boilerplate ## Overview -*Carpentry* is essentially a custom vanilla template for [Vite](https://vitejs.dev/) with an enhanced scaffolding and a ready-made integration for [Twig](https://github.com/twigjs/twig.js/). +*Carpentry* is essentially a custom vanilla template for [Vite](https://vitejs.dev/) with an enhanced scaffolding and a ready-made integration of [Twig](https://github.com/twigjs/twig.js/) and [windicss](https://github.com/windicss/windicss). It also comes along with built-in additional utilities and basic configurations aimed to speed up your workflow. @@ -38,13 +38,20 @@ The usage of template engines is very common in backend frameworks (like *Larave Take a look to [vite-plugin-twig](https://github.com/fiadone/vite-plugin-twig/) to learn more. +#### Looking for backend integration? +Using Twig is not only a comfortable and efficient way to handle markup during static sites development, but it could be a project requirement too (e.g. when dealing with a cms or when you're asked to provide both bundle and views to be integrated in a backend). +In those cases, the *twig* files from the source tree can be ejected (and normalized) during the build process and made available under the *dist/views* directory. +To take advantage of this feature, use the *npm run build:views* command. + +> ⚠️ Attention: this feature is experimental and comes with some relevant limitations. For example, by using the built-in extensions from *@fiad/twig-addons* you'll be led to have parsing errors since they won't be available in the Twig environment of the target backend. Also, the ejection doesn't provide any automatic assets injection, so you'll need to implement it by yourself (by the way the build process will generate a manifest.json for that purpose). + ### Built-in SCSS and vanilla JS utilities Since there is no front-end framework involved here, this boilerplate comes with some "old but gold" *SCSS* and *vanilla JS* utilities out of the box. Take a look to [@fiad/stitchery](https://github.com/fiadone/stitchery/) and [@fiad/toolbox](https://github.com/fiadone/toolbox/) to learn more. -### Pre-structured router with page lazy loading and transitions -Take a look to [barba.js](https://barba.js.org/) to learn more. +### Pre-configured WindiCSS +Take a look to [windicss](https://github.com/windicss/windicss) to learn more. -### Pre-configured *css* purging for production +### Pre-configured *CSS* purging for production Take a look to [postcss-purgecss](https://github.com/FullHuman/purgecss/tree/main/packages/postcss-purgecss/) to learn more. diff --git a/bin/eject-views/index.js b/bin/eject-views/index.js new file mode 100644 index 0000000..c7c9ec4 --- /dev/null +++ b/bin/eject-views/index.js @@ -0,0 +1,27 @@ +const path = require('path') +const glob = require('glob') +const fs = require('fs-extra') +const { getTemplateFilename, getTemplateContent } = require('./utils') + +const cwd = process.cwd() +const srcPath = path.join(cwd, 'src') +const distPath = path.join(cwd, 'dist/views') +const sourceFiles = glob.sync(path.join(srcPath, '**/*.twig'), { + ignore: [ + '.git/**', + 'bin/**', + 'dist/**', + 'node_modules/**', + 'public/**', + 'src/**' + ] +}) + +fs.emptyDirSync(distPath) + +sourceFiles.forEach(filepath => { + const filename = getTemplateFilename(filepath, srcPath, distPath) + const content = getTemplateContent(filepath) + if (!filename || !content) return + fs.outputFileSync(filename, content) +}) \ No newline at end of file diff --git a/bin/eject-views/utils.js b/bin/eject-views/utils.js new file mode 100644 index 0000000..4ac39e6 --- /dev/null +++ b/bin/eject-views/utils.js @@ -0,0 +1,24 @@ +const path = require('path') +const fs = require('fs-extra') + +module.exports.getTemplateFilename = function(file, srcPath, distPath) { + try { + const base = path.dirname(file).replace(srcPath, distPath) + const name = path.basename(file, '.twig') + return `${(name === 'template') ? base : path.join(base, name)}.twig` + } catch { + return null + } +} + +module.exports.getTemplateContent = function(file) { + try { + return ( + fs.readFileSync(file) + .toString() + .replace(/({{\s?(sourcePath|publicPath)\s?}}|\/template)/g, '')) + .replace(/(\s)* \ No newline at end of file diff --git a/src/templates/home.twig b/src/templates/home.twig new file mode 100644 index 0000000..f2f4dc0 --- /dev/null +++ b/src/templates/home.twig @@ -0,0 +1,15 @@ +{% extends 'templates/base.twig' %} + +{% block content %} +
+
+ @fiad/carpentry +

{{ title }}

+

{{ subtitle }}

+

{{ abstract|raw }}

+
+ {% include 'components/button/template.twig' with button only %} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/theme/_layout.scss b/src/theme/_layout.scss index 11186c6..4c8c03f 100644 --- a/src/theme/_layout.scss +++ b/src/theme/_layout.scss @@ -1,5 +1,8 @@ html { + background-color: var(--color-background-default); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-size: 100%; + @include auto-scaling; } @@ -7,61 +10,8 @@ html, body { width: 100%; height: 100%; - background-color: $white; -} - -.container { - width: 100%; - max-width: rem($container-maxwidth); - padding: 0 rem($container-padding); - position: relative; - margin: 0 auto; } -*[class*="flex"] { - display: flex; - - @each $key, $value in ('row': row, 'col': column) { - &.flex\:#{$key} { - flex-direction: $value; - } - - &.flex\:#{$key}-reverse { - flex-direction: #{$value}-reverse; - } - } - - @each $key, $value in ( - 'start': flex-start, - 'center': center, - 'end': flex-end, - 'between': space-between, - 'around': space-around, - 'evenly': space-evenly - ) { - &.justify\:#{$key} { - justify-content: $value; - } - } - - @each $key, $value in ( - 'start': flex-start, - 'center': center, - 'stretch': stretch, - 'end': flex-end - ) { - &.align\:#{$key} { - align-items: $value; - } - - & > *.align\:#{$key} { - align-self: $value; - } - } -} - -[data-reveal] { - opacity: 0; +body { + min-width: 320px; } - -@include grid(12, #{rem($grid-gutter)}); \ No newline at end of file diff --git a/src/theme/_tokens.scss b/src/theme/_tokens.scss deleted file mode 100644 index af1dd9c..0000000 --- a/src/theme/_tokens.scss +++ /dev/null @@ -1,27 +0,0 @@ -// PATHS -$assets: '/src/assets'; -// RESPONSIVE -$mq-breakpoints: ( - "tablet": 768px, - "desktop": 1024px, - "wide": 1366px -); -// SIZES -$container-maxwidth: 1280px; -$container-padding: 24px; -$grid-gutter: 24px; -$scalar: 8px; -$radius: 4px; -// FONTS -$default-font: 'Montserrat', sans-serif; -$icon-font: "icons"; -// COLORS -$black: #000000; -$gray: #BFC0C0; -$white: #FFFFFF; -$primary: #81A684; -$secondary: #EF8354; -$tertiary: #4F5D75; -$indigo: #2D3142; -// MISC -$default-duration: .3s; \ No newline at end of file diff --git a/src/theme/_typography.scss b/src/theme/_typography.scss index 0d5fef3..ff0d32d 100644 --- a/src/theme/_typography.scss +++ b/src/theme/_typography.scss @@ -1,13 +1,13 @@ body { - font-family: $default-font; + font-family: var(--font-default); font-size: 1rem; font-variant-ligatures: none; - line-height: 1; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + line-height: 1; text-size-adjust: none; text-rendering: optimizeLegibility; - color: $tertiary; + color: var(--color-text-default); } h1, .h1, @@ -30,6 +30,7 @@ h6, .h6 { } p, .p { + margin-bottom: 0.25em; line-height: 1.5; } @@ -46,18 +47,11 @@ small { } a { - -webkit-tap-highlight-color: transparent; -} - -.c-primary { - color: $primary; -} - -.c-secondary { - color: $secondary; + text-decoration: none; + color: inherit; } ::selection { - background-color: $tertiary; - color: $white; -} \ No newline at end of file + background-color: var(--color-background-tertiary); + color: var(--color-text-tertiary); +} diff --git a/src/theme/_utils.scss b/src/theme/_utils.scss index 7291063..42c179c 100644 --- a/src/theme/_utils.scss +++ b/src/theme/_utils.scss @@ -1,19 +1,4 @@ -@import '@fiad/stitchery'; -@import 'sass-mq/mq'; - -@mixin font-face($name, $weight: 'normal', $style: 'normal', $display: 'swap') { - @font-face { - font-family: $name; - src: url('#{$assets}/fonts/#{$name}/#{$name}.woff') format('woff'), - url('#{$assets}/fonts/#{$name}/#{$name}.ttf') format('truetype'), - url('#{$assets}/fonts/#{$name}/#{$name}.svg##{$name}') format('svg'); - font-weight: $weight; - font-style: $style; - font-display: $display; - } -} - -@mixin off-container { - width: 100vw; - left: calc((100% - 100vw) / 2); -} +@function breakpoint($name, $adjustment: 0) { + $value: map-get($name, $breakpoints); + @return ($value + $adjustment) * 1px; +} \ No newline at end of file diff --git a/src/theme/_variables.scss b/src/theme/_variables.scss new file mode 100644 index 0000000..5523ab7 --- /dev/null +++ b/src/theme/_variables.scss @@ -0,0 +1,28 @@ +$assets: '/src/assets'; + +$breakpoints: ( + "sm": 768, + "md": 1024, + "lg": 1280, + "xl": 1440 +); + +$glyphs: ( + "github": \f09b +); + +:root { + // colors + --color-background-default: #FBF5F3; + --color-background-primary: #81A684; + --color-background-secondary: #EF8354; + --color-background-tertiary: #4F5D75; + --color-text-default: #39393A; + --color-text-primary: #FFFFFF; + --color-text-secondary: #FFFFFF; + --color-text-tertiary: #FFFFFF; + // fonts + --font-default: 'Montserrat', sans-serif; + // misc + --transition-duration-default: .3s; +} \ No newline at end of file diff --git a/src/theme/core.scss b/src/theme/core.scss index d9fe8e7..a1c77b2 100644 --- a/src/theme/core.scss +++ b/src/theme/core.scss @@ -1,2 +1,3 @@ -@import 'tokens'; -@import 'utils'; \ No newline at end of file +@import '@fiad/stitchery'; +@import 'variables'; +@import 'utils'; diff --git a/src/theme/index.scss b/src/theme/index.scss deleted file mode 100644 index 531b41b..0000000 --- a/src/theme/index.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import 'the-new-css-reset/css/reset'; - -@import 'layout'; -@import 'typography'; - -@import '~/library/components/button'; -@import '~/library/components/icon'; \ No newline at end of file diff --git a/src/theme/style.scss b/src/theme/style.scss new file mode 100644 index 0000000..4e465b9 --- /dev/null +++ b/src/theme/style.scss @@ -0,0 +1,19 @@ +// reset +@import 'the-new-css-reset/css/reset'; + +// globals +@import 'layout'; +@import 'typography'; + +// critical UI +@import '../components/button'; +@import '../components/icon'; + +// fonts +@font-face { + src: url('#{$assets}/fonts/icons/icons.woff') format('woff'); + font-family: 'icons'; + font-weight: normal; + font-style: normal; + font-display: swap; +} \ No newline at end of file diff --git a/twig.config.js b/twig.config.js index 395a48b..261ce70 100644 --- a/twig.config.js +++ b/twig.config.js @@ -1,4 +1,3 @@ -const path = require('path') const twigAddons = require('@fiad/twig-addons') module.exports = { @@ -10,6 +9,6 @@ module.exports = { currentYear: new Date().getFullYear() }, settings: { - views: path.resolve(__dirname, 'src') + views: 'src' } } \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 97f624d..8bc7576 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,20 +1,37 @@ import { defineConfig } from 'vite' -import purgecss from '@fullhuman/postcss-purgecss' -import twig from 'vite-plugin-twig' +import Twig from 'vite-plugin-twig' +import WindiCSS from 'vite-plugin-windicss' +import PurgeCSS from '@fullhuman/postcss-purgecss' +import { glob } from 'glob' export default defineConfig(({ command }) => ({ build: { + manifest: true, rollupOptions: { - input: { - index: 'index.html' - } + input: glob.sync('**/*.html', { + ignore: [ + '.git/**', + 'bin/**', + 'dist/**', + 'node_modules/**', + 'public/**', + 'src/**' + ] + }) } }, css: { postcss: { - plugins: (command !== 'build') ? [] : [ - purgecss({ - content: ['./**/*.html', './src/**/*.twig'] + plugins: (command === 'build') && [ + PurgeCSS({ + content: ['**/*.{html,twig}'], + skippedContentGlobs: [ + '.git/**', + 'bin/**', + 'dist/**', + 'node_modules/**', + 'public/**' + ] }) ] }, @@ -25,7 +42,8 @@ export default defineConfig(({ command }) => ({ } }, plugins: [ - twig() + Twig(), + WindiCSS() ], resolve: { extensions: ['.js', '.json', '.css', '.scss'], diff --git a/windi.config.js b/windi.config.js new file mode 100644 index 0000000..591309c --- /dev/null +++ b/windi.config.js @@ -0,0 +1,26 @@ +import { defineConfig } from 'windicss/helpers' + +export default defineConfig({ + extract: { + include: ['**/*.{html,twig}'], + exclude: [ + '.git/**', + 'bin/**', + 'dist/**', + 'node_modules/**', + 'public/**' + ] + }, + theme: { + container: { + center: true, + padding: '1rem' + }, + screens: { + sm: '768px', + md: '1024px', + lg: '1280px', + xl: '1440px' + } + } +})