Skip to content

Commit e5fa2ed

Browse files
committed
Implement hashing for CSS filenames
Based on @ashleygwilliams work
1 parent 04e0af1 commit e5fa2ed

File tree

10 files changed

+1263
-113
lines changed

10 files changed

+1263
-113
lines changed

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/target/
22
**/*.rs.bk
33
/node_modules
4-
/static/styles/app.css
5-
/static/styles/fonts.css
64
/static/styles/*.map
75
.sass-cache
86
localhost*
9-
/static/styles/vendor.css
7+
/static/styles/vendor_*.css
8+
/static/styles/app_*.css
9+
/static/styles/fonts_*.css

Cargo.lock

Lines changed: 135 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ toml = "0.4"
2121
serde_json = "1.0"
2222
rust_team_data = { git = "https://github.com/rust-lang/team" }
2323
handlebars = "1.1.0"
24+
siphasher = "0.2.3"
2425

2526
[dependencies.rocket_contrib]
2627
version = "*"

src/main.rs

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern crate serde_json;
99
extern crate rocket;
1010
extern crate rust_team_data;
1111
extern crate sass_rs;
12+
extern crate siphasher;
1213
extern crate toml;
1314

1415
extern crate rocket_contrib;
@@ -32,8 +33,10 @@ mod teams;
3233

3334
use production::User;
3435

36+
use std::collections::hash_map::DefaultHasher;
3537
use std::fs;
3638
use std::fs::File;
39+
use std::hash::Hasher;
3740
use std::io::prelude::*;
3841
use std::iter::FromIterator;
3942
use std::path::{Path, PathBuf};
@@ -44,6 +47,7 @@ use rocket::{
4447
http::Status,
4548
response::{NamedFile, Redirect},
4649
};
50+
4751
use rocket_contrib::templates::Template;
4852

4953
use sass_rs::{compile_file, Options};
@@ -52,6 +56,20 @@ use category::Category;
5256

5357
use i18n::{I18NHelper, SupportedLocale, TeamHelper};
5458

59+
lazy_static! {
60+
static ref CSS: CSSNames = {
61+
let app_css_file = compile_sass("app");
62+
let fonts_css_file = compile_sass("fonts");
63+
let vendor_css_file = concat_vendor_css(vec!["skeleton", "tachyons"]);
64+
65+
CSSNames {
66+
app: app_css_file,
67+
fonts: fonts_css_file,
68+
vendor: vendor_css_file,
69+
}
70+
};
71+
}
72+
5573
#[derive(Serialize)]
5674
struct Context<T: ::serde::Serialize> {
5775
page: String,
@@ -61,6 +79,14 @@ struct Context<T: ::serde::Serialize> {
6179
data: T,
6280
lang: String,
6381
baseurl: String,
82+
css: CSSNames,
83+
}
84+
85+
#[derive(Clone, Serialize)]
86+
struct CSSNames {
87+
app: String,
88+
fonts: String,
89+
vendor: String,
6490
}
6591

6692
static LAYOUT: &str = "components/layout";
@@ -209,6 +235,7 @@ fn not_found() -> Template {
209235
data: (),
210236
lang: ENGLISH.to_string(),
211237
baseurl: String::new(),
238+
css: CSS.clone(),
212239
};
213240
Template::render(page, &context)
214241
}
@@ -218,26 +245,43 @@ fn catch_error() -> Template {
218245
not_found()
219246
}
220247

221-
fn compile_sass(filename: &str) {
248+
fn hash_css(css: &str) -> String {
249+
let mut hasher = DefaultHasher::new();
250+
hasher.write(css.as_bytes());
251+
hasher.finish().to_string()
252+
}
253+
254+
fn compile_sass(filename: &str) -> String {
222255
let scss_file = format!("./src/styles/{}.scss", filename);
223-
let css_file = format!("./static/styles/{}.css", filename);
224256

225257
let css = compile_file(&scss_file, Options::default())
226258
.expect(&format!("couldn't compile sass: {}", &scss_file));
259+
260+
let css_sha = format!("{}_{}", filename, hash_css(&css));
261+
let css_file = format!("./static/styles/{}.css", css_sha);
262+
227263
let mut file =
228264
File::create(&css_file).expect(&format!("couldn't make css file: {}", &css_file));
229265
file.write_all(&css.into_bytes())
230266
.expect(&format!("couldn't write css file: {}", &css_file));
267+
268+
String::from(&css_file[1..])
231269
}
232270

233-
fn concat_vendor_css(files: Vec<&str>) {
271+
fn concat_vendor_css(files: Vec<&str>) -> String {
234272
let mut concatted = String::new();
235273
for filestem in files {
236274
let vendor_path = format!("./static/styles/{}.css", filestem);
237275
let contents = fs::read_to_string(vendor_path).expect("couldn't read vendor css");
238276
concatted.push_str(&contents);
239277
}
240-
fs::write("./static/styles/vendor.css", &concatted).expect("couldn't write vendor css");
278+
279+
let css_sha = format!("vendor_{}", hash_css(&concatted));
280+
let css_path = format!("./static/styles/{}.css", &css_sha);
281+
282+
fs::write(&css_path, &concatted).expect("couldn't write vendor css");
283+
284+
String::from(&css_path[1..])
241285
}
242286

243287
fn render_index(lang: String) -> Template {
@@ -263,6 +307,7 @@ fn render_index(lang: String) -> Template {
263307
},
264308
baseurl: baseurl(&lang),
265309
lang,
310+
css: CSS.clone(),
266311
};
267312
Template::render(page, &context)
268313
}
@@ -278,6 +323,7 @@ fn render_category(category: Category, lang: String) -> Template {
278323
data: (),
279324
baseurl: baseurl(&lang),
280325
lang,
326+
css: CSS.clone(),
281327
};
282328
Template::render(page, &context)
283329
}
@@ -293,6 +339,7 @@ fn render_production(lang: String) -> Template {
293339
data: load_users_data(),
294340
baseurl: baseurl(&lang),
295341
lang,
342+
css: CSS.clone(),
296343
};
297344
Template::render(page, &context)
298345
}
@@ -310,6 +357,7 @@ fn render_governance(lang: String) -> Result<Template, Status> {
310357
data,
311358
baseurl: baseurl(&lang),
312359
lang,
360+
css: CSS.clone(),
313361
};
314362
Ok(Template::render(page, &context))
315363
}
@@ -337,6 +385,7 @@ fn render_team(
337385
data,
338386
baseurl: baseurl(&lang),
339387
lang,
388+
css: CSS.clone(),
340389
};
341390
Ok(Template::render(page, &context))
342391
}
@@ -368,15 +417,12 @@ fn render_subject(category: Category, subject: String, lang: String) -> Template
368417
data: (),
369418
baseurl: baseurl(&lang),
370419
lang,
420+
css: CSS.clone(),
371421
};
372422
Template::render(page, &context)
373423
}
374424

375425
fn main() {
376-
compile_sass("app");
377-
compile_sass("fonts");
378-
concat_vendor_css(vec!["skeleton", "tachyons"]);
379-
380426
let templating = Template::custom(|engine| {
381427
engine
382428
.handlebars

static/images/mdn-logo.svg.png

3.7 KB
Loading

0 commit comments

Comments
 (0)