guix_mirror_bot pushed a commit to branch javascript-team
in repository guix.

commit 0c5de8b6f6974790a61302157f266ae49484a65e
Author: Jelle Licht <[email protected]>
AuthorDate: Thu Sep 3 13:21:30 2026 +0200

    gnu: node: Replace bootstrap phases with esbuild bundler.
    
    Drop npm-based bootstrap-node-phases (set-home, delete-lockfiles,
    npm-install, repack, npm-global-install).  New phases:
    - configure: build NODE_PATH from inputs' lib/node_modules dirs
    - build: invoke esbuild --bundle to produce a single CJS bundle;
      reads entry point from package.json "main" or $ENTRYPOINT
    - install: copies bundle.js + minimal package.json into out
    
    * gnu/packages/node.scm: Add (gnu packages guile) module import.  Remove 
(guix
    build-system node) import.
    (bootstrap-node-phases): Replace npm-based phases with esbuild bundler using
    NODE_PATH.
    (delete-dependencies*): Remove procedure.
    (node-semver-bootstrap)[arguments]<#:phases>: Use bootstrap-node-phases
    directly.
    [native-inputs]: Replace node-bootstrap with esbuild.
    (node-llparse-builder-bootstrap)[arguments]<#:phases>: Remove
    patch-dependencies and manual repack/build phases; add set-entrypoint phase.
    [native-inputs]: Remove node-bootstrap.
    (node-llparse-frontend-bootstrap)[arguments]: Remove node-bootstrap.
    [native-inputs]: Likewise.
    (node-llparse-bootstrap)[arguments]: Likewise.
    [native-inputs]: Likewise.
---
 gnu/packages/node.scm | 254 ++++++++++++++------------------------------------
 1 file changed, 68 insertions(+), 186 deletions(-)

diff --git a/gnu/packages/node.scm b/gnu/packages/node.scm
index c786142f6e3..797ea14c920 100644
--- a/gnu/packages/node.scm
+++ b/gnu/packages/node.scm
@@ -36,7 +36,9 @@
   #:use-module (gnu packages compression)
   #:use-module (gnu packages dns)
   #:use-module (gnu packages gcc)
+  #:use-module (gnu packages guile)
   #:use-module (gnu packages icu4c)
+  #:use-module (gnu packages javascript)
   #:use-module (gnu packages libevent)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages networking)
@@ -48,7 +50,6 @@
   #:use-module (gnu packages)
   #:use-module ((guix build utils) #:select (alist-replace))
   #:use-module (guix build-system gnu)
-  #:use-module (guix build-system node)
   #:use-module (guix derivations)
   #:use-module (guix download)
   #:use-module (guix gexp)
