Spago-only lockfile vs. combined Spago + npm lockfile for reproducible PureScript FFI builds
0 reputation · 29 May 2021, 09:17 UTC
0 reputation · 29 May 2021, 09:17 UTC
Goal: achieve deterministic builds for a PureScript project that calls JavaScript via FFI.
Constraint: Spago’s Dhall lockfile guarantees exact PureScript package versions but does not capture the npm packages used in foreign imports, leaving the JS dependency tree vulnerable to drift.
Uncertainty: teams can either rely solely on Spago's lockfile and manage JS versions with npm’s --save-exact, accepting possible JS version drift, or maintain a separate npm lockfile (or yarn.lock) alongside Spago and keep both in sync, incurring overhead but promising full reproducibility.
Questions: Should the project treat the npm lockfile as authoritative for JS dependencies and enforce synchronization via automated checks, or is it acceptable to lock JS versions loosely and audit them periodically? Does the added maintenance of dual lockfiles justify the guarantee of deterministic runtime behavior?
35275 reputation · 29 May 2021, 16:58 UTC
Treat the npm lockfile as authoritative for JavaScript dependencies and keep it in sync with Spago’s lockfile; this gives deterministic builds for FFI code.
Spago’s lockfile pins the exact PureScript package set, while an npm lockfile (package‑lock.json or yarn.lock) pins the exact Node modules used by foreign imports. Using both together fixes the two ecosystems simultaneously, preventing version drift between the PureScript code and its FFI‑bound JavaScript.
spago.lock or via spago.dhall) that records the precise set and versions resolved by spago install.package-lock.json/yarn.lock that records the exact versions of all Node modules, including those required by FFI imports.npm ci (or yarn install --frozen-lockfile) followed by spago build (without re‑running spago install or npm install) guarantees the same dependency tree on every machine.spago.lock and package-lock.json or yarn.lock) to the repository.# install exact Node modules
npm ci # or: yarn install --frozen-lockfile
# build PureScript using the already‑installed packages
spago build # or spago test, spago bundle, etc.
npm install # updates package-lock.json if needed
spago install # updates spago.lock if needed
git diff --exit-code spago.lock package-lock.json
If the diff exits with a non‑zero status, the commit is rejected, forcing the developer to re‑run the lock‑sync steps.Do you already have a CI step that installs dependencies from the lockfiles without re‑solving (i.e., runs npm ci or yarn install --frozen-lockfile)? If not, add that step; otherwise the dual‑lockfile approach is recommended.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 29 May 2021, 09:53 UTC
When using both lockfiles, run the package manager's frozen install first (npm ci or yarn install --frozen-lockfile) and then invoke spago build without re‑running spago install. This keeps the Spago lockfile unchanged because Spago only updates it during spago install. If you need to add a new PureScript dependency, run spago install followed by the appropriate npm install (or yarn add) and commit both updated lockfiles together.