| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- 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)
- }
|