mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-27 11:01:56 +02:00
[web] precompile pug templates in CI GitOrigin-RevId: 6ec2b85a357fa3d5c35d8e7eb1a2e81ac5f3b447
131 lines
3.4 KiB
JavaScript
131 lines
3.4 KiB
JavaScript
const logger = require('@overleaf/logger')
|
|
const pug = require('pug')
|
|
const globby = require('globby')
|
|
const Settings = require('@overleaf/settings')
|
|
const fs = require('fs')
|
|
const Path = require('path')
|
|
|
|
// Generate list of view names from app/views
|
|
function buildViewList() {
|
|
return globby
|
|
.sync('app/views/**/*.pug', {
|
|
onlyFiles: true,
|
|
concurrency: 1,
|
|
ignore: [
|
|
// Ignore includes
|
|
'**/_*.pug',
|
|
'**/_*/**',
|
|
// Ignore shared layout files
|
|
'app/views/layout*',
|
|
'app/views/layout/*',
|
|
],
|
|
})
|
|
.concat(
|
|
globby.sync('modules/*/app/views/**/*.pug', {
|
|
onlyFiles: true,
|
|
concurrency: 1,
|
|
// Ignore includes
|
|
ignore: ['**/_*.pug', '**/_*/**'],
|
|
})
|
|
)
|
|
.concat(Object.values(Settings.viewIncludes).flat())
|
|
.map(x => Path.resolve(x))
|
|
}
|
|
|
|
const PUG_COMPILE_ARGUMENTS = {
|
|
doctype: 'html',
|
|
cache: true,
|
|
compileDebug: Settings.debugPugTemplates,
|
|
inlineRuntimeFunctions: false,
|
|
module: true,
|
|
}
|
|
|
|
function precompileViewsAndCacheToDisk() {
|
|
const startTime = Date.now()
|
|
let success = 0
|
|
let precompiled = 0
|
|
for (const filename of buildViewList()) {
|
|
const precompiledFilename = filename.replace(/\.pug$/, '.js')
|
|
try {
|
|
const src = pug.compileFileClient(filename, PUG_COMPILE_ARGUMENTS)
|
|
try {
|
|
if (fs.readFileSync(precompiledFilename, 'utf-8') === src) {
|
|
precompiled++
|
|
continue
|
|
}
|
|
} catch {}
|
|
fs.writeFileSync(precompiledFilename, src, {
|
|
encoding: 'utf-8',
|
|
mode: 0o644,
|
|
})
|
|
success++
|
|
} catch (err) {
|
|
logger.err({ err, filename }, 'failed to precompile pug template')
|
|
throw err
|
|
}
|
|
}
|
|
logger.info(
|
|
{ timeTaken: Date.now() - startTime, success, precompiled },
|
|
'compiled pug templates'
|
|
)
|
|
}
|
|
|
|
module.exports = {
|
|
compileViewIncludes(app) {
|
|
const viewIncludes = {}
|
|
for (const [view, paths] of Object.entries(Settings.viewIncludes)) {
|
|
viewIncludes[view] = []
|
|
for (const filePath of paths) {
|
|
viewIncludes[view].push(
|
|
pug.compileFile(filePath, {
|
|
...PUG_COMPILE_ARGUMENTS,
|
|
cache: app.enabled('view cache'),
|
|
})
|
|
)
|
|
}
|
|
}
|
|
return viewIncludes
|
|
},
|
|
|
|
precompileViews(app) {
|
|
const startTime = Date.now()
|
|
let success = 0
|
|
let precompiled = 0
|
|
let failures = 0
|
|
for (const filename of buildViewList()) {
|
|
const precompiledFilename = filename.replace(/\.pug$/, '.js')
|
|
if (fs.existsSync(precompiledFilename)) {
|
|
logger.debug({ filename }, 'loading precompiled pug template')
|
|
try {
|
|
pug.cache[filename] = require(precompiledFilename)
|
|
precompiled++
|
|
continue
|
|
} catch (err) {
|
|
logger.error(
|
|
{ filename, err },
|
|
'error loading precompiled pug template'
|
|
)
|
|
failures++
|
|
}
|
|
}
|
|
try {
|
|
logger.warn({ filename }, 'compiling pug template at boot time')
|
|
pug.compileFile(filename, PUG_COMPILE_ARGUMENTS)
|
|
success++
|
|
} catch (err) {
|
|
logger.error({ filename, err }, 'error compiling pug template')
|
|
failures++
|
|
}
|
|
}
|
|
logger.debug(
|
|
{ timeTaken: Date.now() - startTime, failures, success, precompiled },
|
|
'compiled pug templates'
|
|
)
|
|
},
|
|
}
|
|
|
|
if (require.main === module) {
|
|
precompileViewsAndCacheToDisk()
|
|
process.exit(0)
|
|
}
|