build: switch to pnpm

It should be a bit more secure to not install scripts by default and to
allow one to update dependencies with a delay. Also, it is faster. The
downside is that it is not usually shipped with npm, but we can download
it through corepack (which is shipped with node). It also has more
builtin features, including patching packages (but we don't need that
anymore).
This commit is contained in:
Vincent Bernat
2025-09-17 08:50:32 +02:00
parent dab2f78751
commit fce383dbf4
13 changed files with 3958 additions and 5528 deletions

View File

@@ -33,13 +33,17 @@ runs:
cache-dependency-path: | cache-dependency-path: |
go.sum go.sum
bin/external-tool bin/external-tool
- uses: pnpm/action-setup@v4
if: ${{ inputs.setup-node == 'true' }}
with:
package_json_file: console/frontend/package.json
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
if: ${{ inputs.setup-node == 'true' }} if: ${{ inputs.setup-node == 'true' }}
with: with:
node-version: ${{ inputs.node-version }} node-version: ${{ inputs.node-version }}
cache: npm cache: pnpm
cache-dependency-path: | cache-dependency-path: |
console/frontend/package-lock.json console/frontend/pnpm-lock.yaml
bin/external-tool bin/external-tool
- name: Restore IANA files from cache - name: Restore IANA files from cache
uses: actions/cache/restore@v4 uses: actions/cache/restore@v4

View File

@@ -18,7 +18,7 @@ jobs:
id: check-changes id: check-changes
if: github.event_name == 'schedule' if: github.event_name == 'schedule'
run: | run: |
LOCKFILES="go.sum console/frontend/package-lock.json" LOCKFILES="go.sum console/frontend/pnpm-lock.yaml"
LAST_CHANGE=$(git log -1 --format=%ct -- $LOCKFILES) LAST_CHANGE=$(git log -1 --format=%ct -- $LOCKFILES)
CURRENT_TIME=$(date +%s) CURRENT_TIME=$(date +%s)
ONE_HOUR_AGO=$((CURRENT_TIME - 3600)) ONE_HOUR_AGO=$((CURRENT_TIME - 3600))

View File

@@ -14,17 +14,17 @@ run tests:
- .go-cache/ - .go-cache/
- key: - key:
files: files:
- console/frontend/package-lock.json - console/frontend/pnpm-lock.yaml
paths: paths:
- .npm-cache - .pnpm-store
script: script:
# Tests on GitLab do not include functional tests. This was the case in the # Tests on GitLab do not include functional tests. This was the case in the
# past but this is a slight burden to maintain in addition to GitHub CI. # past but this is a slight burden to maintain in addition to GitHub CI.
# Check commit ceaa6ebf8ef6 for the last version supporting functional # Check commit ceaa6ebf8ef6 for the last version supporting functional
# tests. # tests.
- time apk add --no-cache git make gcc musl-dev shared-mime-info npm curl zip - time apk add --no-cache git make gcc musl-dev shared-mime-info pnpm curl zip
- export GOMODCACHE=$PWD/.go-cache - export GOMODCACHE=$PWD/.go-cache
- npm config --user set cache $PWD/.npm-cache - pnpm config set store-dir .pnpm-store
- time go mod download - time go mod download
- time make && ./bin/akvorado version - time make && ./bin/akvorado version
- time make test-race - time make test-race

View File

@@ -60,7 +60,7 @@ $ make docker-dev && CONSOLE_HEALTHCHECK_DISABLED=true docker compose --profile
Once done, run `docker compose --profile demo down` to stop all the containers. Once done, run `docker compose --profile demo down` to stop all the containers.
If you need to work on the frontend part, you can spawn the Docker compose If you need to work on the frontend part, you can spawn the Docker compose
setup, then in `console/frontend`, use `npm run dev` and point your browser to setup, then in `console/frontend`, use `pnpm run dev` and point your browser to
`http://localhost:5173` instead of `http://localhost:8080`. Any change of `http://localhost:5173` instead of `http://localhost:8080`. Any change of
frontend-related files should be applied immediately. frontend-related files should be applied immediately.

View File

