# @soleil-se/build-app

Skript för att bygga WebApps 2, RESTApps och Widgets med Svelte.

> **Breaking changes från version 1**
>
> **WebApps 1**\
> Stödet för att bygga WebApps 1 är borttaget, om man fortfarande behöver bygga en äldre app använd version 1.\
> Vi rekommenderar att gå över till WebApps 2, då behöver även `@soleil-se/app-util` uppdateras till version 5, läs [migreringsguiden](/packages/app-util/migration/).
>
> **Alias**\
> Från version 2 används `project_config.json` för att sätta alias och standardalias är borttagna, läs mer under [Alias](#alias).
>
> **Importer av Sitevision API:er**\
> Sitevision API:er måste importeras med `@sitevision/api`.

## Nyheter

[Stöd för att bygga appar av typen MCP Server](https://developer.sitevision.se/docs/mcp-server)2026-05-21

[Stöd för att bygga appar utan en main.js-fil](/build/app/no-main-js)2025-10-06

[Stöd för TypeScript](#typescript)2025-09-26

## Kom igång

Läs vår guide om hur man [kommer igång med Svelte](/sitevision/svelte/)!

## Installation

Skriptet installeras **lokalt** i appen.

```sh
npm install @soleil-se/build-app --save-dev
```

## Skript

Lägg till följande skript i `package.json`:

**package.json**

```json
{
  "scripts": {
    "build": "build-app build",
    "watch": "build-app watch",
    "start": "build-app start",
    "deploy": "build-app deploy"
  }
}
```

* `build`: Bygger ihop appen utan att ladda upp.
* `watch`: Startar en watcher, när någon av de filer som loggas vid uppstart ändras byggs appen ihop och laddas upp till default miljön eller den miljö som anges i `--env` argumentet.
* `start`: Bygger först ihop och laddar upp appen till default miljön eller den miljö som anges i `--env` argumentet, därefter startas en watcher.
* `deploy`: Bygger ihop, signerar och laddar upp appen till default miljön eller den miljö som anges i `--env` argumentet.

Innan 1.11.0**

Använder man en äldre version än 1.11.0 lägg då till följande skript i `package.json` istället:

**package.json**

```json
{
  "scripts": {
    "build": "build-app --no-sync",
    "watch": "build-app --watch",
    "start": "build-app --build --watch",
    "deploy": "build-app --sign",
  }
}
```

## Styling preprocessor

Om en preprocessor används för styling (vanligtvis Sass) behöver denna installeras lokalt i appen eller i projektets rotkatalog.

```sh
npm install sass --save-dev
```

## Struktur

Största skillnaden från Sitevisions standardstruktur är att appens konfiguration ligger i egna kataloger.

WebApp**

* config Konfiguration för appen.

  * App.svelte Huvudkomponent för konfigurationen
  * config.js Klientkod för konfigurationen
  * index.js Serverkod för konfigurationen

* config\_global Global konfiguration för appen

  * App.svelte Huvudkomponent för globala konfigurationen
  * config.js Klientkod för globala konfigurationen
  * index.js Serverkod för globala konfigurationen

* src

  * client/ Klientspecifik kod

    * …

  * common/ Universell kod

    * …

  * components/ Komponenter

    * …

  * server/ Serverspecifik kod

    * …

  * resource/ Mapp för appens resurser

    * …

  * App.svelte Huvudkomponent för appen

  * index.js Serverkod för appen

  * hooks.js Pre render hooks

  * main.js Klientkod för appen

  * appDataDefaults.json Defaultvärden för konfiguration

* jsconfig.json

* manifest.json

* package.json

* svelte.config.json

RESTApp**

* config Konfiguration för appen.

  * App.svelte Huvudkomponent för konfigurationen
  * config.js Klientkod för konfigurationen
  * index.js Serverkod för konfigurationen

* src

  * api/ Kod för appen

    * …

  * resource/ Appens resurser

    * …

  * index.js Serverkod för appen

  * appDataDefaults.json Defaultvärden för konfiguration

* jsconfig.json

* manifest.json

* package.json

* svelte.config.json

Det går även att använda [samma filer som Sitevision](https://developer.sitevision.se/docs/webapps/webapps-2/configuration) för enklare konfigurationer.

Sitevision konfiguration**

* config Konfiguration för appen

  * index.html
  * index.js
  * config.js
  * config.css

* config\_global Global konfiguration för appen.

  * index.html
  * index.js
  * config.js
  * config.css

* src/

  * …

* jsconfig.json

* manifest.json

* package.json

* svelte.config.json

## Inställningar

Skriptet använder följande inställningar:

* [Miljö](/build/config/#milj%C3%B6)
* [Browserslist](/build/config/#browserslist)
* [Globals](/build/config/#globals)
* [PostCSS](/build/config/#postcss)

## Signering

I `user_config.json` anger man vilken användare och vilket certifikat som ska användas vid signering av appar.

* `auth` - En base64-enkodad sträng med formatet `username:password`.
* `certificate` - Namn på certifikatet som ska användas vid signering.

**user\_config.json**

```json
{
  "webappSign": {
    "auth": "dXNlcm5hbWU6cGFzc3dvcmQ=",
    "certificate": "Soleil"
  }
}
```

## Manifest

Information om appen, se till att `bundled` är satt till `true` för att använda WebApps 2. Läs mer om [manifest.json](https://developer.sitevision.se/docs/webapps/webapps-2/manifest) på Sitevisions utvecklarwebb.

**manifest.json**

```json
{
  "id": "se.soleil.myApp",
  "version": "1.0.0",
  "name": "Namn på app",
  "author": "Soleil AB",
  "description": "Beskrivning av app.",
  "helpUrl": "",
  "type": "WebApp",
  "bundled": true
}
```

### Flerspråkiga namn 1.4.0

I Sitevision 10.1 introducerades stöd för [flerspråkiga namn på appar](https://developer.sitevision.se/archives/developer-news/developer-news/2022-01-28-multilingual-webapp-names).

Som standard kommer det svenska namnet (`name.sv` i `manifest.json`) att användas för själva tillägget i `sv:addonRepository`. Behöver man ändra detta kan man ange ett annat språk under `addonNameLang` i `project_config.json`.

**project\_config.json**

```json
{
  "env": { ... },
  "addonNameLang": "en"
}
```

## Svelte config

I filen `svelte.config.js` anger man inställningar för preprocessing och kompilatorn.

Som standard har filen följande inställningar när en ny app skapas.

* Svelte preprocessing med `svelte-preprocess` utan några specifika inställningar är aktiverat.
* Vissa Svelte varningar ignoreras.
  * `state_referenced_locally` - Är för det mesta inte ett problem då den oftast klagar på props som kommer från servern.

**svelte.config.js**

```js
import { sveltePreprocess } from 'svelte-preprocess';


const ignoredWarnings = ['state_referenced_locally'];


export default {
  preprocess: sveltePreprocess(),
  compilerOptions: {
    warningFilter(warning) {
      return !ignoredWarnings.includes(warning.code);
    },
  },
};
```

Exempel för att ändra inkluderade sökvägar för Sass och slå på inställningen `preserveWhitespace` i kompilatorn.

**svelte.config.js**

```js
import { sveltePreprocess } from 'svelte-preprocess';


const ignoredWarnings = ['state_referenced_locally'];


export default {
  preprocess: sveltePreprocess({
    scss: { includePaths: [`${import.meta.dirname}/../../../../client_src/sass`] },
  }),
  compilerOptions: {
    preserveWhitespace: true,
    warningFilter(warning) {
      return !ignoredWarnings.includes(warning.code);
    },
  },
};
```

[Läs mer om preprocessing](https://github.com/sveltejs/svelte-preprocess#readme).

[Läs mer om kompilatorinställningar](https://svelte.dev/docs#compile-time-svelte-compile).

## Argument

* `--no-eslint` - Stänger av linting av kod.
* `--no-sync` - Stänger av uppladdning till Sitevision.
* `--no-cache` - Stänger av cachning av kod när appen byggs ihop.
* `--force` - Forcerar uppladdning av app.
* `--debug` - Stänger av minifiering för enklare felsökning.
* `--sign` - Signerar alltid appen.
* `--activate` - Aktiverar appen vid uppladdning.
* `--append-watch` - Lägger till sökväg för watchern, glob mönster är tillåtna, ex `npm run start -- --append-watch ../common`.
* `--ignore-watch` - Ignorerar sökväg för watchern, glob mönster är tillåtna, ex `npm run start -- --ignore-watch src/ignore.js`.

Följande argument är deprekerade och kommer att tas bort i framtida versioner:

* `--watch` (DEPRECATED) - Startar övervakning av filer och bygger ihop appen vid förändringar.
* `--build` (DEPRECATED) - Bygger alltid appen vid uppstart, även med `--watch`.

## Alias

Det finns möjlighet att sätta upp alias för Rollup för att slippa långa relativa sökvägar.\
Alias prefixas med ett `#` för att vara lättare att urskilja.

```js
import doSomething from '#api/doSomething';
```



* Version 2

  Alias definieras i `project_config.json`.\
  Utgångspunkten för alias är den katalog där `project_config.json` ligger.

  **project\_config.json**

  ```json
  {
    "rollup": {
      "server": {
        "alias": {
          "#api": "./server/api",
        }
      },
      "client": {
        "alias": {
          "#api": "./client/api",
        }
      }
    }
  }
  ```

* Version 1

  Utgångspunkten för alias är den katalog där `project_config.json` ligger.

  På serversidan finns följande alias uppsatta som standard:

  ```javascript
  {
    '#api': './server_src/api',
    '#api/webapps': './server_src/webapps/api',
    '#api/restapps': './server_src/restapps/api',
    '#components': './server_src/webapps/components',
  }
  ```

  På klientsidan finns följande alias uppsatta som standard:

  ```javascript
  {
    '#api': './server_src/api',
    '#api/webapps': './server_src/webapps/api',
    '#components': './server_src/webapps/components',
  }
  ```

  Det går att definera egna alias i `project_config.json`.

  **project\_config.json**

  ```json
  {
    "rollup": {
      "server": {
        "alias": {
          "#myAlias": "./some/path"
        }
      },
      "client": {
        "alias": {
          "#myOtherAlias": "./some/other/path"
        }
      }
    }
  }
  ```

## TypeScript2.4.0

Det finns från och med version 2.4.0 stöd för TypeScript.

* [TypeScript i Sitevision](https://developer.sitevision.se/docs/webapps/typescript)
* [TypeScript i Svelte](https://svelte.dev/docs/typescript)

### Kom igång

1. Installera beroenden

   Installera senaste versionen av `@soleil-se/build-app` samt de beroenden som krävs för att bygga och linta TypeScript-kod.

   ```sh
   npm i @soleil-se/build-app@^2.4.0 typescript @soleil-se/eslint-config@^6.2.6 typescript-eslint eslint-import-resolver-typescript --save-dev
   ```

2. Skapa tsconfig.json

   Skapa en `tsconfig.json` i appens rotkatalog med följande innehåll.\
   Ta bort `jsconfig.json` om den finns.

   **tsconfig.json**

   ```json
   {
     "exclude": ["node_modules", "dist"],
     "compilerOptions": {
       "target": "ES2022",
       "module": "ES2022",
       "esModuleInterop": true,
       "forceConsistentCasingInFileNames": true,
       "strict": true,
       "skipLibCheck": true,
       "lib": ["ES2022", "DOM"],
       "moduleResolution": "node",
       "outDir": "dist",
       "verbatimModuleSyntax": true,
       "isolatedModules": true,
       "allowJs": true
     }
   }
   ```

3. Uppdatera ESLint-config

   Byt ut importen i ESLint-konfigurationen till den som stödjer TypeScript.

   **eslint.config.js**

   ```js
   import config from '@soleil-se/eslint-config';
   import config from '@soleil-se/eslint-config/typescript';


   export default [
       ...config,
   ];
   ```

   Man behöver även uppdatera inställningen `eslint.validate` i VS Code för att linta TypeScript.

   **settings.json**

   ```json
     "eslint.validate": ["javascript", "javascriptreact", "svelte"],
     "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact", "svelte"],
   ```

4. Uppdatera filändelse på ingångspunkter

   Byt filändelse på ingångspunkterna i appen till `.ts`. \_ `src/index.js` → `src/index.ts` \_ `src/main.js` → `src/main.ts` \* `src/hooks.js` → `src/hooks.ts`

5. Uppdatera main.ts

   Om du har en `src/main.ts` uppdatera den med följande typer för default exporten.

   **src/main.ts**

   ```ts
   import { render } from '@soleil-se/app-util/client/svelte/5';
   import App from './App.svelte';


   export default (props, target) => {
   export default (props: Record<string, unknown>, target: HTMLElement) => {
       render(App, { props, target });
   };
   ```

6. Starta byggskript

   Starta byggskriptet som vanligt, läs mer om [TypeScript i Sitevision](https://developer.sitevision.se/docs/webapps/typescript#h-Howtouse)

   ```sh
   npm run start
   ```

### Typning av Svelte i VS Code

För att typning av Svelte komponenter ska fungera korrekt, slå på “Svelte for VS Code”-tilläggets TS-plugin i användarinställningarna.

**settings.json**

```json
"svelte.enable-ts-plugin": true
```

### Typning av appData och globalAppData

Man kan använda [appData](/packages/app-util/server/app-data/) och [globalAppData](/packages/app-util/server/global-app-data/) från `@soleil-se/app-util` för bättre typning av en apps konfiguration och slippa casting av typer.

**src/index.ts**

```ts
import appData from '@sitevision/api/server/appData';
import appData from '@soleil-se/app-util/server/app-data';


const myString = appData.get('myStringKey') as string;
const myNumber = appData.get('myNumberKey') as number;
const myBoolean = appData.get('myBooleanKey') as boolean;
const myArray = appData.getArray('myStringArrayKey') as string[];
const myString = appData.getString('myStringKey');
const myNumber = appData.getNumber('myNumberKey');
const myBoolean = appData.getBoolean('myBooleanKey');
const myArray = appData.getStrings('myStringArrayKey');
```

### Typning av Props

Vill man få med typning för props i både `src/index.ts` och `src/main.ts` kan man exportera denna från `src/App.svelte` och använda i `src/index.ts` och `src/main.ts`.

**src/App.svelte**

```svelte
<script module lang="ts">
  export type Props = {
    message: string;
  };
</script>


<script lang="ts">
  let { message }: Props = $props();
</script>


<p>{message}</p>


<style lang="scss">
  p {
    color: black;
  }
</style>
```

**src/index.ts**

```ts
import router from '@sitevision/api/common/router';
import appData from '@soleil-se/app-util/server/app-data';
import { render } from '@soleil-se/app-util/server/svelte/5';


import App, { type Props } from './App.svelte';


router.get('/', (req, res) => {
  const props: Props = {
    message: appData.getString('message'),
  };
  const html = render(App, props);
  res.agnosticRender(html, props);
});
```

**src/main.ts**

```ts
import { render } from '@soleil-se/app-util/client/svelte/5';


import App, { type Props } from './App.svelte';


export default (props: Props, target: HTMLElement) => {
  render(App, { props, target });
};
```