{"id":312530,"date":"2020-06-09T08:10:02","date_gmt":"2020-06-09T15:10:02","guid":{"rendered":"https:\/\/css-tricks.com\/?p=312530"},"modified":"2020-06-09T08:10:05","modified_gmt":"2020-06-09T15:10:05","slug":"making-my-netlify-build-run-sass","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/making-my-netlify-build-run-sass\/","title":{"rendered":"Making My Netlify Build Run Sass"},"content":{"rendered":"\n

Let’s say you wanted to build a site with Eleventy<\/a> as the generator. Popular choice these days! Eleventy doesn’t have some particularly blessed way of preprocessing your CSS, if that’s something you want to do. There are a variety of ways to do it and perhaps that freedom is part of the spirit of Eleventy.<\/p>\n\n\n\n

I’ve seen people set up Gulp for this, which is cool, I still use and like Gulp for some stuff. I’ve seen someone use templating<\/a> to return preprocessed CSS<\/a>, which seems weird, but hey, whatever works. I’ve even seen someone extend the Eleventy config<\/a> itself to run the processing.<\/p>\n\n\n\n\n\n\n\n

So far, the thing that has made the most sense to me is to use npm scripts<\/a> do the Sass processing. Do the CSS first, then the HTML, with npm-run-all<\/a>. So, you’d set up something like this in your package.json<\/code>:<\/p>\n\n\n\n

  \"scripts\": {\n    \"build\": \"npm-run-all build:css build:html\",\n    \"build:css\": \"node-sass src\/site\/_includes\/css\/main.scss > src\/site\/css\/main.css\",\n    \"build:html\": \"eleventy\",\n    \"watch\": \"npm-run-all --parallel watch:css watch:html\",\n    \"watch:css\": \"node-sass --watch src\/site\/_includes\/css\/main.scss > src\/site\/css\/main.css\",\n    \"watch:html\": \"eleventy --serve --port=8181\",\n    \"start\": \"npm run watch\"\n  },<\/code><\/pre>\n\n\n\n

I think that’s fairly nice. Since Eleventy doesn’t have a blessed CSS processing route anyway, it feels OK to have it de-coupled from Eleventy processing.<\/p>\n\n\n\n

But I see Netlify has come along nicely<\/a> with their build plugins. As Sarah put it:<\/p>\n\n\n\n

What the Build Plugin does is give you access to key points in time during that process, for instance, onPreBuild<\/code><\/strong>, onPostBuild<\/code><\/strong>, onSuccess<\/code><\/strong>, and so forth. You can execute some logic at those specific points in time<\/p><\/blockquote>\n\n\n\n

There is something really intuitive and nice<\/em> about that structure. A lot of build plugins are created by the community or Netlify themselves. You just click them on via the UI or reference them in your config. But Sass isn’t a build-in project (as I write), which I would assume is because people are a pretty opinionated about what\/where\/how their CSS is processed that it makes sense to just let people do it themselves. So let’s do that.<\/p>\n\n\n\n

In our project, we’d create a directory for our plugins, and then a folder for this particular plugin we want to write:<\/p>\n\n\n\n

project-root\/\n  src\/\n  whatever\/\n  plugins\/\n    sass\/\n      index.js\n      manifest.yml<\/code><\/pre>\n\n\n\n

That index.js<\/code> file is where we write our code, and we’ll specifically want to use the onPreBuild<\/code> hook here, because we’d want our Sass to be done preprocessing before<\/em> the build process runs Eleventy and Eleventy moves things around.<\/p>\n\n\n\n

module.exports = {\n  onPreBuild: async ({ utils: { run } }) => {\n    await run.command(\n      \"node-sass src\/site\/_includes\/css\/main.scss src\/site\/css\/main.css\"\n    );\n  },\n};<\/code><\/pre>\n\n\n\n

Here’s a looksie into all the relevant files together:<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

Now, if I netlify build<\/code> from the command line, it will run the same build process that Netlify itself does, and it will hook into my plugin and run it!<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

One little thing I noticed is that I was trying to have my config be the (newer) netlify.yml<\/code> format, but the plugins didn’t work, and I had to re-do the config as netlify.toml<\/code>. <\/p>\n\n\n\n

So we de-coupled ourselves from Eleventy with this particular processing, and coupled ourselves to Netlify. Just something to be aware of. I’m down with that as this way of configuring a build is so nice and I see so much potential in it. <\/p>\n\n\n\n

I prefer the more explicit and broken up configuration of this style. Just look at how much cleaner the package.json<\/code> gets:<\/p>\n\n\n\n

\"Removed<\/figure>\n\n\n

I still have this idea…<\/h3>\n\n\n

…of building a site that is a dog-fooded example of all the stuff you could\/should do during a build process. I’ve started the site here<\/a>, (and repo<\/a>), but it’s not doing too much yet. I think it would be cool to wire up everything on that list (and more?) via Build Plugins. <\/p>\n\n\n\n

If you wanna contribute, feel free to let me know. Maybe email me or open an issue to talk about what you’d want to do. You’re free to do a Pull Request too, but PRs without any prior communication are a little tricky sometimes as it’s harder to ensure our visions are aligned before you put in a bunch of effort.<\/p>\n","protected":false},"excerpt":{"rendered":"

Let’s say you wanted to build a site with Eleventy as the generator. Popular choice these days! Eleventy doesn’t have some particularly blessed way of preprocessing your CSS, if that’s something you want to do. There are a variety of ways to do it and perhaps that freedom is part of the spirit of Eleventy. […]<\/p>\n","protected":false},"author":3,"featured_media":312539,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[579,1401,1415,476],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/06\/netlify-build-plugins-sass.png?fit=1200%2C600&ssl=1","jetpack-related-posts":[{"id":303133,"url":"https:\/\/css-tricks.com\/possibly-the-easiest-way-to-run-an-ssg\/","url_meta":{"origin":312530,"position":0},"title":"Possibly The Easiest Way to Run an SSG","date":"February 4, 2020","format":false,"excerpt":"\"Static Site Generator,\" that is. We'll get to that in a second. Netlify is a sponsor of this site (thank you very much), and I see Zach Leatherman has gone to work over there now. Very cool. Zach is the creator of Eleventy, an SSG for Node. One thing of\u2026","rel":"","context":"In "Sponsored"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":298530,"url":"https:\/\/css-tricks.com\/the-future-is-bright-because-the-future-is-static\/","url_meta":{"origin":312530,"position":1},"title":"The future is bright, because the future is static","date":"November 20, 2019","format":false,"excerpt":"I've been doing this web thing for money for 10 years this year and although I haven\u2019t been around as long as some folks, I feel like I've seen a few cycles come and go now, so let's say that hot new things are often cynically viewed, initially. This milestone\u2026","rel":"","context":"In "2019 End-of-Year Thoughts"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":326089,"url":"https:\/\/css-tricks.com\/cloudinary-fetch-with-eleventy-respecting-local-development\/","url_meta":{"origin":312530,"position":2},"title":"Cloudinary Fetch with Eleventy (Respecting Local Development)","date":"December 4, 2020","format":false,"excerpt":"This is about a wildly specific combination of technologies \u2014 Eleventy, the static site generator, with pages with images on them that you ultimately want hosted by Cloudinary \u2014 but I just wanna document it as it sounds like a decent amount of people run into this situation. The deal:\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/11\/eleventy-cloudinary.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":301707,"url":"https:\/\/css-tricks.com\/eleventy-love\/","url_meta":{"origin":312530,"position":3},"title":"Eleventy Love","date":"January 17, 2020","format":false,"excerpt":"Been seeing a lot of Eleventy action lately. It's a smaller player in the world of static site generators, but I think it's got huge potential because of how simple it is, yet does about anything you'd need it to do. It's Just JavaScript\u2122. Jason Lengstorf and Zach Leatherman did\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/01\/11ty-balloon.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":318724,"url":"https:\/\/css-tricks.com\/a-community-driven-site-with-eleventy-building-the-site\/","url_meta":{"origin":312530,"position":4},"title":"A Community-Driven Site with Eleventy: Building the Site","date":"August 20, 2020","format":false,"excerpt":"In the last article, we learned what goes into planning for a community-driven site. We saw just how many considerations are needed to start accepting user submissions, using what I learned from my experience building Style Stage as an example. Now that we\u2019ve covered planning, let\u2019s get to some code!\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/08\/weekly-pet-battle.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":318499,"url":"https:\/\/css-tricks.com\/building-a-community-driven-site-with-eleventy-preparing-for-contributions\/","url_meta":{"origin":312530,"position":5},"title":"A Community-Driven Site with Eleventy: Preparing for Contributions","date":"August 19, 2020","format":false,"excerpt":"I've recently found myself reaching for Eleventy (aka 11ty) above all other tools when I want to develop a website. It's hard to beat a static site generator that provides advanced templating opportunities while otherwise getting out of your way and allowing you to just create. One of those sites\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/08\/11ty-stylestage.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]}],"featured_media_src_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/06\/netlify-build-plugins-sass.png?fit=1024%2C512&ssl=1","_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/312530"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=312530"}],"version-history":[{"count":2,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/312530\/revisions"}],"predecessor-version":[{"id":312540,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/312530\/revisions\/312540"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/312539"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=312530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=312530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=312530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}