first commit
This commit is contained in:
74
services/web/frontend/macros/import-overleaf-module.macro.js
Normal file
74
services/web/frontend/macros/import-overleaf-module.macro.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const { createMacro, MacroError } = require('babel-plugin-macros')
|
||||
|
||||
// This copy of the settings will be taken when webpack starts.
|
||||
// Be sure to restart webpack after making changes to the settings.
|
||||
const Settings = require('@overleaf/settings')
|
||||
|
||||
const macro = createMacro(importOverleafModuleMacro)
|
||||
|
||||
function importOverleafModuleMacro({ references, state, babel }) {
|
||||
references.default.forEach(referencePath => {
|
||||
const { types: t } = babel
|
||||
|
||||
const modulePaths = getModulePaths(referencePath.parentPath)
|
||||
|
||||
const { importNodes, importedVariables } = modulePaths.reduce(
|
||||
(all, path) => {
|
||||
// Generate a unique variable name for the module
|
||||
const id = referencePath.scope.generateUidIdentifier(path)
|
||||
|
||||
// Generate an import statement for the module
|
||||
// In the form: import * as __ID__ from "__PATH__"
|
||||
all.importNodes.push(
|
||||
t.importDeclaration(
|
||||
[t.importNamespaceSpecifier(id)],
|
||||
t.stringLiteral(path)
|
||||
)
|
||||
)
|
||||
|
||||
// Also keep track of the imported variable, so it can be added to
|
||||
// the assigned array
|
||||
all.importedVariables.push(
|
||||
t.objectExpression([
|
||||
t.objectProperty(t.identifier('import'), id),
|
||||
t.objectProperty(t.identifier('path'), t.stringLiteral(path)),
|
||||
])
|
||||
)
|
||||
|
||||
return all
|
||||
},
|
||||
{ importNodes: [], importedVariables: [] }
|
||||
)
|
||||
|
||||
// Generate an array of imported variables
|
||||
const arrayExpression = t.arrayExpression(importedVariables)
|
||||
|
||||
// Inject the import statements at the top of the file
|
||||
const program = state.file.path
|
||||
program.node.body.unshift(...importNodes)
|
||||
|
||||
// Replace the importFromSettings line with the generated array of imported
|
||||
// variables
|
||||
referencePath.parentPath.replaceWith(arrayExpression)
|
||||
})
|
||||
}
|
||||
|
||||
function getModulePaths(callExpressionPath) {
|
||||
// Get the first argument to importFromSettings
|
||||
const key = callExpressionPath.get('arguments')[0].evaluate().value
|
||||
|
||||
if (!Settings.overleafModuleImports) {
|
||||
throw new MacroError('Settings.overleafModuleImports not found')
|
||||
}
|
||||
|
||||
// Get the module paths
|
||||
const modulePaths = Settings.overleafModuleImports[key]
|
||||
|
||||
if (!modulePaths) {
|
||||
throw new MacroError(`Overleaf module '${key}' not found`)
|
||||
}
|
||||
|
||||
return modulePaths
|
||||
}
|
||||
|
||||
module.exports = macro
|
@@ -0,0 +1,30 @@
|
||||
const fs = require('fs')
|
||||
const Path = require('path')
|
||||
const Settings = require('@overleaf/settings')
|
||||
|
||||
module.exports = function invalidateBabelCacheIfNeeded() {
|
||||
const cachePath = Path.join(__dirname, '../../node_modules/.cache')
|
||||
const statePath = Path.join(cachePath, 'last-overleafModuleImports.json')
|
||||
let lastState = ''
|
||||
try {
|
||||
lastState = fs.readFileSync(statePath, { encoding: 'utf-8' })
|
||||
} catch (e) {}
|
||||
|
||||
const newState = JSON.stringify(Settings.overleafModuleImports)
|
||||
if (lastState !== newState) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'Detected change in overleafModuleImports, purging babel cache!'
|
||||
)
|
||||
// Gracefully handle cache mount in Server Pro build, only purge nested folders and keep .cache/ folder.
|
||||
fs.mkdirSync(cachePath, { recursive: true })
|
||||
for (const name of fs.readdirSync(cachePath)) {
|
||||
fs.rmSync(Path.join(cachePath, name), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
maxRetries: 5,
|
||||
})
|
||||
}
|
||||
fs.writeFileSync(statePath, newState)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user