🎉🎉🎉
Â
We're a JavaScript shop.
Â
🎉🎉🎉
A universal JavaScript runtime. Asynchronous and non-blocking, perfect for active servers or just local tooling. Node 10+ runs all our tooling.
Â
Drop into a REPL at any time:
node
> 1 + 1
2
>
Run any JavaScript file:
node cats.js
"meow"
Manage it with nvm.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
Set a new default node:
nvm install v10 && nvm alias default v10
* Docker projects handle this
See all nodes installed:
nvm ls
v10.15.0
v10.15.1
-> v10.16.0
NPM manages node packages and project structure. It is one of the only globally installed node packages on your machine.
npm init
npm is used to start node projects and create package.json files:
npm installs node modules for projects:
npm install webpack --save-dev
* Docker projects handle this
npm install -g npm@6
Yes, you use npm to update npm. Turtles.
A version of npm will be installed alongside node. Keep it updated.
For the time being, PHP is still part of Phase2 frontend tooling to compile php-twig.Â
Â
August 2019: Composer will no longer be required as of Particle 10.4 with our move to patternlab-node.
Â
September-October 2019: We'll be experimenting with twig.js and StoryBook, entirely removing the need for PHP within our frontend tooling.
Homebrew is our friend.
brew install php72
* Docker projects handle this
Config/Tools/Packages
Design System
Apps
npm, webpack, package.json scripts
Components & assets: twig, CSS, JS, icons
Something that eats components & assets:
Drupal, Pattern Lab, etc
Syntax | Runtime | Lint | Format | Process | Optimize | Bundle | Generate | Test | |
---|---|---|---|---|---|---|---|---|---|
JavaScript | ES2016+ TypeScript |
Node Browser |
eslint | prettier | Babel BrowsersList |
Terser | Webpack | Yeoman | Jest |
Styles | SCSS CSS (Tailwind) |
Browser | stylelint | prettier | SCSS Tailwind PostCSS BrowsersList |
PurgeCSS CSSNano |
Webpack | Yeoman | Backstop |
Server markup | Twig  |
PHP* Node* |
twiglint | prettier | Webpack | Yeoman | pa11y Cypress |
||
UI: jQuery | ES2016+ TypeScript |
Browser | eslint | prettier | Babel | Terser | Webpack | Yeoman | Jest Cypress |
UI: Vue/React | ES2016+ TypeScript Vue/React |
Browser | eslint | prettier | Babel | Terser | Webpack | Yeoman | vue-testing-library react-testing-library Cypress |
ES2016+
Webpack
Eslint
Babel
Assets
Tests
SCSS/Tailwind
Webpack
stylelint
PostCSS
Assets
ES2016+
Webpack
Eslint
Stylelint
Babel
PostCSS
Assets
Tests
Twig
Webpack
Assets
Why are you making this all so complicated?!1!
Â
Why is modern web development so complicated? A long yet hasty explanation: Part 1!
Undefined is not a function
Â
Run tasks against folders and dump output mixed within source files.
Â
Gulp/Grunt
Â
Entry point files that include assets that include assets, that include assets, that include assets etc. Bundles are generated from this chain of dependencies.
Â
Webpack
import $ from 'jquery';
import 'bootstrap/js/dist/carousel';
// Module dependencies
import 'protons';
// Module template
import './_carousel.twig';
// Module styles
import './_carousel.scss';
export const name = 'carousel';
export const defaults = {
interval: 3000,
};
export function enable($context, { carousel = {} }) {
// Find carousel elements on the page
const $carousel = $('.carousel', $context);
// Bail if none exist
if (!$carousel.length) {
return;
}
// Override defaults with upstream settings
const settings = { ...defaults, ...carousel };
// Initialize the carousel with (potentially) overridden settings
$carousel.carousel({
interval: settings.interval,
});
}
export default enable;
apps/drupal.js
source/design-system.js
atoms/...
molecules/...carousel.js
organisms/...
protons/index.js
bootstrap/carousel.js
jquery.js
molecules/carousel.scss
Write frontend code that depends on other assets (js, html, css, images, etc) for eventual bundling in the browser. Webpack brings sanity to managing, splitting, loading, optimizing frontend assets.
2015!
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
};
<!doctype html>
<html>
<head>
<title>Getting Started</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
import _ from 'lodash';
function component() {
const element = document.createElement('div');
// Lodash used below!
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
document.body.appendChild(component());
webpack.config.js
src/index.js
dist/index.html
./webpack.particle.js
./source/default/webpack.config.js
./apps/drupal/webpack.config.js
Overall, shared configÂ
Design System-specific config
("Where are 'atoms'?")
App-specifc overrides
("Where is the bundle output?")
("Does Drupal needs its own jQuery?")
Loaders allow transformation and processing of imported assets.
module.exports = {
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader' },
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader'},
]
}
]
}
};
webpack.config.js
./src/index.ts
import './thingy.scss';
import { IStuff } from '../types';
const doStuff = (stuff: IStuff): string[] =>
stuff.items.map(item => `Do this: ${item}`);
body {
background: red;
}
./src/thingy.scss
Local host for static files. "Hot reloads" assets from Webpack without the need to write assets to disk. Shows and refreshes Pattern Lab HTML output while we work.
./apps/node-pl/webpack.config.js
Transforms any version of JavaScript into another version of JavaScript. Babel lets us use up to Stage 3 JavaScript proposals today while ensuring compiled JavaScript is supported by our target browsers.
./babel.config.env
Writing raw CSS sucks. Two flavors of styling:
Â
Transform CSS with JavaScript.
Â
./webpack.particle.js
Declare browsers you support, lets Babel and PostCSS figure out how your bundle must be transformed.
last 2 versions
not dead
> 1% in US
ie 11
./.browserslistrc
Ensure all CSS and JS are compiled for support by:
- the last two versions of Chrome, Safari, and Firefox
- as long as they're not dead
- and they have >1% usage in the US*
- and IE11 because we can't have nice things
Enforce SCSS/CSS code style rules.
Transforms code to code style rules. Also guarantees code to fit within a column count limit.
Â
If adhering to the opinionated rules in the prior two slides sounds like a lot of work, you're in luck: this reformats every file the project.
npm run fmt
To reformat on save within an IDE, see JetBrains and VSCode plugins.
UI interactive libraries of choice for Particle.
Q: "When should I reach for Vue/React instead of jQuery?"
A: When the pain of writing HTML in PHP to store application state in DOM outweighs the discomfort of adding a JS library.
Â
Simple JavaScript testing framework.
Â
npm run test
Share IDE settings across teams via a config file.Â
Â
# Unix-style newlines with a newline ending every file
[*]
indent_style = space
indent_size = 2
tab_width = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
[composer.{json,lock}]
indent_size = 4
Automate the creation of new source files easily.
Â
npm run new
The core of any node project. Holds all packages, scripts, and meta about a project.
scripts: {
"lint": "eslint --ext .js ./"
}
Do frontend work according to Atomic Design principles in a fast and iterative way. Augmented by Webpack Dev Server for rapid reloads and recompiling.
Â
A Drupal theme pre-wired to consume:
# Define Particle theme's library CSS and JS assets along
core:
css:
theme:
../../dist/app-drupal/assets/app.styles.css:
preprocess: true
js:
../../dist/app-drupal/assets/app.js:
preprocess: true
# see all in Drupal's `core/core.libraries.yml`
dependencies:
- particle/jquery
- core/drupal
- core/drupalSettings
# Create custom jQuery libraries
# that'll override the Drupal core jQuery libraries
# See `libraries-override` in particle.info.yml
jquery:
js:
../../dist/app-drupal/assets/drupal-jquery.js:
{ minified: true, weight: -20 }
./apps/drupal/particle.libraries.yml
# ...
component-libraries:
protons:
paths: []
atoms:
paths:
- ../../dist/app-drupal/assets/atomic/_patterns/01-atoms
molecules:
paths:
- ../../dist/app-drupal/assets/atomic/_patterns/02-molecules
organisms:
paths:
- ../../dist/app-drupal/assets/atomic/_patterns/03-organisms
templates:
paths: []
pages:
paths: []
./apps/drupal/particle.info.yml
Integrate Twig to Drupal
Make a "presenter" file at a hook that uses Drupal as the "model" to provide data to pure twig components
{% set article_card = {
card_border: 'none',
card_title: label,
card_text: content.body,
button: {
button_element: 'a',
button_color: 'secondary',
button_text: 'View details »'|t,
button_link: url,
}
} %}
{% Feel free to use Drupal attributes() here %}
{% include '@molecules/card/_card.twig' with article_card %}
./apps/drupal/templates/content/node--article--teaser.html.twig