Merge branch 'build/enforce_node_version' into 'v3'

ui_migration upgrade NodeJS version 26 and configurations

Closes #732

See merge request openflexure/openflexure-microscope-server!550
This commit is contained in:
Julian Stirling 2026-05-23 17:18:32 +00:00
commit 710883cff5
7 changed files with 951 additions and 2016 deletions

View file

@ -18,7 +18,7 @@ include:
.javascript_webapp: .javascript_webapp:
extends: .javascript extends: .javascript
variables: variables:
JS_IMAGE: node:20 JS_IMAGE: node:26
JS_PATH: webapp JS_PATH: webapp
JS_CACHE_PATH: webapp/node_modules JS_CACHE_PATH: webapp/node_modules

View file

@ -11,11 +11,22 @@
_Note: If you are using a Windows OS, the following commands must be executed in a Powershell terminal._ _Note: If you are using a Windows OS, the following commands must be executed in a Powershell terminal._
* Install Node.js v18 (and npm) * [Get Node.js v26 using the official installation scripts for your operating system.](https://nodejs.org/en/download/current)
* [Get Node.js v26 using the official installation scripts for your operating system.](https://nodejs.org/en/download/current) *(Optionally, you can instead install NVM as explained below)*.
* Navigate into the webapp directory with `cd webapp` * Navigate into the webapp directory with `cd webapp`
* Install dependencies with `npm install` * Install dependencies with `npm install`
* Build the static web app with `npm run build` * Build the static web app with `npm run build`
#### ( Optional ) Using NVM "Node-Version-Manager"
If you have multiple projects that use different versions of Node.JS you can install Node Version Manager (NVM) to allow you to switch version from the terminal. To use NVM:
* [Install NVM](https://www.nvmnode.com/guide/installation.html)
* Install Node.js v26 with `nvm install 26`
* Set the Node.js to version 26 with `nvm use 26`
## Live Server ## Live Server
When developing it is useful to use the development server so Vue changes happen instantly without the need to rebuild. To start the development server run: When developing it is useful to use the development server so Vue changes happen instantly without the need to rebuild. To start the development server run:

2874
webapp/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
"description": "User interface for the OpenFlexure Microscope Server", "description": "User interface for the OpenFlexure Microscope Server",
"author": "OpenFlexure <contact@openflexure.org> (https://www.openflexure.org)", "author": "OpenFlexure <contact@openflexure.org> (https://www.openflexure.org)",
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=26.0.0"
}, },
"scripts": { "scripts": {
"gv": "genversion src/version.js", "gv": "genversion src/version.js",
@ -19,44 +19,47 @@
"test:unit": "NODE_OPTIONS=--expose-gc vitest run src/tests/unit/ --no-cache --mode test --detectAsyncLeaks --coverage --isolate=true --pool=forks --silent --logHeapUsage" "test:unit": "NODE_OPTIONS=--expose-gc vitest run src/tests/unit/ --no-cache --mode test --detectAsyncLeaks --coverage --isolate=true --pool=forks --silent --logHeapUsage"
}, },
"dependencies": { "dependencies": {
"@vueuse/core": "^14.1.0", "@vueuse/core": "^14.3.0",
"axios": "^1.7.7", "axios": "^1.16.1",
"material-design-icons": "^3.0", "material-symbols": "^0.44.8",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"mousetrap": "^1.6.5", "mousetrap": "^1.6.5",
"openseadragon": "^5.0.0", "openseadragon": "^5.0.0",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"pinia-plugin-persistedstate": "^4.7.1", "pinia-plugin-persistedstate": "^4.7.1",
"uikit": "^3.24.2", "uikit": "^3.25.16",
"vue": "^3.4.0" "vue": "^3.5.34"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.28.5", "@eslint/js": "^10.0.1",
"@pinia/testing": "^1.0.3", "@pinia/testing": "^1.0.3",
"@vitejs/plugin-vue": "^6.0.6", "@vitejs/plugin-vue": "^6.0.7",
"@vitest/coverage-v8": "^4.1.6", "@vitest/coverage-v8": "^4.1.7",
"@vue/eslint-config-prettier": "9.0.0", "@vue/eslint-config-prettier": "10.2.0",
"@vue/test-utils": "^2.4.10", "@vue/test-utils": "^2.4.10",
"autoprefixer": "^10.4.24", "autoprefixer": "^10.5.0",
"core-js": "^3.46.0", "core-js": "^3.49.0",
"cross-env": "^10.1.0", "cross-env": "^10.1.0",
"eslint": "^9.39.2", "eslint": "^10.4.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-pinia": "^0.4.2", "eslint-plugin-pinia": "^0.4.2",
"eslint-plugin-prettier": "^5.5.5", "eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-vue": "^9.20.0", "eslint-plugin-vue": "^10.9.1",
"globals": "^17.6.0",
"happy-dom": "^20.9.0", "happy-dom": "^20.9.0",
"less": "^4.5.1", "less": "^4.6.4",
"material-symbols": "^0.39.1",
"postcss-html": "^1.8.1", "postcss-html": "^1.8.1",
"postcss-less": "^6.0.0", "postcss-less": "^6.0.0",
"prettier": "^3.2.8", "prettier": "^3.8.3",
"stylelint": "^17.11.0", "stylelint": "^17.12.0",
"stylelint-config-standard": "^40.0.0", "stylelint-config-standard": "^40.0.0",
"stylelint-config-standard-less": "^4.1.0", "stylelint-config-standard-less": "^4.1.0",
"typescript-eslint": "^8.59.0", "typescript-eslint": "^8.59.4",
"vite": "^7.3.1", "vite": "^8.0.13",
"vitest": "^4.1.6" "vitest": "^4.1.7"
},
"overrides": {
"glob": "12.0"
}, },
"postcss": { "postcss": {
"plugins": { "plugins": {

View file

@ -58,7 +58,7 @@ export default {
...mapActions(useSettingsStore, ["resetState"]), ...mapActions(useSettingsStore, ["resetState"]),
...mapActions(useWotStore, ["deleteAllThingDescriptions"]), ...mapActions(useWotStore, ["deleteAllThingDescriptions"]),
systemRequest: function (action) { systemRequest: function (action) {
let message = ""; let message;
if (action == "reboot") { if (action == "reboot") {
message = "Restart microscope?"; message = "Restart microscope?";
} else { } else {

View file

@ -40,6 +40,9 @@ export default defineConfig(({ command, mode }) => {
? [ ? [
(node) => { (node) => {
// Check if the current AST node is an HTML element // Check if the current AST node is an HTML element
// Node.type 1 is equal to node.type ELEMENT
// https://developer.mozilla.org/es/docs/Web/API/Node/nodeType
// https://developer.mozilla.org/es/docs/Web/API/Element
if (node.type === 1) { if (node.type === 1) {
// Filter out any property named "data-test-id" // Filter out any property named "data-test-id"
node.props = node.props.filter((prop) => prop.name !== "data-test-id"); node.props = node.props.filter((prop) => prop.name !== "data-test-id");
@ -60,11 +63,27 @@ export default defineConfig(({ command, mode }) => {
chunkSizeWarningLimit: 400, chunkSizeWarningLimit: 400,
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks: { manualChunks(id) {
"vue-vendor": ["vue", "pinia", "pinia-plugin-persistedstate"], // Only split out third-party dependencies from node_modules
openseadragon: ["openseadragon"], if (id.includes("node_modules")) {
uikit: ["uikit"], if (id.includes("vue") || id.includes("pinia")) {
utils: ["axios", "mitt", "mousetrap", "@vueuse/core"], return "vue-vendor";
}
if (id.includes("openseadragon")) {
return "openseadragon";
}
if (id.includes("uikit")) {
return "uikit";
}
if (
id.includes("axios") ||
id.includes("mitt") ||
id.includes("mousetrap") ||
id.includes("@vueuse")
) {
return "utils";
}
}
}, },
}, },
}, },

View file

@ -61,7 +61,7 @@ export default defineConfig({
optimizer: { optimizer: {
web: { web: {
enabled: true, enabled: true,
include: ["uikit", "openseadragon", "material-design-icons"], include: ["uikit", "openseadragon", "material-symbols"],
}, },
}, },
}, },