├── .eleventy.js
├── .gitignore
├── README.md
├── netlify.toml
├── package-lock.json
├── package.json
├── plugins
└── sass
│ ├── index.js
│ └── manifest.yml
└── src
├── site
├── _includes
│ ├── css
│ │ └── main.scss
│ ├── js
│ │ └── main.js
│ └── layouts
│ │ └── base.njk
├── content
│ ├── 01-process-html.md
│ ├── 02-process-css.md
│ ├── 03-process.js.md
│ ├── 04-optimize-images.md
│ ├── 05-unit-tests.md
│ ├── 06-end-to-end.md
│ ├── 07-a11y-tests.md
│ ├── 08-visual-regression.md
│ ├── 09-perf-budget.md
│ ├── 10-sitemap.md
│ └── 11-notify.md
├── css
│ └── .gitignore
├── images
│ └── css-tricks.svg
└── index.njk
└── utils
├── minify-html.js
└── minify-js.js
/.eleventy.js:
--------------------------------------------------------------------------------
1 | const util = require("util");
2 |
3 | module.exports = function(eleventyConfig) {
4 | // a debug utility
5 | eleventyConfig.addFilter("dump", obj => {
6 | return util.inspect(obj);
7 | });
8 |
9 | // alias
10 | eleventyConfig.addLayoutAlias("default", "layouts/base.njk");
11 |
12 | // compress and combine js files
13 | eleventyConfig.addFilter("jsmin", require("./src/utils/minify-js.js"));
14 |
15 | // minify the html output when running in prod
16 | if (process.env.NODE_ENV == "production") {
17 | eleventyConfig.addTransform(
18 | "htmlmin",
19 | require("./src/utils/minify-html.js")
20 | );
21 | }
22 |
23 | // Collections
24 | eleventyConfig.addCollection("processes", function(collection) {
25 | return collection.getFilteredByGlob("./src/site/content/*.md");
26 | });
27 |
28 | // Passthrough
29 | // eleventyConfig.addPassthroughCopy("./src/site/fonts");
30 | eleventyConfig.addPassthroughCopy("./src/site/images");
31 | eleventyConfig.addPassthroughCopy("./src/site/css");
32 |
33 | return {
34 | dir: {
35 | input: "src/site",
36 | inludes: "_includes",
37 | output: "dist"
38 | },
39 | passthroughFileCopy: true,
40 | templateFormats: ["njk", "md"],
41 | htmlTemplateEngine: "njk",
42 | markdownTemplateEngine: "njk"
43 | };
44 | };
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependecies installed by npm
2 | /node_modules
3 |
4 | # build artefacts
5 | /dist
6 | /src/site/css/*.css
7 |
8 | # secrets
9 | .env
10 |
11 | # macOS related files
12 | .DS_Store
13 | .AppleDouble
14 | .LSOverride
15 |
16 | # Local Netlify folder
17 | .netlify
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Just an idea...
2 |
3 | This is just the start of a little microsite idea I wanna do in 2020.
4 |
5 | I cloned this intial project from Phil's [ElevenTail](https://eleventail.netlify.com/about/) to give me a starter kit.
6 |
7 |
8 | ## Prerequisites
9 |
10 | - [Node and NPM](https://nodejs.org/)
11 | - [Netlify CLI](https://www.npmjs.com/package/netlify-cli)
12 |
13 |
14 | ## Running locally
15 |
16 | ```bash
17 |
18 | # install Netlify CLI globally
19 | npm install netlify-cli -g
20 |
21 | # install the project dependencies
22 | npm install
23 |
24 | # run the build and server locally
25 | netlify dev
26 | ```
27 |
28 |
29 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "npm run build"
3 | publish = "dist"
4 |
5 | [context.production]
6 | environment = { NODE_VERSION = "10.15.3", NODE_ENV = "production" }
7 |
8 | [dev]
9 | command = "npm run start"
10 | publish = "dist"
11 | port = 3000
12 | targetPort = 8181
13 | NODE_ENV = "development"
14 |
15 | # Using the `.toml` version of this config file as plugins don't seem to work with the .yml style.
16 | [[plugins]]
17 | package = "/plugins/sass"
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "BuildProcess",
3 | "version": "1.0.0",
4 | "description": "Site about Build Processes",
5 | "author": "Chris Coyier",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/CSS-Tricks/build-process"
10 | },
11 | "scripts": {
12 | "build": "eleventy",
13 | "start": "netlify dev"
14 | },
15 | "dependencies": {
16 | "@11ty/eleventy": "^0.10.0",
17 | "html-minifier": "^4.0.0",
18 | "node-sass": "^4.13.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/plugins/sass/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | onPreBuild: async ({ utils: { run } }) => {
3 | await run.command(
4 | "node-sass src/site/_includes/css/main.scss src/site/css/main.css"
5 | );
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/plugins/sass/manifest.yml:
--------------------------------------------------------------------------------
1 | name: sass
2 |
--------------------------------------------------------------------------------
/src/site/_includes/css/main.scss:
--------------------------------------------------------------------------------
1 | $mobile: "(max-width: 600px)";
2 | $yellow: #fff72c;
3 |
4 | * {
5 | margin: 0;
6 | padding: 0;
7 | box-sizing: border-box;
8 | }
9 |
10 | html {
11 | --yellow: #fff72c;
12 |
13 | font: 1.2rem/1.3 "PT Serif", serif;
14 | font-weight: bolder;
15 | background: #1b1b1b;
16 | color: white;
17 | }
18 | body {
19 | padding: 2rem;
20 | max-width: 650px;
21 | margin: 0 auto;
22 | @media #{$mobile} {
23 | padding: 1rem;
24 | }
25 | }
26 |
27 | h1,
28 | h2,
29 | h3,
30 | h4,
31 | h5,
32 | h6 {
33 | font-family: "Montserrat", sans-serif;
34 | margin: 0 0 1rem 0;
35 | }
36 | h1 {
37 | font-weight: 700;
38 | letter-spacing: 0.02rem;
39 | font-size: calc(3.9rem + 2vmin);
40 | line-height: 0.9;
41 | margin: 0 0 3rem 0;
42 | }
43 | h1,
44 | h2 {
45 | color: $yellow;
46 | }
47 | h2 {
48 | font-size: 1.9rem;
49 | }
50 | p {
51 | margin: 0 0 1rem 0;
52 | }
53 | a {
54 | color: #f79a44;
55 | &:hover {
56 | color: #ffc793;
57 | }
58 | }
59 | ul {
60 | margin: 0 0 1rem 0;
61 | }
62 |
63 | .button {
64 | background: white;
65 | color: black;
66 | text-decoration: none;
67 | border-radius: 4px;
68 | padding: 0.2rem 1rem;
69 | }
70 | .repo-button {
71 | position: fixed;
72 | top: 5px;
73 | right: 5px;
74 | }
75 |
76 | .presented-by {
77 | margin: 0 0 2rem 0;
78 | }
79 |
80 | .site-header {
81 | h1 {
82 | span {
83 | font-size: 1rem;
84 | display: block;
85 | font-family: "PT Serif", serif;
86 | font-style: italic;
87 | color: white;
88 | &:nth-of-type(2) {
89 | margin-top: 0.35rem;
90 | text-indent: 11rem;
91 | @media #{$mobile} {
92 | text-indent: 8.5rem;
93 | }
94 | }
95 | }
96 | }
97 | }
98 | .intro-p {
99 | font-size: 1.5rem;
100 | margin: 0 0 3rem 0;
101 | @media #{$mobile} {
102 | font-size: 1.2rem;
103 | }
104 | }
105 |
106 | main {
107 | counter-reset: my-awesome-counter;
108 | .process {
109 | counter-increment: my-awesome-counter;
110 | display: grid;
111 | grid-template-columns: 100px 1fr;
112 | grid-gap: 2rem;
113 | margin: 0 0 4rem 0;
114 | &::before {
115 | content: counter(my-awesome-counter);
116 | display: block;
117 | border: 5px solid $yellow;
118 | border-radius: 50%;
119 | height: 100px;
120 | width: 100px;
121 | line-height: 90px;
122 | text-align: center;
123 | font-family: "Montserrat", sans-serif;
124 | font-size: 3rem;
125 | }
126 | @media #{$mobile} {
127 | display: block;
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/site/_includes/js/main.js:
--------------------------------------------------------------------------------
1 | console.log("hi");
2 |
--------------------------------------------------------------------------------
/src/site/_includes/layouts/base.njk:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{ title }}
10 |
11 |
12 |
13 |
14 | {{ content | safe }}
15 |
16 | {% set js %}
17 | {% include "js/main.js" %}
18 | {% endset %}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/site/content/01-process-html.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Process HTML
3 | ---
4 |
5 | It's likely you'll need some kind of HTML processing to turn templates, layouts, partials, and data into full HTML documents you can use.
6 |
7 | ### Principles
8 |
9 | - Commit only authored files to the repo
10 | - Minify production code
11 |
12 | ### Relevant Tools
13 |
14 | - With [Static Site Generators](https://serverless.css-tricks.com/services/ssgs) like [Eleventy](https://www.11ty.dev/), [Jekyll](https://jekyllrb.com/), and [Hugo](https://gohugo.io/) you handle this rather directly.
15 | - With JavaScript Framework Site Generators like [Gatsby](https://www.gatsbyjs.org/), [Next](https://nextjs.org/), [Nuxt](https://nuxtjs.org/), [VuePress](https://vuepress.vuejs.org/), and [Gridsome](https://gridsome.org/), the HTML is created as part of piecing together components.
16 |
--------------------------------------------------------------------------------
/src/site/content/02-process-css.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Process CSS
3 | ---
4 |
5 | It's likely you'll use some kind of CSS processing on a site.
6 |
7 | This site will assume a Sass setup, but it could be all PostCSS, or Stylus and Autoprefixer, Tailwind and PurgeCSS and cssnano, etc.
8 |
9 | ### Principles
10 |
11 | - Lint & Prettify authored files
12 | - Commit only authored files to repo
13 | - Concatenate & minify production code
14 | - Create sourcemaps
15 |
16 | ### Relevant Tools
17 |
18 | - Linting: [Stylelint](https://stylelint.io/)
19 | - Code Formatting: [Prettier](https://prettier.io/)
20 | - Preprocessors: [Sass](https://sass-lang.com/), [Less](http://lesscss.org/), and [Stylus](http://stylus-lang.com/).
21 | - Preprocessors meant to run last like [PostCSS](https://github.com/postcss/postcss)/[Autoprefixer](https://github.com/postcss/autoprefixer)
22 | - Minifiers: [cssnano](https://cssnano.co/), [clean-css](https://www.npmjs.com/package/clean-css), [uglifycss](https://www.npmjs.com/package/uglifycss), [csso](https://github.com/css/csso), or [node-minify](https://www.npmjs.com/package/node-minify).
23 | - [Unused CSS](https://css-tricks.com/how-do-you-remove-unused-css-from-a-site/) removers: [PurgeCSS](https://purgecss.com/), [PurifyCSS](https://github.com/purifycss/purifycss)
24 |
--------------------------------------------------------------------------------
/src/site/content/03-process.js.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Process JavaScript
3 | ---
4 |
5 | You may want to preprocess your JavaScript, allowing for use of modern features that may not be supported in as many browsers as you'd like to support. But you may also want to split up your authored JavaScript for readability.
6 |
7 | ### Principals
8 |
9 | - Only commit authored files to repo
10 | - Concatenate & minify production code
11 | - Create sourcemaps
12 | - Code splitting (only load what is needed at the time)
13 | - Tree shaking (remove unused code)
14 |
15 | ### Relevant Tools
16 |
17 | - Linting: [ESLint](https://eslint.org/)
18 | - Code Formatting: [Prettier](https://prettier.io/)
19 | - Preprocessor: [Babel](https://babeljs.io/)
20 | - Bundlers like [Rollup](https://github.com/rollup/rollup), [Parcel](https://parceljs.org/), and [webpack](https://webpack.js.org/).
21 | - Post-install [Snowpack](https://www.snowpack.dev/).
22 |
--------------------------------------------------------------------------------
/src/site/content/04-optimize-images.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Optimize Images
3 | ---
4 |
5 | Images are often the heaviest assets on any website, and are notoriously served under optimized, despite the fact that optimizing images isn't particularly difficult. Beyond optimization, serving the correct size and format image for the circumstance can go a long way.
6 |
7 | ### Principals
8 |
9 | - Keep the highest quality images around (but not in repo itself)
10 | - Optimize every single production image
11 | - Use responsive image syntax in the HTML
12 | - Lazy loading
13 | - Serve the best image formats that are supported (e.g. create and serve `.webp` when possible)
14 | - Use muted, autoplaying, looping `` instead of GIFs
15 |
16 | ### Relevant Tools
17 |
18 | - Optimizing raster images: [sharp](https://github.com/lovell/sharp) or [imagemin](https://github.com/imagemin/imagemin)
19 | - Optimizing SVG images: [svgo](https://github.com/svg/svgo) for .svg
20 | - APIs: [Imgix](https://docs.imgix.com/apis/url) [ImageOptim](https://imageoptim.com/api)
21 | - Image hosting + API: [Cloudinary](https://cloudinary.com/)
22 |
--------------------------------------------------------------------------------
/src/site/content/05-unit-tests.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Run Unit Tests
3 | ---
4 |
5 | Make sure your JavaScript is doing what you wrote it to do, by writing unit tests and making sure those tests pass.
6 |
7 | ### Principals
8 |
9 | - Run your unit tests on every commit
10 | - Don't deploy Pull/Merge requests if the tests fail
11 | - Notifications for failures
12 |
13 | ### Relevant Tools
14 |
15 | - Testing frameworks: [Jest](https://jestjs.io/), [Mocha](https://mochajs.org/), [Karma](https://karma-runner.github.io/2.0/index.html), [AVA](https://github.com/avajs/ava), [Jasmine](https://jasmine.github.io/), [Tape](https://jasmine.github.io/)
16 | - Assertion libraries: [Chai](https://www.chaijs.com/)
17 |
--------------------------------------------------------------------------------
/src/site/content/06-end-to-end.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Run End-to-End Tests
3 | ---
4 |
5 | Make sure your website is doing all the important things it should be doing. End-to-end tests are great for testing whole usage flows like visiting a URL, clicking a button, and making sure a certain modal is open with the correct text in it. Or going through a sign up process.
6 |
7 | ### Principals
8 |
9 | - Run your end-to-end tests on every commit
10 | - Notifications for failures
11 |
12 | ### Relevant Tools
13 |
14 | - Testing frameworks: [Cypress](https://www.cypress.io/), [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer), [WebdriverIO](https://webdriver.io/), [TestCafe](https://github.com/DevExpress/testcafe), [Nightwatch.js](https://nightwatchjs.org/)
15 | - Browser automation: [Puppeteer](https://github.com/puppeteer/puppeteer), [Selenium](https://selenium.dev/), [Playwright](https://github.com/microsoft/playwright), [SlimerJS](https://slimerjs.org/)
16 |
--------------------------------------------------------------------------------
/src/site/content/07-a11y-tests.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Run Accessibility Tests
3 | ---
4 |
5 | You should prevent yourself from shipping any easily preventable and detectable accessibility problems by running automated accessibility testing tools.
6 |
7 | ### Principals
8 |
9 | - Run your accessibility tests on every commit
10 | - Notifications for failures
11 |
12 | ### Relevant Tools
13 |
14 | - [Accessibility Testing Tools](https://css-tricks.com/accessibility-testing-tools/): [Axe](https://github.com/dequelabs/axe-cli), [pA11y](https://github.com/pa11y/pa11y), [accessibilityjs](https://github.com/github/accessibilityjs), [Tenon.io](https://tenon.io/getcode.php)
15 |
--------------------------------------------------------------------------------
/src/site/content/08-visual-regression.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Run Visual Regression Tests
3 | ---
4 |
5 | Prevent yourself from making unwanted visual changes to a site by comparing screenshots and ensuring that the changes you made are the changes you want.
6 |
7 | ### Principals
8 |
9 | - Run your visual regression tests on pull requests coming into Master.
10 | - Notifications for failures
11 |
12 | ### Relevant Tools
13 |
14 | - Visual Regression Testing Services: [Percy](https://percy.io/), [Chromatic](https://www.chromaticqa.com/), [diff.io](https://diff.io/), [Axcept](https://axcept.io/), [Applitools](https://applitools.com/)
15 | - Visual Regression Frameworks: [BackstopJS](https://github.com/garris/BackstopJS), [Wraith](https://github.com/BBC-News/wraith) (Pair with [Spectre](https://github.com/wearefriday/spectre))
16 |
--------------------------------------------------------------------------------
/src/site/content/09-perf-budget.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Test Against Performance Budget
3 | ---
4 |
5 | Make sure your website doesn't regress in performance by testing all changes against your established performance budget.
6 |
7 | ### Principals
8 |
9 | - Run your performance tests on every commit
10 | - Notifications for exceeding budget
11 |
12 | ### Relevant Tools
13 |
14 | - Hosted services: [SpeedCurve](https://speedcurve.com/) ([CLI](https://github.com/SpeedCurve-Metrics/speedcurve-cli)) and [Calibre](https://calibreapp.com/) ([CLI](https://calibreapp.com/cli))
15 | - Frameworks: [Build Tracker](https://buildtracker.dev/)
16 |
--------------------------------------------------------------------------------
/src/site/content/10-sitemap.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Build a sitemap
3 | ---
4 |
5 | If your site is large/complex (over 500 pages), search engines like Google [suggest](https://support.google.com/webmasters/answer/156184?hl=en) a sitemap so they can more intelligently crawl your site.
6 |
7 | ### Principals
8 |
9 | - Produce sitemap files only for production
10 | - Check for broken links
11 |
12 | ### Relevant Tools
13 |
14 | - Something that makes site maps
15 | - [broken-link-checker](https://www.npmjs.com/package/broken-link-checker)
16 |
--------------------------------------------------------------------------------
/src/site/content/11-notify.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Send Notifications
3 | ---
4 |
5 | ### Principals
6 |
7 | - When important things happen in a build process, notify the right people.
8 |
9 | ### Relevant Tools
10 |
11 | - Slack, Discord
12 | - Email sending APIs like Sparkpost, Mailgun, etc.
13 | - SMS sending APIs like Twilio
14 |
--------------------------------------------------------------------------------
/src/site/css/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory, except this file
2 | # It's here because the folder needs to exist for Netlify
3 | !.gitignore
--------------------------------------------------------------------------------
/src/site/images/css-tricks.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/site/index.njk:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
18 |
19 |
20 | {%- for process in collections.processes -%}
21 |
22 |
23 |
24 | {{ process.data.title }}
25 |
26 | {{ process.templateContent | safe }}
27 |
28 |
29 | {%- endfor -%}
30 |
--------------------------------------------------------------------------------
/src/utils/minify-html.js:
--------------------------------------------------------------------------------
1 | const htmlmin = require("html-minifier");
2 |
3 | module.exports = function(content, outputPath) {
4 | if (outputPath.endsWith(".html")) {
5 | let minified = htmlmin.minify(content, {
6 | useShortDoctype: true,
7 | removeComments: true,
8 | collapseWhitespace: true
9 | });
10 | return minified;
11 | }
12 | return content;
13 | };
14 |
--------------------------------------------------------------------------------
/src/utils/minify-js.js:
--------------------------------------------------------------------------------
1 | const UglifyJS = require("uglify-js");
2 |
3 | module.exports = function(code) {
4 | let minified = UglifyJS.minify(code);
5 | if (minified.error) {
6 | console.log("UglifyJS error: ", minified.error);
7 | return code;
8 | }
9 | return minified.code;
10 | };
11 |
--------------------------------------------------------------------------------