Skip to content

Instantly share code, notes, and snippets.

@le-martre
Last active June 14, 2023 12:30
Show Gist options
  • Save le-martre/7235dbf42f601d83744067a72c4348fa to your computer and use it in GitHub Desktop.
Save le-martre/7235dbf42f601d83744067a72c4348fa to your computer and use it in GitHub Desktop.
// Dependencies :
// npm i download jsdom walk replaceall
const path = require('path')
const fsp = require('fs').promises
const download = require('download')
const walk = require('walk')
const replaceAll = require("replaceall");
const { JSDOM } = require('jsdom')
// usage :
// node fetchImages.js nextjsOutDirectory imagesPrefix1 imagesPrefix2 imagesPrefix3
// example :
// node fetchImages.js ./out http://localhost:1337
// What I did :
// - Put the file at the root of my project
// - Edit my "export" npm script and added "&& npm run fetch-images" after "next build && next export"
let startPath = process.argv[2]
let urls = process.argv.slice(3)
async function fetchImages() {
let walker = walk.walk(startPath)
walker.on('file', async (root, fileStats, next) => {
if (fileStats.name.indexOf('.html') > 0) {
const filePath = path.join(root, fileStats.name)
const file = await fsp.readFile(filePath, { encoding: 'utf-8' })
await handlePage(file)
await updatePage(file, filePath)
} else if (fileStats.name.indexOf('.json') > 0) {
const filePath = path.join(root, fileStats.name)
const file = await fsp.readFile(filePath, { encoding: 'utf-8' })
await handleJson(file)
await updatePage(file, filePath)
}
next()
})
walker.on('errors', console.log)
walker.on('end', function () {
console.log('all done');
});
}
async function handlePage(data) {
let dom = new JSDOM(data, { resources: 'usable' })
let srcs = dom.window.document.querySelectorAll('img[src]')
let srcSets = dom.window.document.querySelectorAll('img[srcSet]')
function setUrls(src) {
if (src && src !== '') {
if (src.indexOf('http') === 0) {
downloadSrc(src)
}
}
}
srcs.forEach((e) => setUrls(e.getAttribute('src')))
srcSets.forEach((srcSet) => {
const imgSrcSet = srcSet.getAttribute('srcset')
imgSrcSet
.split(', ')
.forEach((src) => {
setUrls(src)
})
})
}
// Update the pages' content
async function updatePage(data, filePath) {
urls.forEach((url) => {
console.log(url)
data = replaceAll(url, '/assets', data)
})
try {
console.log('updating file')
fsp.writeFile(filePath, data, { encoding: 'utf8' })
} catch (e) {
console.log(e)
}
}
async function handleJson(data) {
let srcs = [];
urls.forEach((url) => {
let regex = new RegExp('"' + url + '\/\.\*\?' + '"', 'g');
srcs = [...srcs, ...data.matchAll(regex)];
});
srcs = srcs.flat().map((e) => e.replace(/"/g, ''));
function setUrls(src) {
if (src && src !== '') {
if (src.indexOf('http') === 0) {
downloadSrc(src)
}
}
}
srcs.forEach((e) => setUrls(e))
}
async function downloadSrc(src) {
const urlTrimmed = src.split('?')[0]
const filename = urlTrimmed.split('/').slice(-1)[0]
try {
await fsp.stat(path.join(startPath, '/assets', filename))
console.log('skipping asset named', filename, 'already exists')
} catch (e) {
console.log('downloading to assets', urlTrimmed.split('/').slice(-1))
await download(urlTrimmed.split('?')[0], path.join(startPath, '/assets'))
}
}
fetchImages()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment