@kopflos-cms/vite 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/index.d.ts +29 -24
- package/index.js +87 -47
- package/lib/config.d.ts +9 -2
- package/lib/config.js +7 -4
- package/package.json +3 -3
- package/template.d.ts +1 -1
- package/template.js +20 -21
- package/lib/log.d.ts +0 -1
- package/lib/log.js +0 -2
- package/lib/server.d.ts +0 -2
- package/lib/server.js +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @kopflos-cms/vite
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5ca6fa4: Resolve `configPath` against the kopflos' base path
|
|
8
|
+
|
|
9
|
+
## 0.3.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- c1a1f48: Plugin configuration: `root`/`entrypoints`/`outDir` options moved to `build`, which can be single object or an array. If absent, nothing will be built. This way multiple builds can be configured.
|
|
14
|
+
- c1a1f48: `@kopflos-cms/vite/template.js` now does not require a previous step but loads a file provided in argument. The file path will be resolved against the correct root/build path depending on running `dev`/prod` environment
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- c1a1f48: Plugin authors can now derive from `VitePlugin` to provide build configurations
|
|
19
|
+
- c1a1f48: Build: `entrypoints` will be resolved against the `root` option of its respective build configuration
|
|
20
|
+
- c1a1f48: Updated `@zazuko/env` to v3
|
|
21
|
+
|
|
3
22
|
## 0.2.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/index.d.ts
CHANGED
|
@@ -2,34 +2,39 @@ import type { Kopflos, KopflosEnvironment, KopflosPlugin } from '@kopflos-cms/co
|
|
|
2
2
|
import express from 'express';
|
|
3
3
|
import type { InlineConfig, ViteDevServer } from 'vite';
|
|
4
4
|
export { defineConfig } from 'vite';
|
|
5
|
-
export interface
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
root?: string;
|
|
5
|
+
export interface BuildConfiguration {
|
|
6
|
+
root: string;
|
|
7
|
+
entrypoints: string[];
|
|
9
8
|
outDir?: string;
|
|
10
|
-
entrypoints?: string[];
|
|
11
|
-
}
|
|
12
|
-
interface VitePlugin extends KopflosPlugin {
|
|
13
|
-
viteDevServer?: ViteDevServer;
|
|
14
9
|
}
|
|
15
10
|
declare module '@kopflos-cms/core' {
|
|
16
|
-
interface PluginConfig {
|
|
17
|
-
'@kopflos-cms/vite'?: Options;
|
|
18
|
-
}
|
|
19
11
|
interface Plugins {
|
|
20
|
-
'@kopflos-cms/vite':
|
|
12
|
+
'@kopflos-cms/vite': DefaultPlugin;
|
|
21
13
|
}
|
|
22
14
|
}
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
readonly
|
|
26
|
-
private readonly
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
beforeMiddleware(host: express.Router, { env }: Kopflos): Promise<void>;
|
|
34
|
-
build(env: KopflosEnvironment): Promise<void>;
|
|
15
|
+
export declare abstract class VitePlugin implements KopflosPlugin {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
protected readonly buildConfigurations: Array<BuildConfiguration>;
|
|
18
|
+
private readonly log;
|
|
19
|
+
private _viteDevServer;
|
|
20
|
+
protected constructor(name: string, buildConfigurations: Array<BuildConfiguration>);
|
|
21
|
+
protected getDefaultPlugin(plugins: readonly KopflosPlugin[]): DefaultPlugin;
|
|
22
|
+
protected getViteDevServer(env: KopflosEnvironment, vitePlugin: DefaultPlugin, options: BuildConfiguration): Promise<ViteDevServer>;
|
|
23
|
+
private createConfig;
|
|
24
|
+
private resolveOutDir;
|
|
25
|
+
beforeMiddleware(host: express.Router, { env, plugins }: Kopflos): Promise<void>;
|
|
26
|
+
build(env: KopflosEnvironment, plugins: readonly KopflosPlugin[]): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
interface DefaultPluginOptions {
|
|
29
|
+
build?: Array<BuildConfiguration> | BuildConfiguration;
|
|
30
|
+
configPath?: string;
|
|
31
|
+
config?: InlineConfig;
|
|
32
|
+
}
|
|
33
|
+
export default class DefaultPlugin extends VitePlugin {
|
|
34
|
+
readonly config: InlineConfig | undefined;
|
|
35
|
+
readonly configPath: string | undefined;
|
|
36
|
+
readonly buildConfiguration?: BuildConfiguration;
|
|
37
|
+
constructor({ build, config, configPath }: DefaultPluginOptions);
|
|
38
|
+
protected getDefaultPlugin(): this;
|
|
39
|
+
getDefaultViteDevServer(env: KopflosEnvironment): Promise<ViteDevServer>;
|
|
35
40
|
}
|
package/index.js
CHANGED
|
@@ -1,57 +1,97 @@
|
|
|
1
1
|
import { resolve } from 'node:path';
|
|
2
2
|
import express from 'express';
|
|
3
|
-
import { build } from 'vite';
|
|
4
|
-
import {
|
|
3
|
+
import { createServer, build } from 'vite';
|
|
4
|
+
import { createLogger } from '@kopflos-cms/logger';
|
|
5
5
|
import { prepareConfig } from './lib/config.js';
|
|
6
|
-
import { log } from './lib/log.js';
|
|
7
6
|
export { defineConfig } from 'vite';
|
|
8
|
-
export
|
|
9
|
-
constructor(
|
|
10
|
-
this.
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
onStart({ env }) {
|
|
20
|
-
const viteVars = {
|
|
21
|
-
basePath: resolve(env.kopflos.basePath, env.kopflos.config.mode === 'development' ? this.rootDir : this.buildDir),
|
|
22
|
-
};
|
|
23
|
-
log.info('Variables', viteVars);
|
|
24
|
-
env.kopflos.variables.VITE = Object.freeze(viteVars);
|
|
25
|
-
}
|
|
26
|
-
async beforeMiddleware(host, { env }) {
|
|
27
|
-
if (env.kopflos.config.mode === 'development') {
|
|
28
|
-
log.info('Development UI mode. Creating Vite server...');
|
|
29
|
-
const configPath = this.options.configPath
|
|
30
|
-
? resolve(env.kopflos.basePath, this.options.configPath)
|
|
31
|
-
: this.options.configPath;
|
|
32
|
-
this._viteDevServer = await createViteServer({
|
|
33
|
-
...this.options,
|
|
34
|
-
configPath,
|
|
35
|
-
});
|
|
36
|
-
host.use(this._viteDevServer.middlewares);
|
|
7
|
+
export class VitePlugin {
|
|
8
|
+
constructor(name, buildConfigurations) {
|
|
9
|
+
this.name = name;
|
|
10
|
+
this.buildConfigurations = buildConfigurations;
|
|
11
|
+
this._viteDevServer = new WeakMap();
|
|
12
|
+
this.log = createLogger(this.name.replace(/^@kopflos-cms\//, ''));
|
|
13
|
+
}
|
|
14
|
+
getDefaultPlugin(plugins) {
|
|
15
|
+
const defaultPlugin = plugins.find(plugin => plugin instanceof DefaultPlugin);
|
|
16
|
+
if (!defaultPlugin) {
|
|
17
|
+
throw new Error('No default plugin found. Please add @kopflos-cms/vite to your plugins list');
|
|
37
18
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
19
|
+
return defaultPlugin;
|
|
20
|
+
}
|
|
21
|
+
async getViteDevServer(env, vitePlugin, options) {
|
|
22
|
+
if (!this._viteDevServer.has(options)) {
|
|
23
|
+
const viteDevServer = await createServer(await this.createConfig(env, vitePlugin, options));
|
|
24
|
+
this._viteDevServer.set(options, viteDevServer);
|
|
43
25
|
}
|
|
26
|
+
return this._viteDevServer.get(options);
|
|
44
27
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const outDir =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
:
|
|
51
|
-
|
|
52
|
-
...this.options,
|
|
28
|
+
createConfig(env, vitePlugin, options) {
|
|
29
|
+
const root = resolve(env.kopflos.basePath, options.root);
|
|
30
|
+
const outDir = this.resolveOutDir(env, options);
|
|
31
|
+
return prepareConfig({
|
|
32
|
+
...options,
|
|
33
|
+
appRoot: env.kopflos.basePath,
|
|
34
|
+
root,
|
|
53
35
|
outDir,
|
|
54
|
-
|
|
55
|
-
|
|
36
|
+
config: vitePlugin.config,
|
|
37
|
+
configPath: vitePlugin.configPath,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
resolveOutDir(env, options) {
|
|
41
|
+
return resolve(env.kopflos.basePath, env.kopflos.buildDir, options.outDir || '');
|
|
42
|
+
}
|
|
43
|
+
async beforeMiddleware(host, { env, plugins }) {
|
|
44
|
+
const vitePlugin = this.getDefaultPlugin(plugins);
|
|
45
|
+
for (const options of this.buildConfigurations) {
|
|
46
|
+
if (env.kopflos.config.mode === 'development') {
|
|
47
|
+
this.log.info('Development UI mode. Creating Vite server...');
|
|
48
|
+
const viteDevServer = await this.getViteDevServer(env, vitePlugin, options);
|
|
49
|
+
host.use(viteDevServer.middlewares);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const buildDir = this.resolveOutDir(env, options);
|
|
53
|
+
this.log.info('Serving from build directory');
|
|
54
|
+
this.log.debug('Build directory:', buildDir);
|
|
55
|
+
host.use(express.static(buildDir));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async build(env, plugins) {
|
|
60
|
+
const vitePlugin = this.getDefaultPlugin(plugins);
|
|
61
|
+
for (const options of this.buildConfigurations) {
|
|
62
|
+
if (!options.entrypoints?.length) {
|
|
63
|
+
this.log.debug('No entrypoints specified. Skipping build');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.log.info('Building UI...');
|
|
67
|
+
const config = await this.createConfig(env, vitePlugin, options);
|
|
68
|
+
await build(config);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export default class DefaultPlugin extends VitePlugin {
|
|
73
|
+
constructor({ build = [], config, configPath }) {
|
|
74
|
+
if (!Array.isArray(build)) {
|
|
75
|
+
super('@kopflos-cms/vite', [build]);
|
|
76
|
+
this.buildConfiguration = build;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
super('@kopflos-cms/vite', build);
|
|
80
|
+
if (build.length === 1) {
|
|
81
|
+
this.buildConfiguration = build[0];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this.config = config;
|
|
85
|
+
this.configPath = configPath;
|
|
86
|
+
}
|
|
87
|
+
getDefaultPlugin() {
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
getDefaultViteDevServer(env) {
|
|
91
|
+
// only work when there is exactly one build configuration
|
|
92
|
+
if (!this.buildConfiguration) {
|
|
93
|
+
throw new Error('No build configuration found. Please add a build configuration to your vite plugin');
|
|
94
|
+
}
|
|
95
|
+
return this.getViteDevServer(env, this, this.buildConfiguration);
|
|
56
96
|
}
|
|
57
97
|
}
|
package/lib/config.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { InlineConfig } from 'vite';
|
|
2
|
+
import type { BuildConfiguration } from '../index.js';
|
|
3
|
+
type ConfigOptions = BuildConfiguration & {
|
|
4
|
+
appRoot: string;
|
|
5
|
+
configPath: string | undefined;
|
|
6
|
+
config: InlineConfig | undefined;
|
|
7
|
+
};
|
|
8
|
+
export declare function prepareConfig({ appRoot, root, configPath, entrypoints, outDir, config }: ConfigOptions): Promise<Record<string, any>>;
|
|
9
|
+
export {};
|
package/lib/config.js
CHANGED
|
@@ -2,7 +2,7 @@ import { resolve } from 'node:path';
|
|
|
2
2
|
import { glob } from 'glob';
|
|
3
3
|
import { mergeConfig } from 'vite';
|
|
4
4
|
import defaultConfig from '../vite.config.js';
|
|
5
|
-
export async function prepareConfig({ root, configPath, entrypoints, outDir, config = {} }) {
|
|
5
|
+
export async function prepareConfig({ appRoot, root, configPath, entrypoints, outDir, config = {} }) {
|
|
6
6
|
const inputConfig = {
|
|
7
7
|
root,
|
|
8
8
|
build: {
|
|
@@ -10,14 +10,17 @@ export async function prepareConfig({ root, configPath, entrypoints, outDir, con
|
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
12
|
if (outDir) {
|
|
13
|
-
inputConfig.build.outDir = resolve(
|
|
13
|
+
inputConfig.build.outDir = resolve(root, outDir);
|
|
14
14
|
}
|
|
15
|
-
if (entrypoints) {
|
|
15
|
+
if (entrypoints.length > 0) {
|
|
16
16
|
inputConfig.build.rollupOptions = {
|
|
17
|
-
input: entrypoints.flatMap(entry => glob.sync(entry)),
|
|
17
|
+
input: entrypoints.flatMap(entry => glob.sync(resolve(root, entry))),
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
if (configPath) {
|
|
21
|
+
if (configPath.startsWith('.')) {
|
|
22
|
+
configPath = resolve(appRoot, configPath);
|
|
23
|
+
}
|
|
21
24
|
const userConfig = await import(configPath);
|
|
22
25
|
return mergeConfig(mergeConfig(defaultConfig, inputConfig), userConfig.default);
|
|
23
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kopflos-cms/vite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Zazuko GmbH",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"vite": "^6.4.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@kopflos-cms/core": "^0.
|
|
38
|
-
"@zazuko/env-node": "^
|
|
37
|
+
"@kopflos-cms/core": "^0.7.0",
|
|
38
|
+
"@zazuko/env-node": "^3.0.0",
|
|
39
39
|
"@types/glob": "^8.1.0",
|
|
40
40
|
"chai": "^5.1.1"
|
|
41
41
|
},
|
package/template.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Kopflos, SubjectHandler } from '@kopflos-cms/core';
|
|
2
|
-
export declare const transform: (this: Kopflos) => SubjectHandler;
|
|
2
|
+
export declare const transform: (this: Kopflos, path: string) => SubjectHandler;
|
package/template.js
CHANGED
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { createLogger } from '@kopflos-cms/logger';
|
|
4
|
+
const log = createLogger('template');
|
|
5
|
+
export const transform = function (path) {
|
|
6
|
+
const vitePlugin = this.getPlugin('@kopflos-cms/vite');
|
|
3
7
|
const prepareDevTemplate = async (subject, template) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
throw new Error('Vite dev server not initialized. Check vite plugin configuration.');
|
|
8
|
+
if (!vitePlugin) {
|
|
9
|
+
throw new Error('Vite plugin not found. Did you forget to add it to the config?');
|
|
7
10
|
}
|
|
11
|
+
const viteDevServer = await vitePlugin.getDefaultViteDevServer(this.env);
|
|
8
12
|
const subjectPath = new URL(subject.value).pathname;
|
|
9
|
-
return
|
|
13
|
+
return viteDevServer.transformIndexHtml(subjectPath, template);
|
|
10
14
|
};
|
|
11
15
|
return async ({ subject, env }, response) => {
|
|
12
|
-
if (!isHtmlResponse(response)) {
|
|
13
|
-
throw new Error('Vite handler must be chained after another which returns a HTML response');
|
|
14
|
-
}
|
|
15
16
|
if (env.kopflos.config.mode === 'production') {
|
|
16
|
-
|
|
17
|
+
const template = await fs.readFile(resolve(env.kopflos.basePath, env.kopflos.buildDir, path));
|
|
18
|
+
return {
|
|
19
|
+
status: 200,
|
|
20
|
+
body: template.toString(),
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'text/html',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
17
25
|
}
|
|
18
26
|
log.debug('Compiling page template');
|
|
27
|
+
const template = await fs.readFile(resolve(env.kopflos.basePath, vitePlugin.buildConfiguration.root, path));
|
|
19
28
|
return {
|
|
20
29
|
...response,
|
|
21
|
-
body: await prepareDevTemplate(subject,
|
|
30
|
+
body: await prepareDevTemplate(subject, template.toString()),
|
|
22
31
|
};
|
|
23
32
|
};
|
|
24
33
|
};
|
|
25
|
-
function isHtmlResponse(response) {
|
|
26
|
-
return typeof response?.body === 'string' || hasHeader(response?.headers, 'Content-Type', 'text/html');
|
|
27
|
-
}
|
|
28
|
-
function hasHeader(headers, headerName, headerValue) {
|
|
29
|
-
const normalizedHeaderName = headerName.toLowerCase();
|
|
30
|
-
return !!headers && Object.entries(headers)
|
|
31
|
-
.some(([key, value]) => {
|
|
32
|
-
return key.toLowerCase() === normalizedHeaderName && (value === headerValue || (Array.isArray(value) && value.includes(headerValue)));
|
|
33
|
-
});
|
|
34
|
-
}
|
package/lib/log.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const log: import("anylogger").Logger<import("anylogger").BaseLevels>;
|
package/lib/log.js
DELETED
package/lib/server.d.ts
DELETED
package/lib/server.js
DELETED