1
0
Fork 0
Browse Source

chore: post-process HTML to inline

Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
main
André Jaenisch 11 months ago
parent
commit
65ae584fe3
Signed by: ryuno-ki
GPG Key ID: 5A668E771F1ED854
  1. 2
      .gitignore
  2. 0
      dist/css/.gitkeep
  3. 0
      dist/js/.gitkeep
  4. BIN
      js13kgames.zip
  5. 884
      package-lock.json
  6. 3
      package.json
  7. 4
      rollup.config.js
  8. 152
      scripts/post-process.cjs

2
.gitignore vendored

@ -151,3 +151,5 @@ dist
# Custom
tmp
!dist/.gitkeep
!dist/js/.gitkeep
!dist/css/.gitkeep

0
dist/css/.gitkeep vendored

0
dist/js/.gitkeep vendored

BIN
js13kgames.zip

Binary file not shown.

884
package-lock.json generated

File diff suppressed because it is too large Load Diff

3
package.json

@ -12,6 +12,8 @@
"lint:js": "eslint ./src",
"postbuild": "cp ./tmp/*.js ./dist/ && npm run check",
"posttest": "npm run tsd",
"post-process": "node ./scripts/post-process.cjs",
"precheck": "npm run post-process",
"prepare": "husky install",
"pre-commit": "npm run types && npm run lint && npm run test",
"test": "mocha",
@ -45,6 +47,7 @@
"eslint-plugin-promise": "4.2.1",
"html5-boilerplate": "8.0.0",
"husky": "7.0.1",
"jsdom": "16.7.0",
"mocha": "9.0.3",
"nyc": "15.1.0",
"rollup": "2.56.2",

4
rollup.config.js

@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License
along with An Offline Life. If not, see <https://www.gnu.org/licenses/>.`
export default {
input: './src/app.js',
input: './src/js/app.js',
output: {
file: './tmp/app.js',
file: './dist/js/app.js',
format: 'iife',
},
plugins: [

152
scripts/post-process.cjs

@ -0,0 +1,152 @@
const fs = require('fs')
const path = require('path')
const jsdom = require('jsdom')
const { JSDOM } = jsdom
const distFolder = path.join(__dirname, '..', 'dist')
const indexHtmlFilePath = path.join(distFolder, 'index.html')
async function deleteFile (filePath) {
console.log('Clean up ', filePath)
return new Promise((resolve, reject) => {
fs.unlink(filePath, (error) => {
if (error) {
reject(error)
}
resolve()
})
})
}
async function cleanUp (scriptFileName, styleFileName) {
return Promise.all([
deleteFile(scriptFileName),
deleteFile(styleFileName)
])
}
async function extractScriptFileName (htmlString) {
const dom = new JSDOM(htmlString)
const document = dom.window.document
const scriptElement = document.querySelector('script')
const scriptSrc = scriptElement.getAttribute('src')
const scriptFileName = path.join(distFolder, scriptSrc)
return scriptFileName
}
async function inlineScript (htmlString, scriptSrc) {
const dom = new JSDOM(htmlString)
const document = dom.window.document
const scriptElement = document.querySelector('script')
const script = document.createElement('script')
const source = document.createTextNode(scriptSrc)
script.appendChild(source)
scriptElement.parentNode.replaceChild(script, scriptElement)
return Promise.resolve(document.documentElement.outerHTML)
}
async function extractStyleFileName (htmlString) {
const dom = new JSDOM(htmlString)
const document = dom.window.document
const linkElement = document.querySelector('link[rel="stylesheet"]')
const styleSrc = linkElement.getAttribute('href')
const styleFileName = path.join(distFolder, styleSrc)
return styleFileName
}
async function inlineStyle (htmlString, styleSrc) {
const dom = new JSDOM(htmlString)
const document = dom.window.document
const linkElement = document.querySelector('link[rel="stylesheet"]')
const style = document.createElement('style')
const source = document.createTextNode(styleSrc)
style.appendChild(source) // TODO: Should work with replaceChild, too?
linkElement.remove()
document.head.appendChild(style)
return Promise.resolve(document.documentElement.outerHTML)
}
async function updateFile (originalHtmlString, updatedHtmlString) {
const dom = new JSDOM(originalHtmlString)
const doctype = dom.window.document.doctype
const content = [
'<!DOCTYPE ',
doctype.name,
doctype.internalSubset,
doctype.publicId,
doctype.systemId,
'>'
].join('') + '\n' + updatedHtmlString
return new Promise((resolve, reject) => {
fs.writeFile(indexHtmlFilePath, content, (error) => {
if (error) {
return reject(error)
}
resolve(updatedHtmlString)
})
})
}
function parseFile (filePath) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (error, content) => {
if (error) {
return reject(error)
}
resolve(content)
})
})
}
async function run () {
let htmlString = ''
let updatedHtmlString = htmlString
try {
htmlString = await parseFile(indexHtmlFilePath)
} catch (exc) {
console.error(exc)
return process.exit(1)
}
const scriptFileName = await extractScriptFileName(htmlString)
const styleFileName = await extractStyleFileName(htmlString)
try {
const scriptSrc = await parseFile(scriptFileName)
updatedHtmlString = await inlineScript(htmlString, scriptSrc)
} catch (exc) {
console.error(exc)
return process.exit(2)
}
try {
const styleSrc = await parseFile(styleFileName)
updatedHtmlString = await inlineStyle(updatedHtmlString, styleSrc)
} catch (exc) {
console.error(exc)
return process.exit(3)
}
try {
await updateFile(htmlString, updatedHtmlString)
} catch (exc) {
console.error(exc)
process.exit(4)
}
try {
cleanUp(scriptFileName, styleFileName)
} catch (exc) {
console.error(exc)
return process.exit(5)
}
}
run()
Loading…
Cancel
Save