@@ -7,7 +7,9 @@ VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null
PKGS = $(or $(PKG),$(shell $(GO) list ./...)) PKGS = $(or $(PKG),$(shell $(GO) list ./...))
GO = go GO = go
NPM = npm PNPM = $(or $(shell command -v pnpm 2>/dev/null),\
$(shell command -v corepack 2>/dev/null | sed 's/$$/ pnpm/'),\
$(error No pnpm command found))
TIMEOUT = 45s TIMEOUT = 45s
LSFILES = git ls-files -cmo --exclude-standard -- LSFILES = git ls-files -cmo --exclude-standard --
V = 0 V = 0
@@ -117,13 +119,13 @@ common/schema/definition_gen.go: common/schema/definition.go common/schema/defin
console/filter/parser.go: console/filter/parser.peg ; $(info $(M) generate PEG parser for filters) console/filter/parser.go: console/filter/parser.peg ; $(info $(M) generate PEG parser for filters)
$Q $(PIGEON) -optimize-basic-latin $< > $@ $Q $(PIGEON) -optimize-basic-latin $< > $@
console/frontend/node_modules: console/frontend/package.json console/frontend/package-lock.json console/frontend/node_modules: console/frontend/package.json console/frontend/pnpm-lock.yaml
console/frontend/node_modules: ; $(info $(M) fetching node modules) console/frontend/node_modules: ; $(info $(M) fetching node modules)
$Q (cd console/frontend ; $(NPM) ci --loglevel=error --ignore-scripts --no-audit --no-fund) && touch $@ $Q (cd console/frontend ; $(PNPM) install --loglevel=error --frozen-lockfile) && touch $@
console/data/frontend: $(GENERATED_JS) console/data/frontend: $(GENERATED_JS)
console/data/frontend: $(shell $(LSFILES) console/frontend 2> /dev/null) console/data/frontend: $(shell $(LSFILES) console/frontend 2> /dev/null)
console/data/frontend: ; $(info $(M) building console frontend) console/data/frontend: ; $(info $(M) building console frontend)
$Q cd console/frontend && $(NPM) run --silent build $Q cd console/frontend && $(PNPM) run --silent build
ASNS_URL = https://vincentbernat.github.io/asn2org/asns.csv ASNS_URL = https://vincentbernat.github.io/asn2org/asns.csv
PROTOCOLS_URL = http://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv PROTOCOLS_URL = http://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv
@@ -223,9 +225,9 @@ test-coverage-go: ; $(info $(M) running Go coverage tests…) @ ## Run Go covera
test-js: .fmt-js~ .lint-js~ $(GENERATED_JS) test-js: .fmt-js~ .lint-js~ $(GENERATED_JS)
test-js: ; $(info $(M) running JS tests) @ ## Run JS tests test-js: ; $(info $(M) running JS tests) @ ## Run JS tests
$Q cd console/frontend && $(NPM) run --silent type-check && $(NPM) run --silent test $Q cd console/frontend && $(PNPM) run --silent type-check && $(PNPM) run --silent test
test-coverage-js: ; $(info $(M) running JS coverage tests) @ ## Run JS coverage tests test-coverage-js: ; $(info $(M) running JS coverage tests) @ ## Run JS coverage tests
$Q cd console/frontend && $(NPM) run --silent type-check && $(NPM) run --silent test -- --coverage $Q cd console/frontend && $(PNPM) run --silent type-check && $(PNPM) run --silent test -- --coverage
.PHONY: lint .PHONY: lint
lint: .lint-go~ .lint-js~ ## Run linting lint: .lint-go~ .lint-js~ ## Run linting
@@ -234,7 +236,7 @@ lint: .lint-go~ .lint-js~ ## Run linting
$Q touch $@ $Q touch $@
.lint-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null) .lint-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null)
.lint-js~: $(GENERATED_JS) ; $(info $(M) running jslint) .lint-js~: $(GENERATED_JS) ; $(info $(M) running jslint)
$Q cd console/frontend && $(NPM) run --silent lint $Q cd console/frontend && $(PNPM) run --silent lint
$Q touch $@ $Q touch $@
.PHONY: fmt .PHONY: fmt
@@ -244,7 +246,7 @@ fmt: .fmt-go~ .fmt-js~ ## Format all source files
$Q touch $@ $Q touch $@
.fmt-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null) .fmt-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null)
.fmt-js~: $(GENERATED_JS) ; $(info $(M) formatting JS code) .fmt-js~: $(GENERATED_JS) ; $(info $(M) formatting JS code)
$Q cd console/frontend && $(NPM) run --silent format $Q cd console/frontend && $(PNPM) run --silent format
$Q touch $@ $Q touch $@
# Misc # Misc
@@ -254,7 +256,7 @@ licensecheck: console/frontend/node_modules ; $(info $(M) check dependency licen
$Q ! git grep -L SPDX-License-Identifier: "*.go" "*.ts" "*.js" || \ $Q ! git grep -L SPDX-License-Identifier: "*.go" "*.ts" "*.js" || \
(>&2 echo "*** Missing license identifiers!"; false) (>&2 echo "*** Missing license identifiers!"; false)
$Q err=0 ; $(GO) mod vendor && $(WWHRD) --quiet check || err=$$? ; rm -rf vendor/ ; exit $$err $Q err=0 ; $(GO) mod vendor && $(WWHRD) --quiet check || err=$$? ; rm -rf vendor/ ; exit $$err
$Q cd console/frontend ; $(NPM) exec --no -- license-compliance \ $Q cd console/frontend ; $(PNPM) exec -- license-compliance \
--production \ --production \
--allow "$$(sed -n '/^allowlist:/,/^[a-z]/p' ../../.wwhrd.yml | sed -n 's/^ - //p' | paste -sd ";")" \ --allow "$$(sed -n '/^allowlist:/,/^[a-z]/p' ../../.wwhrd.yml | sed -n 's/^ - //p' | paste -sd ";")" \
--report detailed --report detailed

View File

@@ -30,8 +30,8 @@ Currently, only a pre-built binary for Linux x86-64 is provided.
## Compilation from source ## Compilation from source
You need to install [Go](https://go.dev/doc/install) (1.21+), and You need to install [Go](https://go.dev/doc/install) (1.21+), and
[NodeJS](https://nodejs.org/en/download/) (20+) with NPM (6+). For example, on [NodeJS](https://nodejs.org/en/download/) (20+) with PNPM (also accessible
Debian: through [Corepack](https://github.com/nodejs/corepack)). For example, on Debian:
```console ```console
# apt install golang nodejs npm # apt install golang nodejs npm
@@ -39,8 +39,8 @@ Debian:
go version go1.24.1 linux/amd64 go version go1.24.1 linux/amd64
# node --version # node --version
v20.19.2 v20.19.2
# npm --version # corepack pnpm --version
9.2.0 10.16.1
``` ```
Then, type: Then, type:

View File

@@ -14,6 +14,7 @@ identified with a specific icon:
- 🌱 *console*: submit form on Ctrl-Enter or Cmd-Enter while selecting dimensions - 🌱 *console*: submit form on Ctrl-Enter or Cmd-Enter while selecting dimensions
- 🌱 *cmd*: make `akvorado version` shorter (use `-d` for full output) - 🌱 *cmd*: make `akvorado version` shorter (use `-d` for full output)
- 🌱 *build*: switch from NPM to PNPM for JavaScript build
- 🌱 *build*: modernize JavaScript build with Oxlint and Rolldown-Vite - 🌱 *build*: modernize JavaScript build with Oxlint and Rolldown-Vite
## 2.0.0-beta.6 - 2025-09-06 ## 2.0.0-beta.6 - 2025-09-06

File diff suppressed because it is too large Load Diff

View File

@@ -3,26 +3,29 @@
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"packageManager": "npm@11.6.0", "packageManager": "pnpm@10.16.1",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "npm run type-check && npm run build-only", "build": "$npm_execpath run type-check && $npm_execpath run build-only",
"build-only": "vite build", "build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", "type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "oxlint --type-aware", "lint": "oxlint --type-aware --vue-plugin",
"format": "prettier --log-level warn --write '{src/**/,}*.{ts,js,vue,html}'", "format": "prettier --log-level warn --write '{src/**/,}*.{ts,js,vue,html}'",
"test": "vitest run" "test": "vitest run"
}, },
"devDependencies": { "devDependencies": {
"@codemirror/autocomplete": "^6.0.1", "@codemirror/autocomplete": "^6.0.1",
"@codemirror/commands": "^6.0.0", "@codemirror/commands": "^6.0.0",
"@codemirror/language": "^6.11.3",
"@codemirror/lint": "^6.0.0", "@codemirror/lint": "^6.0.0",
"@codemirror/state": "^6.0.0", "@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0", "@codemirror/view": "^6.0.0",
"@headlessui/vue": "^1.6.1", "@headlessui/vue": "^1.6.1",
"@heroicons/vue": "^1.0.6", "@heroicons/vue": "^1.0.6",
"@lezer/common": "^1.2.3",
"@lezer/generator": "^1.0.0", "@lezer/generator": "^1.0.0",
"@lezer/highlight": "^1.1.6", "@lezer/highlight": "^1.1.6",
"@lezer/lr": "^1.4.2",
"@tailwindcss/typography": "^0.5.2", "@tailwindcss/typography": "^0.5.2",
"@tailwindcss/vite": "^4.1.5", "@tailwindcss/vite": "^4.1.5",
"@tsconfig/node20": "^20.1.6", "@tsconfig/node20": "^20.1.6",
@@ -32,6 +35,7 @@
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@vitejs/plugin-vue": "^6.0.0", "@vitejs/plugin-vue": "^6.0.0",
"@vitest/coverage-v8": "^3.0.4", "@vitest/coverage-v8": "^3.0.4",
"@vue/language-server": "^3.0.0",
"@vue/tsconfig": "^0.8.1", "@vue/tsconfig": "^0.8.1",
"@vueuse/core": "^13.1.0", "@vueuse/core": "^13.1.0",
"@vueuse/router": "^13.1.0", "@vueuse/router": "^13.1.0",
@@ -46,6 +50,7 @@
"sugar-date": "^2.0.6", "sugar-date": "^2.0.6",
"tailwindcss": "^4.1.5", "tailwindcss": "^4.1.5",
"typescript": "^5.6.3", "typescript": "^5.6.3",
"typescript-language-server": "^4.4.0",
"uuid": "^13.0.0", "uuid": "^13.0.0",
"vite": "npm:rolldown-vite@^7.1.9", "vite": "npm:rolldown-vite@^7.1.9",
"vitest": "^3.0.4", "vitest": "^3.0.4",
@@ -55,9 +60,5 @@
"vue-router": "^4.0.16", "vue-router": "^4.0.16",
"vue-tsc": "^3.0.1", "vue-tsc": "^3.0.1",
"vuedraggable": "^4.1.0" "vuedraggable": "^4.1.0"
},
"optionalDependencies": {
"@vue/language-server": "^3.0.0",
"typescript-language-server": "^4.4.0"
} }
} }

