π Structure Overview
Even though our starter snapshot is rather simple, a small overview of the file structure we prepared is required.
- Root
- Assets
- Build
- Views
- WWW
- Complete Structure
Let's start by reviewing our top level folders & files
βββ []assets # Scripts & Styles source code. Everything inside will be compiled.
βββ []build # Our compilation scripts launched by `npm start`
βββ []data # All the content comes from JSON files inside this directory. It's similar to a database.
βββ []views # Where all the layout magic happens. Our final HTML file comes from all the .twig files inside
βββ []www # Webserver root directory, contains all the compiled code & everything inside will be accessible by the browser.
βββ eleventy.config.cjs # 11ty config file
βββ package.json # NPM imports
Time to dig deeper, the /assets folder is one we'll work a lot in!
We follow a simple structure to improve readability & get our coders life smoother.
First, let's focus on the scripts
βββ []assets
βΒ Β βββ []scripts
βΒ Β βΒ Β βββ []modules # ModularJS modules
βΒ Β βΒ Β βΒ Β ββ Example.js # Sample ModularJS module
βΒ Β βΒ Β βββ []utils # Utilities scripts
β βΒ Β βββ app.js # JS entry point, everything goes from here to generate `www/assets/scripts/app.js`
βΒ Β βΒ Β βββ config.js # Global constants are grouped here
βΒ Β βΒ Β βββ modules.js # Our modules import file, must be filled manually
βΒ Β βββ ...
βββ ...
And now for the styles
βββ []assets
βΒ Β βββ ...
βΒ Β βββ []styles
βΒ Β βββ []components # Contains a .scss file for each component
βΒ Β βββ []generic # Contains default .scss file to help with development (resets, normalizers, etc.)
βΒ Β βββ []settings # This is where we store our SCSS & CSS variables that'll be used extensively. It is split in multiple files for readability
βΒ Β βββ []tools # Contains useful SCSS functions and/or mixins, can be split in multiple files for readability
βΒ Β βββ []utilities # Contains useful CSS classes and animations. Those are too "small" to be considered actual components, they're more helpers.
β Β Β βββ _document.scss # Global CSS settings (like html & body)
βΒ Β Β Β βββ common.scss # Styles imports common to both `main.scss` & `critical.css`. Only for variables & tools: it shouldn't build any actual CSS code.
βΒ Β Β Β βββ main.scss # Styles entry point, everything goes from here to generate `www/assets/styles/main.css`
βΒ Β Β Β βββ critical.scss # Critical CSS entry point, everything goes from here to generate the inline styles in the `head` of our HTML file
βββ ...
This folder contains our compilation scripts launched by npm start. We won't be playing in here but it's good for you to know its purpose.
βββ []build # Our compilation scripts launched by `npm start`
βΒ Β βββ []helpers
βΒ Β βββ []tasks
This is where all the layout magic happens. Our final .html files will come out of all the .twig files inside here.
βββ []views
βΒ Β βββ []layouts # Contains layouts that can be extended in our templates (only one in our case)
βΒ Β βββ []partials # Sections of the website. Using partials helps with our templates readability and prevents repeating code a bit
βΒ Β βββ []snippets # Snippets are small parts of code commonly reused (images, buttons, accordions, etc). It prevents repeating code A LOT!
βΒ Β βββ []templates # Each .twig file in this directory will convert to a .html file in the `www` folder
This is the webserver root directory. It contains all the compiled code & everything inside will be accessible by the browser.
βββ []www
βββ []assets # Contains static & compiled assets
β βββ []3d
β βββ []fonts
β βββ []images
β βββ []scripts
β βββ []styles
βββ index.html # Our final compiled HTML file
βββ []assets # Scripts & Styles source code. Everything inside will be compiled.
β β
βΒ Β βββ []scripts # Scripts source code root
βΒ Β βΒ Β βββ []modules # ModularJS modules
βΒ Β βΒ Β βΒ Β βββ Example.js # Sample ModularJS module
βΒ Β βΒ Β βββ []utils # Utilities scripts
β βΒ Β βββ app.js # JS entry point, everything goes from here to generate `www/assets/scripts/app.js`
βΒ Β βΒ Β βββ config.js # Global constants are grouped here
βΒ Β βΒ Β βββ modules.js # Our modules import file, must be filled manually
β β
βΒ Β βββ []styles # Styles source code root
βΒ Β βββ []components # Contains a .scss file for each component
βΒ Β βββ []generic # Contains default .scss file to help with development (resets, normalizers, etc.)
βΒ Β βββ []settings # This is where we store our SCSS & CSS variables that'll be used extensively. It is split in multiple files for readability
βΒ Β βββ []tools # Contains useful SCSS functions and/or mixins, can be split in multiple files for readability
βΒ Β βββ []utilities # Contains useful CSS classes and animations. Those are too "small" to be considered actual components, they're more helpers.
β Β Β βββ _document.scss # Global CSS settings (like html & body)
βΒ Β Β Β βββ common.scss # Styles imports common to both `main.scss` & `critical.css`. Only for variables & tools: it shouldn't build any actual CSS code.
βΒ Β Β Β βββ main.scss # Styles entry point, everything goes from here to generate `www/assets/styles/main.css`
βΒ Β Β Β βββ critical.scss # Critical CSS entry point, everything goes from here to generate the inline styles in the `head` of our HTML file
β
βββ []build # Our compilation scripts launched by `npm start`
βΒ Β βββ []helpers
βΒ Β βββ []tasks
β
βββ []data # All the content comes from JSON files inside this directory. It's similar to a database.
β
βββ []views # Where all the layout magic happens. Our final HTML file comes from all the .twig files inside
βΒ Β βββ []layouts # Contains layouts that can be extended in our templates (only one in our case)
βΒ Β βββ []partials # Sections of the website. Using partials helps with our templates readability and prevents repeating code a bit
βΒ Β βββ []snippets # Snippets are small parts of code commonly reused (images, buttons, accordions, etc). It prevents repeating code A LOT!
βΒ Β βββ []templates # Each .twig file in this directory will convert to a .html file in the `www` folder
β
βββ []www # Webserver root directory, contains all the compiled code & everything inside will be accessible by the browser.
βββ []assets # Contains static & compiled assets
β βββ []3d
β βββ []fonts
β βββ []images
β βββ []scripts
β βββ []styles
βββ index.html # Our final compiled HTML file
Javascriptβ
/assets/scripts/app.js is our entry point! Everything goes from here to generate /www/assets/scripts/app.js. We then use ModularJS to split our code in Modules that we can call on DOM elements in our view files.
ModularJS basics
We use this library for its ease of use, you'll get the hang of it quickly! The base JS code for a module is as follows:
import { module } from 'modujs';
export default class extends module {
constructor(m) {
super(m);
// selectors
this.$button = this.$('button')[0] // [0] because the `$` function return a NodeList
this.$items = this.$('item')
// event shortcuts
this.events = {
click: {
button: 'doSomething'
}
}
}
doSomething() {
console.log('Hello world');
}
}
Using this.events is a shortcut! This way, you don't have to handle the addEventListener and removeEventListener combo, it's all handled already!
And to call the module in our DOM, it's as simple as that:
<div data-module-example>
<h2>Example</h2>
<button data-example="button">Button</button>
<ul>
<li data-example="item">Item 1</li>
<li data-example="item">Item 2</li>
</ul>
</div>
Appart from that, we can use all the nice ES6 features we all love and not worry about browser support thanks to our building scripts!
Stylesβ
SCSS for better styles handlingβ
We will be using SCSS on this project. This preprocessor scripting language extends the capabilities of regular CSS and offers various advantages (improved readability, modularity, conditional statements, easier maintenance, etc).
You can toggle a grid helper to highlight the 12 cols grid with CTRL + G
Prefixesβ
We use short prefixes on our classes to improve readability.
All our components start with .c- like .c-example. Then we have utility classes that start with .u- like .u-screen-reader-text.
CSS Methodologyβ
In combination with this, we'll follow a slightly altered BEM methodology.
We use the same notion of blocks, elements and modifiers with these exceptions:
- Blocks and elements are separated by a single
_(underscore) instead of two.
So βc-block__elementbecomes βc-block_element - Modifiers are not prefixed by blocks and elements, we directly state them with a
-prefix.
For example:c-block_element -modifier.