|
const fs = require('fs') |
|
const path = require('path') |
|
const replace = require('replace-in-file') |
|
const escapeRegExp = require('lodash.escaperegexp') |
|
|
|
// the directory in which you're outputting your build (come from parcel) |
|
const basePath = path.resolve(__dirname, 'dist') |
|
|
|
console.log('basePath', basePath) |
|
|
|
// the file lists remain location unchanged |
|
const blackList = ['manifest.webmanifest'] |
|
|
|
// the name for the directory where your static files will be moved to |
|
const assetDir = 'assets' |
|
|
|
// the directory where your built files (css and JavaScript) will be moved to |
|
const compiledDir = 'compiled' |
|
|
|
// if the assetDir directory isn't there, create it |
|
if (!fs.existsSync(path.join(basePath, assetDir))) { |
|
fs.mkdirSync(path.join(basePath, assetDir)) |
|
} |
|
|
|
// same for the compiledDir directory |
|
if (!fs.existsSync(path.join(basePath, compiledDir))) { |
|
fs.mkdirSync(path.join(basePath, compiledDir)) |
|
} |
|
|
|
const globalResult = {} |
|
|
|
function replaceFile({ filePath, names, fromFn, toFn, reason }) { |
|
names.forEach(name => { |
|
const fromString = fromFn(name) |
|
const toString = toFn(name) |
|
|
|
const options = { |
|
files: filePath, |
|
from: fromString, |
|
to: toString, |
|
countMatches: true, |
|
} |
|
|
|
try { |
|
const r = replace |
|
.sync(options) |
|
.map(changedFile => ({ |
|
from: fromString, |
|
to: toString, |
|
matches: changedFile.numMatches, |
|
replaced: changedFile.numReplacements, |
|
reason: reason, |
|
})) |
|
.filter(x => x.matches || x.replaced) |
|
|
|
if (r.length !== 0) { |
|
globalResult[filePath] = (globalResult[filePath] || []).concat(r) |
|
} |
|
} catch (error) { |
|
console.error('Error occurred:', error) |
|
} |
|
}) |
|
} |
|
|
|
// Loop through the basePath directory |
|
fs.readdir(basePath, (err, files) => { |
|
// store all files in custom arrays by type |
|
let html = [] |
|
let js = [] |
|
let css = [] |
|
let maps = [] |
|
let assetFiles = [] |
|
|
|
files.forEach(file => { |
|
// first HTML files |
|
if (file.match(/.+\.(html)$/) && !blackList.includes(file)) { |
|
html.push(file) |
|
} else if (file.match(/.+\.(js)$/) && !blackList.includes(file)) { |
|
// then JavaScripts |
|
js.push(file) |
|
} else if (file.match(/.+\.(map)$/) && !blackList.includes(file)) { |
|
// then CSS |
|
maps.push(file) |
|
} else if (file.match(/.+\.(css)$/) && !blackList.includes(file)) { |
|
// then sourcemaps |
|
css.push(file) |
|
} else if (file.match(/.+\..+$/) && !blackList.includes(file)) { |
|
// all other files, exclude current directory and directory one level up |
|
assetFiles.push(file) |
|
} |
|
}) |
|
|
|
// check what went where |
|
console.table({ |
|
html, |
|
css, |
|
js, |
|
assetFiles, |
|
}) |
|
|
|
// create an array for all compiled assets |
|
let compiledFiles = css.concat(js).concat(maps) |
|
|
|
// replace all other resources in html |
|
html.forEach(file => { |
|
replaceFile({ |
|
reason: 'html static assets', |
|
filePath: path.join(basePath, file), |
|
names: assetFiles, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => assetDir + '/' + name, |
|
}) |
|
|
|
replaceFile({ |
|
reason: 'html compiled files', |
|
filePath: path.join(basePath, file), |
|
names: compiledFiles, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => compiledDir + '/' + name, |
|
}) |
|
}) |
|
|
|
// replace source map links in js |
|
js.forEach(file => { |
|
replaceFile({ |
|
reason: 'js source map', |
|
filePath: path.join(basePath, file), |
|
names: maps, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => compiledDir + '/' + name, |
|
}) |
|
}) |
|
|
|
// replace source map links in css |
|
css.forEach(file => { |
|
replaceFile({ |
|
reason: 'css source map', |
|
filePath: path.join(basePath, file), |
|
names: maps, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => compiledDir + '/' + name, |
|
}) |
|
}) |
|
|
|
// replace static assets links in css |
|
css.forEach(file => { |
|
replaceFile({ |
|
reason: 'css static assets', |
|
filePath: path.join(basePath, file), |
|
names: assetFiles, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => assetDir + '/' + name, |
|
}) |
|
}) |
|
|
|
// special review for manifest |
|
replaceFile({ |
|
reason: 'manifest rewrite', |
|
filePath: path.join(basePath, 'manifest.webmanifest'), |
|
names: assetFiles, |
|
fromFn: name => new RegExp(escapeRegExp(name), 'g'), |
|
toFn: name => assetDir + '/' + name, |
|
}) |
|
|
|
Object.keys(globalResult).forEach(key => { |
|
console.group(key) |
|
console.table(globalResult[key]) |
|
console.groupEnd() |
|
}) |
|
|
|
// move js and css and maps |
|
compiledFiles.forEach(name => { |
|
fs.rename(path.join(basePath, name), path.join(basePath, compiledDir, name), function(err) { |
|
if (err) throw err |
|
console.log(`Successfully moved ${name}`) |
|
}) |
|
}) |
|
// move staticAssets |
|
assetFiles.forEach(name => { |
|
fs.rename(path.join(basePath, name), path.join(basePath, assetDir, name), function(err) { |
|
if (err) throw err |
|
console.log(`Successfully moved ${name}`) |
|
}) |
|
}) |
|
}) |