3903
console/frontend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
minimumReleaseAge: 4320 # 3 days

View File

@@ -15,16 +15,26 @@
}; };
l = builtins // pkgs.lib; l = builtins // pkgs.lib;
nodejs = pkgs.nodejs_20; nodejs = pkgs.nodejs_20;
pnpm = pkgs.pnpm_10;
go = pkgs.go_latest; go = pkgs.go_latest;
frontend = pkgs.buildNpmPackage.override { inherit nodejs; } { frontend = pkgs.stdenvNoCC.mkDerivation rec {
name = "akvorado-frontend"; name = "akvorado-frontend";
src = ./console/frontend; src = ./console/frontend;
npmDepsHash = l.readFile ./nix/npmDepsHash.txt; nativeBuildInputs = [
# Filter out optional dependencies nodejs
prePatch = '' pnpm.configHook
${pkgs.jq}/bin/jq 'del(.packages[] | select(.optional == true and .dev == null))' \ ];
< package-lock.json > package-lock.json.tmp
mv package-lock.json.tmp package-lock.json pnpmDeps = pnpm.fetchDeps {
inherit src;
pname = name;
buildInputs = [ nodejs ];
fetcherVersion = 2;
hash = l.readFile ./nix/npmDepsHash.txt;
};
buildPhase = ''
pnpm run build
''; '';
installPhase = '' installPhase = ''
mkdir $out mkdir $out

View File

@@ -1 +1 @@
sha256-SsBPhiozPSDQqMhz7oGlR4Q9anSfah/CZT6MT6lRXFU= sha256-4h48BXKE5yY7ZLkW2xYzybuSi6OZDVH7ziCEMfaiPIo=