Skip to content
Snippets Groups Projects
Verified Commit be8f2649 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Allow running vite build from anywhere

parent 45f8c0ed
No related branches found
No related tags found
1 merge request!1123Resolve "Finalise Vuetify app as SPA"
Pipeline #108306 failed
......@@ -39,6 +39,11 @@ def write_vite_values(out_path: str) -> dict[str, Any]:
# Add core entrypoint
vite_values["coreAssetDir"] = os.path.join(settings.BASE_DIR, "aleksis", "core", "frontend")
# Add directories
vite_values["baseDir"] = settings.BASE_DIR
vite_values["cacheDir"] = settings.CACHE_DIR
vite_values["node_modules"] = settings.JS_ROOT
with open(out_path, "w") as out:
json.dump(vite_values, out)
......
// Configuration for Vite bundling
//
// This config is somewhat elaborate, because it needs to dynamically address
// the several environments where it is used. The AlekSIS frontend bundle is
// always created as a custom asset for a given Django deployment, in order
// to allow for dynamic addition of frontend code from AlekSIS apps.
//
// It is therefore also placed inside the Python package structure, so it
// will be installed into the target system/image by poetry.
//
// Hence, the main scenarios are:
//
// * called directly from the source tree of AlekSIS-Core, with
// cache dir (and thus node_module) in ./cache
// * called from basically anywhere, with the cace dir also anywhere
//
// Vite must always be called through the `aleksis-admin vite` wrapper, which
// generates a JSON file with some hints in the cache directory, so we can
// make Vite find all the puzzle pieces.
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const process = require("process");
import { defineConfig, searchForWorkspaceRoot } from "vite";
import vue from "@vitejs/plugin-vue2";
......@@ -10,8 +31,12 @@ import virtual from "@rollup/plugin-virtual";
import { VitePWA } from "vite-plugin-pwa";
const license = require("rollup-plugin-license");
// Read the hints writen by `aleksis-admin vite`
const django_values = JSON.parse(fs.readFileSync("./django-vite-values.json"));
/**
* Generate code to import messages from a single AlekSIS app.
*/
function generateMessageImportCode(assetDir, name, importAppName) {
let code = "";
let messagesPath = assetDir + "/messages/";
......@@ -27,6 +52,12 @@ function generateMessageImportCode(assetDir, name, importAppName) {
return code;
}
/**
* Generate a virtual module that helps the AlekSIS-Core frontend code import other apps.
*
* App code locations are discovered by the `aleksis-admin` vite wrapper and passed
* in the django_values hints.
*/
function generateAppImporter(appDetails) {
let code = "let appObjects = {};\n";
code += "let appMessages = {};\n";
......@@ -59,7 +90,10 @@ function generateAppImporter(appDetails) {
}
export default defineConfig({
root: path.resolve(".."),
// root must always be the base directory of the AlekSIS-Core source tree
// Changing this will mangle the manifest key of the entrypoint!
root: django_values.baseDir,
// Base URL needs to mimic the /static/ URL in Django
base: django_values.static_url,
build: {
outDir: path.resolve("./vite_bundles/"),
......@@ -109,7 +143,7 @@ export default defineConfig({
},
fs: {
allow: [
searchForWorkspaceRoot(path.resolve("..")),
searchForWorkspaceRoot(path.resolve(django_values.baseDir)),
...Object.values(django_values.appDetails).map(
(details) => details.assetDir
),
......@@ -118,12 +152,15 @@ export default defineConfig({
},
plugins: [
virtual({
// Will be used in AlekSIS-Core frontend code to import aps
aleksisAppImporter: generateAppImporter(django_values.appDetails),
}),
vue(),
nodeResolve({ modulePaths: [path.resolve("./node_modules")] }),
nodeResolve({ modulePaths: [path.resolve(django_values.node_modules)] }),
graphql(),
license({
// A package.json will be written here by `aleksis-admin vite`
cwd: path.resolve(django_values.cacheDir),
banner: {
commentStyle: "ignored",
content: `Frontend bundle for AlekSIS\nSee ./vendor.LICENSE.txt for copyright information.`,
......@@ -135,7 +172,9 @@ export default defineConfig({
failOnViolation: true,
},
output: {
file: path.resolve("./vite_bundles/assets/vendor.LICENSE.txt"),
file: path.resolve(
django_values.cacheDir + "/vite_bundles/assets/vendor.LICENSE.txt"
),
},
},
}),
......@@ -241,8 +280,8 @@ export default defineConfig({
],
resolve: {
alias: {
"@": path.resolve("./node_modules"),
vue: path.resolve("./node_modules/vue/dist/vue.esm.js"),
"@": path.resolve(django_values.node_modules),
vue: path.resolve(django_values.node_modules + "/vue/dist/vue.esm.js"),
},
},
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment