Created
October 25, 2021 23:15
-
-
Save robomatic/8dccf289e33aac6ef92a1c4b6e69ca20 to your computer and use it in GitHub Desktop.
fetch remote images for next ssg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
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 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