@@ -337,64 +338,49 @@ devices.")
                   (cpe-name . "node.js")
                   (hidden? . #t)))))
 
-;; Stripped down version of the node-build-system, avoids (json) and some
-;; niceties, resulting in a simpler but brittle phases.  This allows us to work
-;; on node-build-system without recompiling node-lts for each edit.
-(define bootstrap-node-phases
-  #~(modify-phases %standard-phases
-      (add-after 'unpack 'set-home
-        (lambda _
-          (with-directory-excursion ".."
-            (let loop ((i 0))
-              (let ((dir (string-append "npm-home-" (number->string i))))
-                (if (directory-exists? dir)
-                    (loop (1+ i))
-                    (begin
-                      (mkdir dir)
-                      (setenv "HOME" (string-append (getcwd) "/" dir))
-                      (format #t "set HOME to ~s~%" (getenv "HOME")))))))))
-      (add-before 'configure 'delete-lockfiles
-        (lambda _
-          (let ((lock "package-lock.json"))
-            (when (file-exists? lock)
-            (delete-file lock)))))
-      (replace 'configure
-        (lambda* (#:key inputs #:allow-other-keys)
-          (let ((npm (string-append (assoc-ref inputs "node") "/bin/npm")))
-            (invoke npm "--offline"
-                    "--ignore-scripts"
-                    "--install-links"
-                    "--no-audit"
-                    "install"))))
-      (add-before 'install 'repack
-        (lambda _
-          (invoke "tar"
-                  ;; Add options suggested by 
https://reproducible-builds.org/docs/archives/
-                  "--sort=name"
-                  (string-append "--mtime=@" (getenv "SOURCE_DATE_EPOCH"))
-                  "--owner=0"
-                  "--group=0"
-                  "--numeric-owner"
-                  "-czf" "../package.tgz" ".")))
-      (delete 'build)
-      (replace 'install
-        (lambda* (#:key inputs outputs #:allow-other-keys)
-          (let ((out (assoc-ref outputs "out"))
-                (npm (string-append (assoc-ref inputs "node") "/bin/npm")))
-            (invoke npm "--prefix" #$output
-                    "--global"
-                    "--offline"
-                    "--loglevel" "info"
-                    "--production"
-                    "--install-links"
-                    "install" "../package.tgz"))))))
+;; Stripped-down build phases for JS packages.  Uses esbuild + NODE_PATH 
instead
+;; of npm, so editing node-build-system does not rebuild node-lts.  Set the
+;; ENTRYPOINT environment variable before the build phase to override the entry
+;; point auto-detected from package.json's "main" field, used when "main" 
points
+;; to compiled output but the TypeScript source is what esbuild should bundle.
+(define set-node-path-phase
+  #~(lambda* (#:key inputs native-inputs #:allow-other-keys)
+      (setenv "NODE_PATH"
+              (string-join
+               (delq #f
+                     (map (lambda (input)
+                            (let ((dir (string-append (cdr input) 
"/lib/node_modules")))
+                              (and (file-exists? dir) dir)))
+                          (append (or native-inputs '()) inputs)))
+               ":"))))
 
-(define (delete-dependencies* dependencies)
-  #~(substitute* "package.json"
-      (((string-append " *\"("
-                       (string-join (list #$@dependencies) "|")
-                       ")\": \".*"))
-       "")))
+(define (bootstrap-node-phases)
+  (with-extensions (list guile-json-4)
+    #~(begin
+        (use-modules (json))
+        (modify-phases %standard-phases
+          (replace 'configure #$set-node-path-phase)
+          (replace 'build
+            (lambda* (#:key inputs native-inputs #:allow-other-keys)
+              (let* ((all-inputs (append (or native-inputs '()) inputs))
+                     (esbuild (search-input-file all-inputs "/bin/esbuild"))
+                     (pkg (call-with-input-file "package.json" json->scm))
+                     (entry (or (getenv "ENTRYPOINT")
+                                (assoc-ref pkg "main")
+                                "index.js")))
+                (invoke esbuild "--bundle" "--platform=node" "--format=cjs"
+                        "--outfile=bundle.js" entry))))
+          (replace 'install
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let* ((out (assoc-ref outputs "out"))
+                     (pkg (call-with-input-file "package.json" json->scm))
+                     (name (assoc-ref pkg "name"))
+                     (dest (string-append out "/lib/node_modules/" name)))
+                (mkdir-p dest)
+                (call-with-output-file (string-append dest "/package.json")
+                  (lambda (port)
+                    (scm->json (assoc-set! pkg "main" "./index.js") port)))
+                (copy-file "bundle.js" (string-append dest "/index.js")))))))))
 
 (define-public node-semver-bootstrap
   (package
@@ -413,12 +399,8 @@ devices.")
     (arguments
      (list
       #:tests? #f
-      #:phases
-      #~(modify-phases #$bootstrap-node-phases
-          (add-before 'configure 'patch-dependencies
-            (lambda _
-              #$(delete-dependencies* (list "tap")))))))
-    (native-inputs (list node-bootstrap))
+      #:phases (bootstrap-node-phases)))
+    (native-inputs (list esbuild))
     (home-page "https://github.com/npm/node-semver";)
     (properties '((hidden? . #t)))
     (synopsis "Parses semantic versions strings")
@@ -450,7 +432,7 @@ devices.")
        (list
         #:tests? #f
         #:phases
-        #~(modify-phases #$bootstrap-node-phases
+        #~(modify-phases #$(bootstrap-node-phases)
             (add-after 'unpack 'fix-imports-for-esbuild
               ;; https://github.com/evanw/esbuild/issues/477
               (lambda _
@@ -467,28 +449,11 @@ devices.")
                                "src/code/field.ts"
                                "src/span-allocator.ts")
                   (("\\* as assert") "assert"))))
-            (add-before 'configure 'patch-dependencies
-              (lambda* (#:key inputs #:allow-other-keys)
-                #$(delete-dependencies* (list "@eslint/js"
-                                              "@stylistic/eslint-plugin"
-                                              "@types/eslint__js"
-                                              "@types/node"
-                                              
"@typescript-eslint/eslint-plugin"
-                                              "@typescript-eslint/parser"
-                                              "borp"
-                                              "eslint"
-                                              "typescript-eslint"
-                                              "typescript"))))
-            (add-before 'repack 'build
-              (lambda* (#:key inputs #:allow-other-keys)
-                (let ((esbuild (search-input-file inputs "/bin/esbuild")))
-                  (invoke esbuild
-                          "--platform=node"
-                          "--outfile=lib/builder.js"
-                          "--bundle"
-                          "src/builder.ts")))))))
+            (add-before 'build 'set-entrypoint
+              (lambda _
+                (setenv "ENTRYPOINT" "src/builder.ts"))))))
       (native-inputs
-       (list esbuild node-bootstrap))
+       (list esbuild))
       (home-page "https://github.com/nodejs/llparse-builder#readme";)
       (properties '((hidden? . #t)))
       (synopsis "Graph builder for consumption by llparse")
@@ -513,7 +478,7 @@ devices.")
      (list
       #:tests? #f
       #:phases
-      #~(modify-phases #$bootstrap-node-phases
+      #~(modify-phases #$(bootstrap-node-phases)
           (add-after 'unpack 'fix-imports-for-esbuild
             ;; https://github.com/evanw/esbuild/issues/477
             (lambda _
@@ -525,43 +490,21 @@ devices.")
                              "src/node/single.ts"
                              "src/node/table-lookup.ts"
                              "src/trie/index.ts")
-                (("\\* as assert") "assert"))))
-          (add-before 'configure 'patch-dependencies
-            (lambda* (#:key inputs #:allow-other-keys)
+                (("\\* as assert") "assert"))
               ;; Drop debug dependency, see
               ;; https://github.com/nodejs/llparse-frontend/pull/8
               (substitute* "src/frontend.ts"
                 (("import \\* as debugAPI from 'debug';")
                  "import { debuglog } from 'node:util';")
                 (("debugAPI")
-                 "debuglog"))
-              #$(delete-dependencies* (list "@types/debug"
-                                            "@types/mocha"
-                                            "@types/node"
-                                            "debug"
-                                            "mocha"
-                                            "ts-node"
-                                            "tslint"
-                                            "typescript"))
-              ;; Resolve dependencies manually.
-              (let* ((builder-path "lib/node_modules/llparse-builder")
-                     (builder (search-input-directory inputs builder-path)))
-                (substitute* "package.json"
-                  (("\"llparse-builder\": \".*")
-                   (format #f "\"llparse-builder\": \"file://~a\""
-                           builder))))))
-          (add-before 'repack 'build
-            (lambda* (#:key inputs #:allow-other-keys)
-              (let ((esbuild (search-input-file inputs "/bin/esbuild")))
-                (invoke esbuild
-                        "--platform=node"
-                        "--outfile=lib/frontend.js"
-                        "--bundle"
-                        "src/frontend.ts")))))))
+                 "debuglog"))))
+          (add-before 'build 'set-entrypoint
+            (lambda _
+              (setenv "ENTRYPOINT" "src/frontend.ts"))))))
     (inputs
      (list node-llparse-builder-bootstrap))
     (native-inputs
-     (list esbuild node-bootstrap))
+     (list esbuild))
     (home-page "https://github.com/nodejs/llparse-frontend#readme";)
     (properties '((hidden? . #t)))
     (synopsis "Frontend for the llparse compiler")
@@ -586,7 +529,7 @@ devices.")
      (list
       #:tests? #f
       #:phases
-      #~(modify-phases #$bootstrap-node-phases
+      #~(modify-phases #$(bootstrap-node-phases)
           (add-after 'unpack 'fix-imports-for-esbuild
             ;; https://github.com/evanw/esbuild/issues/477
             (lambda _
@@ -596,49 +539,21 @@ devices.")
                              "src/implementation/c/compilation.ts"
                              "src/implementation/c/helpers/match-sequence.ts"
                              "src/implementation/c/code/mul-add.ts")
-                (("\\* as assert") "assert"))))
-          (add-before 'configure 'patch-dependencies
-            (lambda* (#:key inputs #:allow-other-keys)
+                (("\\* as assert") "assert"))
               ;; Drop debug dependency, see
               ;; https://github.com/nodejs/llparse/pull/87
               (substitute* "src/compiler/index.ts"
                 (("import \\* as debugAPI from 'debug';")
                  "import { debuglog } from 'node:util';")
                 (("debugAPI")
-                 "debuglog"))
-              #$(delete-dependencies* (list "@stylistic/eslint-plugin"
-                                            "@typescript-eslint/eslint-plugin"
-                                            "@typescript-eslint/parser"
-                                            "@types/debug"
-                                            "@types/mocha"
-                                            "@types/node"
-                                            "debug"
-                                            "esm"
-                                            "eslint"
-                                            "llparse-test-fixture"
-                                            "mocha"
-                                            "ts-node"
-                                            "tslint"
-                                            "typescript"))
-              ;; Resolve dependencies manually.
-              (let* ((frontend-path "lib/node_modules/llparse-frontend")
-                     (frontend (search-input-directory inputs frontend-path)))
-                (substitute* "package.json"
-                  (("\"llparse-frontend\": \".*")
-                   (format #f "\"llparse-frontend\": \"file://~a\""
-                           frontend))))))
-          (add-before 'repack 'build
-            (lambda* (#:key inputs #:allow-other-keys)
-              (let ((esbuild (search-input-file inputs "/bin/esbuild")))
-                (invoke esbuild
-                       "--platform=node"
-                       "--outfile=lib/api.js"
-                       "--bundle"
-                       "src/api.ts")))))))
+                 "debuglog"))))
+          (add-before 'build 'set-entrypoint
+            (lambda _
+              (setenv "ENTRYPOINT" "src/api.ts"))))))
     (inputs
      (list node-llparse-frontend-bootstrap))
     (native-inputs
-     (list esbuild node-bootstrap))
+     (list esbuild))
     (home-page "https://github.com/nodejs/llparse#readme";)
     (properties '((hidden? . #t)))
     (synopsis "Compile incremental parsers to C code")
@@ -923,17 +838,7 @@ parser definition into a C output.")
                                   "/llhttpish-" version ".tgz"))
              (sha256
               (base32
-                "19zw4issqjhyfvwi7q39zvjhfmx1cq1kf887zp3sv7g7agyvczr8"))
-              (modules '((guix build utils)))
-              (snippet
-               '(begin
-                  ;; Fix imports for esbuild.
-                  ;; https://github.com/evanw/esbuild/issues/477
-                  (substitute* "llhttp/src/llhttp/http.ts"
-                    (("\\* as assert") "assert"))
-                  (substitute* "llhttp/Makefile"
-                    (("node --import tsx bin/generate.ts")
-                     "node bin/generate.js"))))))
+                "19zw4issqjhyfvwi7q39zvjhfmx1cq1kf887zp3sv7g7agyvczr8"))))
     (build-system gnu-build-system)
     (arguments
      (list
@@ -944,33 +849,10 @@ parser definition into a C output.")
               "PREFIX=")
       #:phases
       #~(modify-phases %standard-phases
-          (add-after 'unpack 'chdir-llhttp
-            (lambda _
-              (chdir "llhttp")))
-          (replace 'configure
-            (lambda* (#:key inputs native-inputs #:allow-other-keys)
-              (let ((esbuild (search-input-file (or native-inputs inputs)
-                                                "/bin/esbuild")))
-                (invoke esbuild
-                        "--platform=node"
-                        "--target=node10"
-                        "--outfile=bin/generate.js"
-                        "--bundle"
-                        "bin/generate.ts"))))
-          (add-before 'install 'create-install-directories
-            (lambda _
-              (mkdir #$output)
-              (with-directory-excursion #$output
-                (for-each mkdir (list "lib" "include" "src")))))
-          (add-after 'install 'install-src
-            (lambda _
-              (let ((src-dir (string-append #$output "/src")))
-                (install-file "build/c/llhttp.c" src-dir)
-                (install-file "src/native/api.c" src-dir)
-                (install-file "src/native/http.c" src-dir)))))))
+          (replace 'configure #$set-node-path-phase))))
     (native-inputs
      (list esbuild
-           node-bootstrap
+           quickjs
            node-llparse-bootstrap
            node-semver-bootstrap))
     (home-page "https://codeberg.org/jlicht/llhttpish";)

Reply via email to