Skip to content
This repository has been archived by the owner on Nov 29, 2022. It is now read-only.

Commit

Permalink
chore: hash images (#5219)
Browse files Browse the repository at this point in the history
* chore: hash images

* Apply suggestions from code review

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* Use posix separator so globby works

* Fixing precompile on Windows

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
  • Loading branch information
3 people committed Mar 15, 2021
1 parent 3fbf6b7 commit 9e4cb8a
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 54 deletions.
2 changes: 0 additions & 2 deletions cypress/integration/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ describe('electronjs.org', () => {
expect(typeHits.first()).to.contain('window-all-closed')
if (type.includes('package'))
expect(typeHits.first()).to.contain('about-window')
if (type.includes('app'))
expect(typeHits.first()).to.contain('PhotoScreenSaver')
})
})
})
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"eslint": "^7.21.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"globby": "^11.0.2",
"handlebars-loader": "^1.7.1",
"husky": "^4.3.8",
"lint-staged": "^10.5.4",
Expand Down
75 changes: 70 additions & 5 deletions script/precompile-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ const crypto = require('crypto')
const path = require('path')
const fs = require('fs-extra')
const sass = require('node-sass')
const globby = require('globby')

function dir(...parts) {
return path.join(__dirname, '..', ...parts)
return path.posix.join(__dirname, '..', ...parts)
}

const env = process.env.NODE_ENV
Expand All @@ -16,20 +17,35 @@ const PATHS = {

cssEntry: dir('public', 'styles', 'index.scss'),
cssDestinationDir: dir('precompiled', 'styles'),

imagesDir: dir('public', 'images'),
imageDestinationDir: dir('precompiled', 'images'),

appImgDir: dir('node_modules', 'electron-apps', 'apps'),
appImgDestinationDir: dir('precompiled', 'images', 'app-img'),
}

async function precompileAssets() {
try {
console.log('Creating directories...')
await fs.ensureDir(PATHS.styles)
await fs.ensureDir(PATHS.imageDestinationDir)
console.log('Precompiling CSS...')
await precompileCss()
console.log('Hashing images...')
await precompileImages()
} catch (err) {
console.error(err)
process.exit(1)
}
}

function calculateHash(content) {
const hash = crypto.createHash('md4').update(content).digest('hex')

return hash
}

