Skip to content

Commit 5bb4337

Browse files
committed
added default.nix for building reproducible dev environment
1 parent 9613dcb commit 5bb4337

4 files changed

Lines changed: 131 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ old-*
4444
i18n/*.tar.gz
4545
*.old
4646
.playwright-mcp
47+
.vite
4748

4849
# Playwright
4950
/playwright/.cache/
5051
/playwright/.auth/
5152

5253
# Fixtures dropped by dev-cdn-intercept.spec.ts if a run is killed mid-test
53-
/assets/img/__probe_*.bin
54+
/assets/img/__probe_*.bin

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ yarn run dev
3535

3636
If you're on Linux, you can simply type `make` and it will do all this for you as well.
3737

38+
[Nix](https://nixos.org/) users can run `nix-shell` to open a temporary shell with a dev environment, or `nix-build -o devshell` to build a persistent script that does it. This method might be especially useful for casual/infrequent contributors who don't want to install all the NodeJS dependencies permanently on their system (but are willing to at least install Nix).
39+
3840
If you're on Windows and need specific help getting tools installed and the repo cloned, see [Detailed Setup Steps](#detailed-setup-steps-windows-but-applicable-mostly-to-others) below.
3941

4042
(And ... those detailed steps may even be a useful pointer about how to get started under Linux/macOS: they're broadly applicable, even if details differ slightly.)

default.nix

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Nix build that defines a reproducible environment for running the
2+
# server. You can use this as an easy way to jump into the dev
3+
# environment without depending on any OS-level software packages.
4+
#
5+
# Requirements: nix must be installed; use "apt install nix-bin" or
6+
# see https://nixos.org/ for more detailed options.
7+
#
8+
# Usage:
9+
#
10+
# To jump into a dev shell:
11+
# nix-shell
12+
#
13+
# To create a permanent shell for later use:
14+
# nix-build -o devshell
15+
#
16+
# Updating:
17+
# When yarn.lock or package.json get updated, we need to build a new
18+
# "offline cache" and recrod its hash. Nix will raise an error in
19+
# this case; please update the hash, try nix-shell again, and make a
20+
# PR if it still works.
21+
#
22+
# Note: this includes a dependency on a personal GitHub repository for
23+
# the simple mkBuildableShell utility. If that URL ever breaks we
24+
# could replace it with the less-functional mkShell or copy in the
25+
# code from a backup somewhere.
26+
27+
let
28+
newYarnLockHash = (builtins.hashFile "md5" yarnLock);
29+
offlineCache =
30+
pkgs.fetchYarnDeps {
31+
inherit yarnLock;
32+
name = "online-go-offline-cache-#{newYarnLockHash}";
33+
sha256 = "nSoatjgLdCrlgmdKsJIA3YqU1fNII+06XgHMEwePZEg=";
34+
};
35+
36+
# nixos-25.11 from 2026-03-15:
37+
nixpkgs =
38+
let version = "8fd9daa3db09ced9700431c5b7ad0e8ba199b575";
39+
in fetchTarball {
40+
name = "nixpkgs-${version}";
41+
url = "https://github.com/NixOS/nixpkgs/archive/${version}.tar.gz";
42+
sha256 = "1i4bkzy1siavmxaskp49lgi9s02gam6crb0d0abbbjmsyl39jbsf";
43+
};
44+
pkgs = (import nixpkgs {});
45+
46+
# mkBuildableShell from 2026-04-11:
47+
mkBuildableShell-src =
48+
let version = "064d5a1bba6236314a14421fadb873195854b0b5";
49+
in fetchTarball {
50+
name = "mkBuildableShell-${version}";
51+
url = "https://github.com/pdg137/mkBuildableShell/archive/${version}.tar.gz";
52+
sha256 = "0dsk7anb6c5f9bd72dkzzzwi4mazdji25h4m9wfn2xfvkixns10i";
53+
};
54+
mkBuildableShell = (import mkBuildableShell-src pkgs);
55+
56+
yarnLock = ./yarn.lock;
57+
packageJson = ./package.json;
58+
node = pkgs.nodejs_24;
59+
60+
# This program "napi-postinstall" didn't work as expected fom a
61+
# post-install script of unrs-resolver, maybe because of
62+
# /usr/bin/env or because of just not being on the path correctly.
63+
# So we make an alias to fix it:
64+
napi-postinstall-alias = pkgs.writeShellScriptBin "napi-postinstall"
65+
''exec ${node}/bin/node ../napi-postinstall/lib/cli.js "$@"'';
66+
67+
node-modules = pkgs.stdenv.mkDerivation {
68+
name = "ogs-node-modules";
69+
70+
dontUnpack = true;
71+
72+
nativeBuildInputs = [
73+
pkgs.yarn
74+
pkgs.fixup-yarn-lock
75+
napi-postinstall-alias
76+
];
77+
78+
buildPhase = ''
79+
set -e
80+
81+
# Use local setup for Yarn with internet access disabled.
82+
export HOME="$(mktemp -d)"
83+
yarn config --offline set yarn-offline-mirror ${offlineCache}
84+
85+
cp ${yarnLock} ./yarn.lock
86+
cp ${packageJson} ./package.json
87+
chmod u+w ./yarn.lock
88+
fixup-yarn-lock yarn.lock
89+
90+
yarn install --offline --frozen-lockfile \
91+
--no-progress --non-interactive
92+
'';
93+
94+
# Note: rollup seems to fail if the directory is not called
95+
# "node_modules", even behind a symlink.
96+
installPhase = ''
97+
set -eu
98+
mkdir -p $out
99+
mv node_modules $out
100+
'';
101+
};
102+
103+
in
104+
mkBuildableShell {
105+
name = "shell";
106+
buildInputs = [ node pkgs.yarn ];
107+
108+
shellHook = ''
109+
set -eu
110+
111+
if [ -e node_modules ] && [ ! -L node_modules ]; then
112+
echo 'Existing ./node_modules directory found; remove before proceeding.'
113+
exit 1
114+
else
115+
echo 'Linking node_modules to Nix store...'
116+
rm -f ./node_modules
117+
ln -sf ${node-modules}/node_modules ./node_modules
118+
fi
119+
export OGS_LOCAL_VITE_CACHE=1
120+
121+
echo 'Run "yarn run dev" to start the server.'
122+
set +eu
123+
'';
124+
}

vite.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ proxy["^/$"] = {
134134

135135
export default defineConfig({
136136
root: "src",
137+
// Use a .vite in the main source tree if requested, otherwise use
138+
// the default in node_modules.
139+
cacheDir: path.resolve(__dirname, process.env.OGS_LOCAL_VITE_CACHE ? ".vite" : "node_modules/.vite"),
137140
// Use relative paths so assets resolve correctly when loaded from CDN
138141
// Without this, Vite generates absolute paths (/) that resolve to document origin
139142
// instead of the CDN where the scripts are actually loaded from

0 commit comments

Comments
 (0)