Importing assets
Nebula uses Vite to import assets into the frontend. Vite is a frontend build tool that is used to build the frontend assets. Vite is also used to serve the frontend assets during development.
Project structure
The frontend assets are located in the nebula/src
directory. The nebula/src
directory is structured as follows:
📦nebula/src
┣ 📂js
┣ 📂public
┃ ┣ 📂images
┃ ┗ 📂js
┣ 📂scss
The nebula/src/js
directory contains TypeScript
and Vue
files that are used to build the frontend.
The nebula/src/public
directory contains assets that are used directly by the frontend.
The nebula/src/scss
directory contains SCSS
files that are used to build the frontend styling.
Note
The nebula/src/public
directory is copied as is to the nebula/static
directory during production.
Importing assets in html
and jinja
Note
This is only used in nebula/templates/index.html
to load the Vue
app. And likely won’t need to be changed or used anywhere else.
However, since this is a non-standard way of importing assets, it is documented here.
Assets in html
and jinja
files need to import from different directories depending on the environment. During development, the assets are served by the Vite webserver
. During production, the assets are built by Vite
and are located in the nebula/static
directory.
To help with this difference, the vite
template is used to import assets. The vite
template is located at nebula/templates/utilities/vite.html
.
Usage
The vite
template provides the following functions: vite_script
, vite_style
, vite_asset
and vite_public_asset
. They can be imported as follows:
{% from 'utilities/vite.html' import vite_script with context %}
vite_script
Imports a script. If the script imports any other assets, they will be imported as well.
param: source
- The path to the script relative to the nebula/src
directory.
Input:
{{ vite_script('js/main.ts') }}
Output:
<script type="module" src="http://localhost:5173/js/main.ts"></script>
<script type="module" src="/static/js/main.js"></script>
<link rel="stylesheet" href="/static/main.css"></link>
vite_style
Imports a style.
param: source
- The path to the style relative to the nebula/src
directory.
Input:
{{ vite_style('scss/main.scss') }}
Output:
<link rel="stylesheet" href="http://localhost:5173/scss/main.scss" />
<link rel="stylesheet" href="/static/main.css"></link>
vite_asset
Imports an asset. The asset will be imported as is.
param: source
- The path to the asset relative to the nebula/src
directory.
Input:
{{ vite_asset('js/main.js') }}
Output:
http://localhost:5173/js/main.js
/static/js/main.js
vite_public_asset
Imports a public asset. The asset will be imported as is. When importing a public asset, this function should be used instead of vite_asset
. This is because public assets are served from a different location.
param: source
- The path to the asset relative to the nebula/src/public
directory.
Input:
{{ vite_public_asset('images/logo.svg') }}
Output:
http://localhost:5173/images/logo.svg
/static/images/logo.svg
utilities/vite.html
{% macro vite_script(source) -%}
{% if development %}
<script type="module" src="{{'http://localhost:5173/nebula/src/' + source }}"></script>
{% else %}
<script type="module"
src="{{ url_for('static', filename=(manifest['nebula/src/' + source]['file'])) }}"></script>
{% if manifest['nebula/src/' + source]['css'] %}
{% for css in manifest['nebula/src/' + source]['css'] %}
<link rel="stylesheet" href="{{ url_for('static', filename=css) }}">
{% endfor %}
{% endif %}
{% endif %}
{% endmacro %}
{% macro vite_style(source) -%}
{% if development %}
<link rel="stylesheet" href={{'http://localhost:5173/nebula/src/' + source}}>
{% else %}
<link rel="stylesheet"
href="{{ url_for('static', filename=(manifest['nebula/src/' + source]['file'])) }}">
{% endif %}
{% endmacro %}
{% macro vite_asset(source) -%}
{% if development %}
{{'http://localhost:5173/nebula/src/' + source }}
{% else %}
{{ url_for('static', filename=(manifest['nebula/src/' + source]['file'])) }}
{% endif %}
{% endmacro %}
{% macro vite_public_asset(source) -%}
{% if development %}
{{'http://localhost:5173/' + source }}
{% else %}
{{ url_for('static', filename=source) }}
{% endif %}
{% endmacro %}
Importing assets in TypeScript
and Vue
Assets in TypeScript
and Vue
files can just be imported the same way as in any other TypeScript
or Vue
project. Vite will handle the import depending on the environment.
// Import a script from a node module
import { createApp } from "vue";
// Import a local script
import App from "@/App.vue";
// Import a style
import "@scss/main.scss";
// Import an asset
import logo from "@public/images/logo.svg";
Aliases
A few aliases are available to make it easier to import assets. The aliases are defined in nebula/src/js/vite.config.ts
.
Creating a new alias is as simple as adding a new entry to the resolve.alias
object in vite.config.ts
and adding it to "compilerOptions"."paths"
in tsconfig.json
.
Adding the alias to vite.config.ts
ensures that the alias will work in TypeScript
and Vue
files.
Adding the alias to tsconfig.json
will allow editors to resolve the alias.
// vite.config.ts
export default defineConfig({
resolve: {
alias: {
// ...
"@": path.resolve(__dirname, "./nebula/src/js"),
"@public": path.resolve(__dirname, "./nebula/src/public"),
"@scss": path.resolve(__dirname, "./nebula/src/scss"),
// ...
},
},
});
// tsconfig.json
{
"compilerOptions": {
// ...
"paths": {
// ...
"@/*": ["nebula/src/js/*"],
"@public/*": ["nebula/src/public/*"],
"@scss/*": ["nebula/src/scss/*"]
// ...
}
// ...
}
}