function precompileCss() {
return new Promise((resolve, reject) => {
sass.render(
Expand All @@ -43,10 +59,7 @@ function precompileCss() {
return reject(err)
}

const cssHash = crypto
.createHash('md4')
.update(result.css)
.digest('hex')
const cssHash = calculateHash(result.css)
const cssFileName =
env === 'production' ? `index.${cssHash}.min.css` : 'index.css'
const cssFile = path.resolve(PATHS.cssDestinationDir, cssFileName)
Expand All @@ -62,6 +75,58 @@ function precompileCss() {
})
}

async function precompileImages() {
// globby patterns only accept `/` (https://github.com/sindresorhus/globby#api)
const websiteImages = await globby(`${PATHS.imagesDir}/**/*`, {
onlyFiles: true,
})

const appImages = await globby(`${PATHS.appImgDir}/**/*.png`, {
onlyFiles: true,
})

const images = [...appImages, ...websiteImages]

const manifest = {}

for (const image of images) {
const basename = path.basename(image)
const extension = path.extname(image)
const filename = basename.replace(extension, '')
const content = await fs.readFile(image)
// We could optimize the images here and save a few bytes
const hash = calculateHash(content)

// Can't use `path.resolve` here because the resulting path on Windows
// will make the calculation of `value` later on even more convoluted
const imageDestination = image
.replace(PATHS.imagesDir, PATHS.imageDestinationDir)
.replace(PATHS.appImgDir, PATHS.appImgDestinationDir)
.replace(basename, `${filename}.${hash}${extension}`)

const finalDir = path.dirname(imageDestination)

await fs.ensureDir(finalDir)
await fs.copyFile(image, imageDestination)

const key = image.includes(PATHS.imagesDir)
? `${image.replace(PATHS.imagesDir, '')}`
: `/app-img${image.replace(PATHS.appImgDir, '')}`

const value = `/images${imageDestination.replace(
PATHS.imageDestinationDir,
''
)}`

manifest[key] = value
}

await fs.writeFile(
path.resolve(PATHS.imageDestinationDir, 'manifest.json'),
JSON.stringify(manifest, null, 2)
)
}

if (require.main === module) {
precompileAssets().catch((err) => {
console.error(err)
Expand Down
4 changes: 0 additions & 4 deletions scripts/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ const types = [
name: 'package',
path: '/community',
},
{
name: 'app',
path: '/apps',
},
]
const typeNames = types.map((type) => type.name)

Expand Down
25 changes: 22 additions & 3 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,42 @@ if (process.env.NODE_ENV === 'production') {
'styles',
'manifest.json'
))
hbs.registerHelper('static-asset', (type, name) => {
const imagesManifest = require(path.join(
__dirname,
'precompiled',
'images',
'manifest.json'
))
hbs.registerHelper('static-asset', (type, ...parts) => {
// `parts` should be at minimum [name, function]
// but it could also be [part1, part2, part3, function ]
// if we want to link to dynamic images
const name = parts.length === 2 ? parts[0] : parts.slice(0, -1).join('')

if (type === 'js') {
return jsManifest[name] || 'unknown.name'
}
if (type === 'css') {
return cssManifest[name] || 'unknown.name'
}
if (type === 'image') {
return imagesManifest[name] || 'unknown.name'
}
return 'unknown.type'
})
} else {
hbs.registerHelper('static-asset', (type, name) => {
hbs.registerHelper('static-asset', (type, ...parts) => {
const name = parts.length === 2 ? parts[0] : parts.slice(0, -1).join('')

if (type === 'js') {
return `/scripts/${name}`
}
if (type === 'css') {
return `/styles/${name}`
}
if (type === 'image') {
return `/images${name}`
}
return 'unknown.type'
})
}
Expand Down Expand Up @@ -138,7 +157,7 @@ app.use(
})
)
app.use(express.static(path.join(__dirname, 'public'), { redirect: false }))
app.use('/app-img', express.static(appImgDir, { redirect: false }))
app.use('/images/app-img', express.static(appImgDir, { redirect: false }))
app.use(slashes(false))
app.use(langResolver)
app.use(contextBuilder)
Expand Down
2 changes: 1 addition & 1 deletion templates/app.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="app-result">
<a class="app-result-icon-link" href="/apps/{{slug}}">
<img class="app-result-icon" src="/app-img/{{slug}}/{{icon32}}" alt="{{slug}} icon">
<img class="app-result-icon" src="{{ static-asset 'image' '/app-img/' slug '/' icon32 }}" alt="{{slug}} icon">
</a>
<span class="search-small-text"><a href="/apps/{{slug}}">{{{name}}}</a> - {{{_highlightResult.description.value}}}</span>
</div>
2 changes: 1 addition & 1 deletion views/apps/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<div class='listed-app-logo-wrapper'>
<div class="listed-app-logo-placeholder placeholder" style="background: {{this.goodColorOnWhite}}">
</div>
<img class='listed-app-logo' data-src='/app-img/{{this.slug}}/{{this.icon64}}' alt='{{app.name}}'>
<img class='listed-app-logo' data-src="{{ static-asset 'image' '/app-img/' this.slug '/' this.icon64 }}" alt='{{app.name}}'>
</div>
<span class='listed-app-name text-gray-dark'>{{this.name}}</span>
<span class='listed-app-description text-gray-light'>{{this.description}}</span>
Expand Down
2 changes: 1 addition & 1 deletion views/apps/show.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<div class="container-xl media-fluid">
<div class="clearfix pt-md-6">
<div class="col-md-3 float-md-left pr-md-5 mb-3 mb-md-0">
<div class="CircleBadge CircleBadge--large mx-auto box-shadow-large mt-1" style="background-color: #ffffff;"><img class="CircleBadge-icon" src='/app-img/{{app.slug}}/{{app.icon128}}' alt='{{app.name}}'></div>
<div class="CircleBadge CircleBadge--large mx-auto box-shadow-large mt-1" style="background-color: #ffffff;"><img class="CircleBadge-icon" src="{{ static-asset 'image' '/app-img/' app.slug '/' app.icon128 }}" alt='{{app.name}}'></div>
</div>
<div class="col-md-9 float-md-left pl-md-5 text-center text-md-left">
<h1 class="f00-light lh-condensed mb-3">
Expand Down
12 changes: 6 additions & 6 deletions views/devtron.hbs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="devtron">
<div class="jumbotron text-center">
<div class="container">
<img class="mb-4 mb-lg-6" src="{{ site.baseurl }}/images/devtron-icon.svg" alt="Devtron icon">
<p><img src="{{ site.baseurl }}/images/devtron-logo.svg" alt="Devtron logo"></p>
<img class="mb-4 mb-lg-6" src="{{ static-asset 'image' '/devtron-icon.svg'}}" alt="Devtron icon">
<p><img src="{{ static-asset 'image' '/devtron-logo.svg'}}" alt="Devtron logo"></p>
<p class='jumbotron-lead'><span class='jumbotron-lead-muted'>An Electron DevTools Extension</span></p>
</div>
</div>
Expand All @@ -26,15 +26,15 @@
</div>
<div class='col-xs-12 col-md-6'>
<div class="app-frame">
<img alt="Screenshot of Devtron Require Graph" src='{{ site.baseurl }}/images/devtron-require-graph.png'>
<img alt="Screenshot of Devtron Require Graph" src="{{ static-asset 'image' '/devtron-require-graph.png'}}">
</div>
</div>
</div>

<div class='row mt-8'>
<div class='col-xs-12 col-md-6 mb-4'>
<div class="app-frame">
<img alt="Screenshot of Devtron Event Listeners" src='{{ site.baseurl }}/images/devtron-event-listeners.png'>
<img alt="Screenshot of Devtron Event Listeners" src="{{ static-asset 'image' '/devtron-event-listeners.png'}}">
</div>
</div>
<div class='col-xs-12 col-md-6 text-left'>
Expand All @@ -56,15 +56,15 @@
</div>
<div class='col-xs-12 col-md-6'>
<div class="app-frame">
<img alt="Screenshot of Devtron IPC Monitor" src='{{ site.baseurl }}/images/devtron-ipc.png'>
<img alt="Screenshot of Devtron IPC Monitor" src="{{ static-asset 'image' '/devtron-ipc.png'}}">
</div>
</div>
</div>

<div class='row mt-8'>
<div class='col-xs-12 col-md-6 mb-4'>
<div class="app-frame">
<img alt="Screenshot of Devtron Linter" src='{{ site.baseurl }}/images/devtron-linter.png'>
<img alt="Screenshot of Devtron Linter" src="{{ static-asset 'image' '/devtron-linter.png'}}">
</div>
</div>
<div class='col-xs-12 col-md-6 text-left'>
Expand Down
12 changes: 6 additions & 6 deletions views/fiddle.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<div class="container">
<img
class="mb-4 mb-lg-6 fiddle-icon"
src="{{ site.baseurl }}/images/fiddle/fiddle-icon.svg"
src="{{ static-asset 'image' '/fiddle/fiddle-icon.svg'}}"
alt="Electron Fiddle Icon"
/>
<p>
<img src="{{ site.baseurl }}/images/fiddle/fiddle-logo.svg" alt="Electron Fiddle">
<img src="{{ static-asset 'image' '/fiddle/fiddle-logo.svg'}}" alt="Electron Fiddle">
</p>
<p class="jumbotron-lead">
<span class="jumbotron-lead-muted">{{localized.landing.fiddle.lead_desc}}</span>
Expand Down Expand Up @@ -176,7 +176,7 @@
<div class="f-app-frame">
<img
alt="Screenshot of Electron Fiddle"
src="{{ site.baseurl }}/images/fiddle/explore-electron.png"
src="{{ static-asset 'image' '/fiddle/explore-electron.png'}}"
/>
</div>
</div>
Expand All @@ -187,7 +187,7 @@
<div class="f-app-frame">
<img
alt="Screenshot of Electron Fiddle Editor"
src="{{ site.baseurl }}/images/fiddle/code-with-types.png"
src="{{ static-asset 'image' '/fiddle/code-with-types.png'}}"
/>
</div>
</div>
Expand All @@ -206,7 +206,7 @@
<div class="f-app-frame">
<img
alt="Screenshot of Electron Fiddle Compile And Package Menu"
src="{{ site.baseurl }}/images/fiddle/compile-and-package.png"
src="{{ static-asset 'image' '/fiddle/compile-and-package.png'}}"
/>
</div>
</div>
Expand All @@ -217,7 +217,7 @@
<div class="f-app-frame">
<img
alt="Screenshot of Electron Fiddle Starting Point"
src="{{ site.baseurl }}/images/fiddle/easy-start.png"
src="{{ static-asset 'image' '/fiddle/easy-start.png'}}"
/>
</div>
</div>
Expand Down
20 changes: 10 additions & 10 deletions views/home.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@
{{#each apps}}
<a class="featured-app-list-item" href="{{ this.url }}" target="_blank" rel="noopener">
<picture>
<source srcset="{{ site.baseurl }}/images/featured_apps/{{ screenshot }}.webp" type="image/webp">
<source srcset="{{ site.baseurl }}/images/featured_apps/{{ screenshot }}.png" type="image/png">
<img alt="" src="{{ site.baseurl }}/images/featured_apps/{{ screenshot }}.png">
<source srcset="{{ static-asset 'image' '/featured_apps/' screenshot '.webp'}}" type="image/webp">
<source srcset="{{ static-asset 'image' '/featured_apps/' screenshot '.png'}}" type="image/png">
<img alt="" src="{{ static-asset 'image' '/featured_apps/' screenshot '.png'}}">
</picture>
<img class="icon" data-src="{{ site.baseurl }}/images/featured_apps/{{ icon }}" alt="">
<img class="icon" data-src="{{ static-asset 'image' '/featured_apps/' icon}}" alt="">
<h4>{{this.name}}</h4>
</a>
{{/each}}
Expand All @@ -75,17 +75,17 @@

<div class="d-sm-flex flex-row text-center text-small mt-6">
<div class="col-xs-12 col-sm-4">
<img class="home-illu" role="presentation" src="/images/web-tech.svg" aria-hidden="true">
<img class="home-illu" role="presentation" src="{{ static-asset 'image' '/web-tech.svg'}}" aria-hidden="true">
<h3 class="f1-light mb-2 mt-0">{{{localized.web_technologies.title}}}</h3>
<p class="f4">{{{localized.web_technologies.description}}}</p>
</div>
<div class="col-xs-12 col-sm-4">
<img class="home-illu" role="presentation" src="/images/open-source.svg" aria-hidden="true">
<img class="home-illu" role="presentation" src="{{ static-asset 'image' '/open-source.svg'}}" aria-hidden="true">
<h3 class="f1-light mb-2 mt-0">{{{localized.open_source.title}}}</h3>
<p class="f4">{{{localized.open_source.description}}}</p>
</div>
<div class="col-xs-12 col-sm-4">
<img class="home-illu" role="presentation" src="/images/cross-platform.svg" aria-hidden="true">
<img class="home-illu" role="presentation" src="{{ static-asset 'image' '/cross-platform.svg'}}" aria-hidden="true">
<h3 class="f1-light mb-2 mt-0">{{{localized.cross_platform.title}}}</h3>
<p class="f4">{{{localized.cross_platform.description}}}</p>
</div>
Expand Down Expand Up @@ -142,7 +142,7 @@
<div class='col-md-5 flex-md-self-center text-center'>
<a href="https://github.com/electron/electron-api-demos/releases">
<div class="app-frame py-4 px-6">
<img alt="Screenshot of Electron API Demos app" width="249px" height="221px" src='/images/electron-api-demos.png'>
<img alt="Screenshot of Electron API Demos app" width="249px" height="221px" src="{{ static-asset 'image' '/electron-api-demos.png'}}">
</div>
</a>
</div>
Expand All @@ -168,11 +168,11 @@
<a href="/fiddle">
<img
class="mb-4 mb-lg-6 fiddle-icon"
src="{{ site.baseurl }}/images/fiddle/fiddle-icon.svg"
src="{{ static-asset 'image' '/fiddle/fiddle-icon.svg'}}"
alt="Electron Fiddle Icon"
/>
<p>
<img src="{{ site.baseurl }}/images/fiddle/fiddle-logo.svg" alt="Electron Fiddle">
<img src="{{ static-asset 'image' '/fiddle/fiddle-logo.svg'}}" alt="Electron Fiddle">
</p>
</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion views/partials/featured_app.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<a href='/apps/{{this.slug}}' title='{{this.name}}' class='featured-app'>
<div class='featured-app-logo-wrapper'>
<img class='featured-app-logo' data-src='/app-img/{{this.slug}}/{{this.icon}}' alt='{{this.name}}'>
<img class='featured-app-logo' data-src="{{ static-asset 'image' '/app-img/' this.slug '/' this.icon }}" alt='{{this.name}}'>
</div>
<div class='featured-app-name'>{{this.name}}</div>
<div class='featured-app-description' style='display:none;'>{{this.description}}</div>
Expand Down

0 comments on commit 9e4cb8a

Please sign in to comment.