ente/web/docs/dependencies.md
2024-05-09 20:44:52 +05:30

6.2 KiB

Dependencies

Dev

These are some global dev dependencies in the root package.json. These set the baseline for how our code be in all the workspaces in this (yarn) monorepo.

  • "prettier" - Formatter
  • "eslint" - Linter
  • "typescript" - Type checker

They also need some support packages, which come from the leaf @/build-config package:

  • "@typescript-eslint/parser" - Tells ESLint how to read TypeScript syntax
  • "@typescript-eslint/eslint-plugin" - Provides TypeScript rules and presets
  • "eslint-plugin-react-hooks", "eslint-plugin-react-namespace-import" - Some React specific ESLint rules and configurations that are used by the workspaces that have React code.
  • "eslint-plugin-react-refresh" - A plugin to ensure that React components are exported in a way that they can be HMR-ed.
  • "prettier-plugin-organize-imports" - A Prettier plugin to sort imports.
  • "prettier-plugin-packagejson" - A Prettier plugin to also prettify package.json.

Utils

Crypto

We use libsodium for encryption, key generation etc. Specifically, we use its WebAssembly and JS wrappers made using Emscripten, maintained by the original authors of libsodium themselves - libsodium-wrappers.

Currently, we've pinned the version to 0.7.9 since later versions remove the crypto_pwhash_* functionality that we use (they've not been deprecated, they've just been moved to a different NPM package). From the (upstream) release notes:

Emscripten: the crypto_pwhash_*() functions have been removed from Sumo builds, as they reserve a substantial amount of JavaScript memory, even when not used.

This wording is a bit incorrect, they've actually been added to the sumo builds (See this issue).

Updating it is not a big problem, it is just a pending chore - we want to test a bit more exhaustively when changing the crypto layer.

UI

React

React ("react") is our core framework. It also has a sibling "react-dom" package that renders JSX to the DOM.

MUI and Emotion

We use MUI ("@mui/material"), which is a React component library, to get a base set of components.

MUI uses Emotion (a styled-component variant) as its preferred CSS-in-JS library.

Emotion itself comes in many parts, of which we need the following:

  • "@emotion/react" - React interface to Emotion. In particular, we set this as the package that handles the transformation of JSX into JS (via the jsxImportSource property in tsconfig.json).

  • "@emotion/styled" - Provides the styled utility, a la styled-components. We don't use it directly, instead we import it from @mui/material. However, MUI docs mention that

    Keep @emotion/styled as a dependency of your project. Even if you never use it explicitly, it's a peer dependency of @mui/material.

Component selectors

Note that currently the SWC plugin doesn't allow the use of the component selectors API (i.e using styled.div instead of styled("div")).

I think the transform for component selectors is not implemented in the swc plugin.

https://github.com/vercel/next.js/issues/46973

There is a way of enabling it by installing the @emotion/babel-plugin and specifying the import map as mentioned here (full example), but that disables the SWC integration altogether, so we live with this infelicity for now.

Translations

For showing the app's UI in multiple languages, we use the i18next library, specifically its three components

  • "i18next": The core i18next library.
  • "i18next-http-backend": Adds support for initializing i18next with JSON file containing the translation in a particular language, fetched at runtime.
  • "react-i18next": React specific support in i18next.

Note that inspite of the "next" in the name of the library, it has nothing to do with Next.js.

For more details, see translations.md.

Meta frameworks

Next.js

Next.js ("next") provides the meta framework for both the Photos and the Auth app, and also for some of the sidecar apps like accounts and cast.

We use a limited subset of Next. The main thing we get out of it is a reasonable set of defaults for bundling our app into a static export which we can then deploy to our webserver. In addition, the Next.js page router is convenient. Apart from this, while we use a few tidbits from Next.js here and there, overall our apps are regular React SPAs, and are not particularly tied to Next.

Vite

For some of our newer code, we have started to use Vite. It is more lower level than Next, but the bells and whistles it doesn't have are the bells and whistles (and the accompanying complexity) that we don't need in some cases.

Media

  • jszip is used for reading zip files in JavaScript (Live photos are zip files under the hood).

  • file-type is used for MIME type detection. We are at an old version 16.5.4 because v17 onwards the package became ESM only - for our limited use case, the custom Webpack configuration that entails is not worth the upgrade.

  • heic-convert is used for converting HEIC files (which browsers don't natively support) into JPEG.

Processing

  • comlink provides a minimal layer on top of Web Workers to make them more easier to use.

Photos app specific

  • react-dropzone is a React hook to create a drag-and-drop input zone.

  • sanitize-filename is for converting arbitrary strings into strings that are suitable for being used as filenames.