Convert app.js to ES modules

GitOrigin-RevId: 7819cc8c8235b93b985c1c07c7dec778c93d9134
This commit is contained in:
andrew rumble 2024-09-25 17:02:35 +01:00 committed by Copybot
parent 209a3670ce
commit e128e8ea32
16 changed files with 130 additions and 137 deletions

View file

@ -120,7 +120,7 @@ services:
- "127.0.0.1:9229:9229"
volumes:
- ../services/web/app:/overleaf/services/web/app
- ../services/web/app.js:/overleaf/services/web/app.js
- ../services/web/app.mjs:/overleaf/services/web/app.mjs
- ../services/web/config:/overleaf/services/web/config
- ../services/web/locales:/overleaf/services/web/locales
- ../services/web/modules:/overleaf/services/web/modules

View file

@ -11,4 +11,4 @@ export LISTEN_ADDRESS=0.0.0.0
export ENABLED_SERVICES="api"
export METRICS_APP_NAME="web-api"
exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.js >> /var/log/overleaf/web-api.log 2>&1
exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.mjs >> /var/log/overleaf/web-api.log 2>&1

View file

@ -11,4 +11,4 @@ export LISTEN_ADDRESS=127.0.0.1
export ENABLED_SERVICES="web"
export WEB_PORT="4000"
exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.js >> /var/log/overleaf/web.log 2>&1
exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.mjs >> /var/log/overleaf/web.log 2>&1

View file

@ -71,7 +71,7 @@ RUN OVERLEAF_CONFIG=/overleaf/services/web/config/settings.overrides.saas.js npm
# the web image with only production dependencies but no webpack production build, for development
FROM pug AS app-only
USER node
CMD ["node", "--expose-gc", "app.js"]
CMD ["node", "--expose-gc", "app.mjs"]
# the final production image, with webpack production build but without source maps
@ -80,4 +80,4 @@ ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
COPY --from=webpack-no-sourcemaps /overleaf/services/web/public /overleaf/services/web/public
USER node
CMD ["node", "--expose-gc", "app.js"]
CMD ["node", "--expose-gc", "app.mjs"]

View file

