From 14dcce6cdb76bbeba11640fa977a6aaa5766a653 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Mon, 16 Jun 2025 16:26:36 +0200 Subject: [PATCH 1/3] Be more specific with the vendoring, and use defered everywhere where loading JS --- .github/workflows/python-publish.yml | 8 + .gitignore | 5 +- javascript/bootstrap.customized.js | 2 + javascript/package-lock.json | 230 ++++++++++++++++++ javascript/package.json | 14 +- javascript/scss/_variables.scss | 2 - javascript/simple-repository-browser.core.js | 8 - .../simple-repository-browser.project.js | 8 - javascript/webpack.config.js | 18 +- .../templates/base/base.html | 4 +- .../templates/base/project.html | 93 +++---- 11 files changed, 319 insertions(+), 73 deletions(-) create mode 100644 javascript/bootstrap.customized.js delete mode 100644 javascript/scss/_variables.scss delete mode 100644 javascript/simple-repository-browser.core.js delete mode 100644 javascript/simple-repository-browser.project.js diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 60d2a9c..131e568 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -26,6 +26,14 @@ jobs: with: python-version: "3.x" + - uses: actions/setup-node@v4 + with: + node-version: 18 + run: | + cd javascript + npm install --include=dev + npm run build + - name: Build release distributions run: | # NOTE: put your own distribution build steps here. diff --git a/.gitignore b/.gitignore index 77fadcd..03d01b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,4 @@ -simple_repository_browser/static/js/simple-repository-browser.project.js.LICENSE.txt -simple_repository_browser/static/js/simple-repository-browser.core.js.LICENSE.txt -simple_repository_browser/static/js/simple-repository-browser.core.js -simple_repository_browser/static/js/simple-repository-browser.project.js +simple_repository_browser/static/vendored/ */_version.py node_modules diff --git a/javascript/bootstrap.customized.js b/javascript/bootstrap.customized.js new file mode 100644 index 0000000..a411b7f --- /dev/null +++ b/javascript/bootstrap.customized.js @@ -0,0 +1,2 @@ +import './scss/app.scss'; +import 'bootstrap'; diff --git a/javascript/package-lock.json b/javascript/package-lock.json index 3743821..9ebdc1e 100644 --- a/javascript/package-lock.json +++ b/javascript/package-lock.json @@ -18,6 +18,7 @@ "@fortawesome/fontawesome-free": "^5.15.4", "autoprefixer": "^10.4.0", "css-loader": "^6.5.1", + "mini-css-extract-plugin": "^2.9.2", "node-sass": "^6.0.1", "postcss-loader": "^6.2.1", "sass-loader": "^12.3.0", @@ -478,6 +479,45 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -1228,6 +1268,22 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -1955,6 +2011,79 @@ "node": ">=4" } }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2680,6 +2809,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -4115,6 +4253,35 @@ "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -4665,6 +4832,12 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true + }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -5228,6 +5401,57 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, + "mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "requires": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "dependencies": { + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + } + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5757,6 +5981,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", diff --git a/javascript/package.json b/javascript/package.json index 19c1625..5f73f06 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -4,8 +4,17 @@ "description": "A web application for a browsing a Python PEP-503 simple repository", "main": "index.js", "scripts": { - "build": "webpack", - "test": "echo \"Error: no test specified\" && exit 1" + "build": "mkdir -p ../simple_repository_browser/static/vendored; npm run -s build-bootstrap; npm run -s build-jquery; npm run -s build-fontawesome; npm run -s build-popper.js; npm run -s build-custom-bootstrap", + "build-bootstrap": "npm run -s build-bootstrap-js && npm run -s build-bootstrap-css", + "build-bootstrap-js": "cp node_modules/bootstrap/dist/js/bootstrap.bundle.min.js* ../simple_repository_browser/static/vendored/", + "build.bootstrap-css": "cp node_modules/bootstrap/dist/css/bootstrap.min.css ../simple_repository_browser/static/vendored/", + "build-jquery": "cp node_modules/jquery/dist/jquery.min.js ../simple_repository_browser/static/vendored/", + "build-fontawesome": "npm run -s build-fontawesome-core && npm run -s build-fontawesome-solid && npm run -s build-fontawesome-regular", + "build-fontawesome-core": "cp node_modules/@fortawesome/fontawesome-free/js/fontawesome.min.js ../simple_repository_browser/static/vendored/", + "build-fontawesome-solid": "cp node_modules/@fortawesome/fontawesome-free/js/solid.min.js ../simple_repository_browser/static/vendored/", + "build-fontawesome-regular": "cp node_modules/@fortawesome/fontawesome-free/js/regular.min.js ../simple_repository_browser/static/vendored/", + "build-popper.js": "cp node_modules/popper.js/dist/umd/popper.min.js ../simple_repository_browser/static/vendored/", + "build-custom-bootstrap": "webpack" }, "author": "", "license": "ISC", @@ -13,6 +22,7 @@ "@fortawesome/fontawesome-free": "^5.15.4", "autoprefixer": "^10.4.0", "css-loader": "^6.5.1", + "mini-css-extract-plugin": "^2.9.2", "node-sass": "^6.0.1", "postcss-loader": "^6.2.1", "sass-loader": "^12.3.0", diff --git a/javascript/scss/_variables.scss b/javascript/scss/_variables.scss deleted file mode 100644 index f692708..0000000 --- a/javascript/scss/_variables.scss +++ /dev/null @@ -1,2 +0,0 @@ -$base-color: #385CB4 !default; -$base-color2: #6B84C5 !default; diff --git a/javascript/simple-repository-browser.core.js b/javascript/simple-repository-browser.core.js deleted file mode 100644 index 8976db1..0000000 --- a/javascript/simple-repository-browser.core.js +++ /dev/null @@ -1,8 +0,0 @@ -import './scss/app.scss'; - -import 'popper.js'; // Needed for bootstrap tooltips. - -import 'bootstrap'; - -// Expose bootstrap, so that we can initiate some events with it (like enabling tooltips). -window.bootstrap = require('bootstrap/dist/js/bootstrap.bundle.js'); diff --git a/javascript/simple-repository-browser.project.js b/javascript/simple-repository-browser.project.js deleted file mode 100644 index fce3757..0000000 --- a/javascript/simple-repository-browser.project.js +++ /dev/null @@ -1,8 +0,0 @@ -import $ from 'jquery'; -window.jQuery = $; -window.$ = $; - - -import '@fortawesome/fontawesome-free/js/fontawesome' -import '@fortawesome/fontawesome-free/js/solid' -import '@fortawesome/fontawesome-free/js/regular' diff --git a/javascript/webpack.config.js b/javascript/webpack.config.js index 87f1c94..097cb41 100644 --- a/javascript/webpack.config.js +++ b/javascript/webpack.config.js @@ -1,25 +1,33 @@ const path = require('path'); +const miniCssExtractPlugin = require('mini-css-extract-plugin') + module.exports = { entry: { - 'simple-repository-browser.core.js': './simple-repository-browser.core.js', - 'simple-repository-browser.project.js': './simple-repository-browser.project.js', + 'bootstrap.customized.js': './bootstrap.customized.js', }, output: { filename: '[name]', - path: path.resolve(__dirname, '../simple_repository_browser/static/js/') + path: path.resolve(__dirname, '../simple_repository_browser/static/vendored/') }, resolve: { extensions: [".ts", ".js"], }, + plugins: [ + new miniCssExtractPlugin() + ], module: { rules: [ { test: /\.(scss)$/, use: [ + // { + // // Adds CSS to the DOM by injecting a `