@ -1,28 +1,34 @@
// Metrics must be initialized before importing anything else
require('@overleaf/metrics/initialize')
import '@overleaf/metrics/initialize.js'
const metrics = require('@overleaf/metrics')
const Settings = require('@overleaf/settings')
const logger = require('@overleaf/logger')
const PlansLocator = require('./app/src/Features/Subscription/PlansLocator')
const SiteAdminHandler = require('./app/src/infrastructure/SiteAdminHandler')
const Modules = require('./app/src/infrastructure/Modules')
import Modules from './app/src/infrastructure/Modules.js'
import metrics from '@overleaf/metrics'
import Settings from '@overleaf/settings'
import logger from '@overleaf/logger'
import PlansLocator from './app/src/Features/Subscription/PlansLocator.js'
import SiteAdminHandler from './app/src/infrastructure/SiteAdminHandler.js'
import http from 'node:http'
import https from 'node:https'
import * as Serializers from './app/src/infrastructure/LoggerSerializers.js'
import Server from './app/src/infrastructure/Server.js'
import QueueWorkers from './app/src/infrastructure/QueueWorkers.js'
import mongodb from './app/src/infrastructure/mongodb.js'
import mongoose from './app/src/infrastructure/Mongoose.js'
import { triggerGracefulShutdown } from './app/src/infrastructure/GracefulShutdown.js'
import FileWriter from './app/src/infrastructure/FileWriter.js'
import { fileURLToPath } from 'url'
logger.initialize(process.env.METRICS_APP_NAME || 'web')
logger.logger.serializers.user =
require('./app/src/infrastructure/LoggerSerializers').user
logger.logger.serializers.docs =
require('./app/src/infrastructure/LoggerSerializers').docs
logger.logger.serializers.files =
require('./app/src/infrastructure/LoggerSerializers').files
logger.logger.serializers.project =
require('./app/src/infrastructure/LoggerSerializers').project
logger.logger.serializers.user = Serializers.user
logger.logger.serializers.docs = Serializers.docs
logger.logger.serializers.files = Serializers.files
logger.logger.serializers.project = Serializers.project
if (Settings.sentry?.dsn != null) {
logger.initializeErrorReporting(Settings.sentry.dsn)
}
const http = require('http')
const https = require('https')
http.globalAgent.maxSockets = Settings.limits.httpGlobalAgentMaxSockets
https.globalAgent.maxSockets = Settings.limits.httpsGlobalAgentMaxSockets
@ -30,15 +36,6 @@ metrics.memory.monitor(logger)
metrics.leaked_sockets.monitor(logger)
metrics.open_sockets.monitor()
const Server = require('./app/src/infrastructure/Server')
const QueueWorkers = require('./app/src/infrastructure/QueueWorkers')
const mongodb = require('./app/src/infrastructure/mongodb')
const mongoose = require('./app/src/infrastructure/Mongoose')
const {
triggerGracefulShutdown,
} = require('./app/src/infrastructure/GracefulShutdown')
const FileWriter = require('./app/src/infrastructure/FileWriter')
if (Settings.catchErrors) {
process.removeAllListeners('uncaughtException')
process.on('uncaughtException', error =>
@ -51,9 +48,8 @@ FileWriter.ensureDumpFolderExists()
const port = Settings.port || Settings.internal.web.port || 3000
const host = Settings.internal.web.host || '127.0.0.1'
if (!module.parent) {
if (process.argv[1] === fileURLToPath(import.meta.url)) {
// Called directly
// We want to make sure that we provided a password through the environment.
if (!process.env.WEB_API_USER || !process.env.WEB_API_PASSWORD) {
throw new Error('No API user and password provided')
@ -65,9 +61,7 @@ if (!module.parent) {
.then(async () => {
Server.server.listen(port, host, function () {
logger.debug(`web starting up, listening on ${host}:${port}`)
logger.debug(
`${require('http').globalAgent.maxSockets} sockets enabled`
)
logger.debug(`${http.globalAgent.maxSockets} sockets enabled`)
// wait until the process is ready before monitoring the event loop
metrics.event_loop.monitor(logger)
})
@ -93,4 +87,4 @@ process.on('SIGTERM', function (signal) {
triggerGracefulShutdown(Server.server, signal)
})
module.exports = Server.server
export default Server.server

View file

@ -6,7 +6,7 @@ POTENTIAL_SEND_USAGE=$(\
grep \
--files-with-matches \
--recursive \
app.js \
app.mjs \
app/ \
modules/*/app \
test/acceptance/ \

View file

@ -1,23 +0,0 @@
require('../../../../../test/acceptance/src/helpers/InitApp')
const MockDocstoreApi = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi')
const MockDocUpdaterApi = require('../../../../../test/acceptance/src/mocks/MockDocUpdaterApi')
const MockFilestoreApi = require('../../../../../test/acceptance/src/mocks/MockFilestoreApi')
const MockNotificationsApi = require('../../../../../test/acceptance/src/mocks/MockNotificationsApi')
const MockProjectHistoryApi = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi')
const MockSpellingApi = require('../../../../../test/acceptance/src/mocks/MockSpellingApi')
const MockV1Api = require('../../../../../test/acceptance/src/mocks/MockV1Api')
const MockV1HistoryApi = require('../../../../../test/acceptance/src/mocks/MockV1HistoryApi')
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockFilestoreApi.initialize(23009, mockOpts)
MockNotificationsApi.initialize(23042, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockSpellingApi.initialize(23005, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)

View file

@ -0,0 +1,22 @@
import '../../../../../test/acceptance/src/helpers/InitApp.mjs'
import MockDocstoreApi from '../../../../../test/acceptance/src/mocks/MockDocstoreApi.js'
import MockDocUpdaterApi from '../../../../../test/acceptance/src/mocks/MockDocUpdaterApi.js'
import MockFilestoreApi from '../../../../../test/acceptance/src/mocks/MockFilestoreApi.js'
import MockNotificationsApi from '../../../../../test/acceptance/src/mocks/MockNotificationsApi.js'
import MockProjectHistoryApi from '../../../../../test/acceptance/src/mocks/MockProjectHistoryApi.js'
import MockSpellingApi from '../../../../../test/acceptance/src/mocks/MockSpellingApi.js'
import MockV1Api from '../../../../../test/acceptance/src/mocks/MockV1Api.js'
import MockV1HistoryApi from '../../../../../test/acceptance/src/mocks/MockV1HistoryApi.js'
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockFilestoreApi.initialize(23009, mockOpts)
MockNotificationsApi.initialize(23042, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockSpellingApi.initialize(23005, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)

View file

@ -1 +0,0 @@
require('../../../../../test/acceptance/src/helpers/InitApp')

View file

@ -0,0 +1 @@
import '../../../../../test/acceptance/src/helpers/InitApp.mjs'

View file

@ -1,14 +0,0 @@
require('../../../../../test/acceptance/src/helpers/InitApp')
const MockProjectHistoryApi = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi')
const MockDocstoreApi = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi')
const MockDocUpdaterApi = require('../../../../../test/acceptance/src/mocks/MockDocUpdaterApi')
const MockV1Api = require('../../../../admin-panel/test/acceptance/src/mocks/MockV1Api')
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockV1Api.initialize(25000, mockOpts)

View file

@ -0,0 +1,14 @@
import '../../../../../test/acceptance/src/helpers/InitApp.mjs'
import MockProjectHistoryApi from '../../../../../test/acceptance/src/mocks/MockProjectHistoryApi.js'
import MockDocstoreApi from '../../../../../test/acceptance/src/mocks/MockDocstoreApi.js'
import MockDocUpdaterApi from '../../../../../test/acceptance/src/mocks/MockDocUpdaterApi.js'
import MockV1Api from '../../../../admin-panel/test/acceptance/src/mocks/MockV1Api.js'
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockV1Api.initialize(25000, mockOpts)

View file

@ -2,7 +2,7 @@
"name": "@overleaf/web",
"description": "The HTTP front end for Overleaf",
"private": true,
"main": "app.js",
"main": "app.mjs",
"directories": {
"public": "./public"
},
@ -15,8 +15,8 @@
"test:unit:app": "npm run test:unit:run_dir -- test/unit/src",
"test:frontend": "NODE_ENV=test TZ=GMT mocha --recursive --timeout 5000 --exit --extension js,jsx,mjs,ts,tsx --grep=$MOCHA_GREP --require test/frontend/bootstrap.js --ignore '**/*.spec.{js,jsx,ts,tsx}' --ignore '**/helpers/**/*.{js,jsx,ts,tsx}' test/frontend modules/*/test/frontend",
"test:frontend:coverage": "c8 --all --include 'frontend/js' --include 'modules/*/frontend/js' --exclude 'frontend/js/vendor' --reporter=lcov --reporter=text-summary npm run test:frontend",
"start": "node app.js",
"nodemon": "node --watch app.js --watch-locales",
"start": "node app.mjs",
"nodemon": "node --watch app.mjs --watch-locales",
"webpack": "webpack serve --config webpack.config.dev.js",
"webpack:production": "webpack --config webpack.config.prod.js",
"webpack:profile": "webpack --config webpack.config.prod.js --profile --json > stats.json",

View file

@ -1,42 +0,0 @@
require('./helpers/InitApp')
const Features = require('../../../app/src/infrastructure/Features')
const MockAnalyticsApi = require('./mocks/MockAnalyticsApi')
const MockChatApi = require('./mocks/MockChatApi')
const MockClsiApi = require('./mocks/MockClsiApi')
const MockDocstoreApi = require('./mocks/MockDocstoreApi')
const MockDocUpdaterApi = require('./mocks/MockDocUpdaterApi')
const MockFilestoreApi = require('./mocks/MockFilestoreApi')
const MockGitBridgeApi = require('./mocks/MockGitBridgeApi')
const MockNotificationsApi = require('./mocks/MockNotificationsApi')
const MockProjectHistoryApi = require('./mocks/MockProjectHistoryApi')
const MockSpellingApi = require('./mocks/MockSpellingApi')
const MockV1Api = require('./mocks/MockV1Api')
const MockV1HistoryApi = require('./mocks/MockV1HistoryApi')
const MockHaveIBeenPwnedApi = require('./mocks/MockHaveIBeenPwnedApi')
const MockThirdPartyDataStoreApi = require('./mocks/MockThirdPartyDataStoreApi')
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockChatApi.initialize(23010, mockOpts)
MockClsiApi.initialize(23013, mockOpts)
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockFilestoreApi.initialize(23009, mockOpts)
MockNotificationsApi.initialize(23042, mockOpts)
MockSpellingApi.initialize(23005, mockOpts)
MockHaveIBeenPwnedApi.initialize(1337, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)
if (Features.hasFeature('saas')) {
MockAnalyticsApi.initialize(23050, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockThirdPartyDataStoreApi.initialize(23002, mockOpts)
}
if (Features.hasFeature('git-bridge')) {
MockGitBridgeApi.initialize(28000, mockOpts)
}

View file

@ -0,0 +1,42 @@
import './helpers/InitApp.mjs'
import Features from '../../../app/src/infrastructure/Features.js'
import MockAnalyticsApi from './mocks/MockAnalyticsApi.js'
import MockChatApi from './mocks/MockChatApi.js'
import MockClsiApi from './mocks/MockClsiApi.js'
import MockDocstoreApi from './mocks/MockDocstoreApi.js'
import MockDocUpdaterApi from './mocks/MockDocUpdaterApi.js'
import MockFilestoreApi from './mocks/MockFilestoreApi.js'
import MockGitBridgeApi from './mocks/MockGitBridgeApi.js'
import MockNotificationsApi from './mocks/MockNotificationsApi.js'
import MockProjectHistoryApi from './mocks/MockProjectHistoryApi.js'
import MockSpellingApi from './mocks/MockSpellingApi.js'
import MockV1Api from './mocks/MockV1Api.js'
import MockV1HistoryApi from './mocks/MockV1HistoryApi.js'
import MockHaveIBeenPwnedApi from './mocks/MockHaveIBeenPwnedApi.js'
import MockThirdPartyDataStoreApi from './mocks/MockThirdPartyDataStoreApi.js'
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockChatApi.initialize(23010, mockOpts)
MockClsiApi.initialize(23013, mockOpts)
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockFilestoreApi.initialize(23009, mockOpts)
MockNotificationsApi.initialize(23042, mockOpts)
MockSpellingApi.initialize(23005, mockOpts)
MockHaveIBeenPwnedApi.initialize(1337, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)
if (Features.hasFeature('saas')) {
MockAnalyticsApi.initialize(23050, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockThirdPartyDataStoreApi.initialize(23002, mockOpts)
}
if (Features.hasFeature('git-bridge')) {
MockGitBridgeApi.initialize(28000, mockOpts)
}

View file

@ -1,18 +1,18 @@
const App = require('../../../../app')
const QueueWorkers = require('../../../../app/src/infrastructure/QueueWorkers')
const MongoHelper = require('./MongoHelper')
const RedisHelper = require('./RedisHelper')
const logger = require('@overleaf/logger')
const Settings = require('@overleaf/settings')
const MockReCAPTCHAApi = require('../mocks/MockReCaptchaApi')
const {
gracefulShutdown,
} = require('../../../../app/src/infrastructure/GracefulShutdown')
const { app } = require('../../../../app/src/infrastructure/Server')
const { injectRouteAfter } = require('./injectRoute')
const SplitTestHandler = require('../../../../app/src/Features/SplitTests/SplitTestHandler')
const SplitTestSessionHandler = require('../../../../app/src/Features/SplitTests/SplitTestSessionHandler')
const Modules = require('../../../../app/src/infrastructure/Modules')
import App from '../../../../app.mjs'
import QueueWorkers from '../../../../app/src/infrastructure/QueueWorkers.js'
import MongoHelper from './MongoHelper.js'
import RedisHelper from './RedisHelper.js'
import logger from '@overleaf/logger'
import Settings from '@overleaf/settings'
import MockReCAPTCHAApi from '../mocks/MockReCaptchaApi.js'
import { gracefulShutdown } from '../../../../app/src/infrastructure/GracefulShutdown.js'
import Server from '../../../../app/src/infrastructure/Server.mjs'
import { injectRouteAfter } from './injectRoute.js'
import SplitTestHandler from '../../../../app/src/Features/SplitTests/SplitTestHandler.js'
import SplitTestSessionHandler from '../../../../app/src/Features/SplitTests/SplitTestSessionHandler.js'
import Modules from '../../../../app/src/infrastructure/Modules.js'
const app = Server.app
logger.logger.level('error')