@konomi-app/k2 2.1.5 → 3.0.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/dist/index.js +287 -257
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +355 -284
- package/dist/plugin.js.map +1 -1
- package/package.json +7 -21
package/dist/index.js
CHANGED
|
@@ -1,123 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
// src/index.ts
|
|
4
10
|
import { program as program6 } from "commander";
|
|
5
11
|
|
|
6
12
|
// src/commands/build.ts
|
|
7
13
|
import { program } from "commander";
|
|
8
|
-
import
|
|
14
|
+
import fs3 from "fs-extra";
|
|
9
15
|
import path6 from "path";
|
|
16
|
+
import chalk2 from "chalk";
|
|
10
17
|
|
|
11
18
|
// src/lib/constants.ts
|
|
12
19
|
import path from "path";
|
|
13
20
|
var WORKSPACE_DIRECTORY = ".k2";
|
|
14
21
|
var DEVELOPMENT_DIRECTORY = path.join(WORKSPACE_DIRECTORY, "dev");
|
|
22
|
+
var PRODUCTION_DIRECTORY = path.join(WORKSPACE_DIRECTORY, "prod");
|
|
15
23
|
var CONFIG_FILE_NAME = "k2.config.mjs";
|
|
16
24
|
var PLUGIN_WORKSPACE_DIRECTORY = ".plugin";
|
|
17
25
|
var PLUGIN_CONTENTS_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "contents");
|
|
18
26
|
var PLUGIN_DEVELOPMENT_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "dev");
|
|
27
|
+
var PLUGIN_PRODUCTION_DIRECTORY = path.join(PLUGIN_WORKSPACE_DIRECTORY, "prod");
|
|
19
28
|
var DEFAULT_PORT = 32767;
|
|
20
29
|
|
|
21
|
-
// src/commands/build-base.ts
|
|
22
|
-
import "webpack";
|
|
23
|
-
|
|
24
|
-
// src/lib/webpack.ts
|
|
25
|
-
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|
26
|
-
import path2 from "path";
|
|
27
|
-
import { cwd } from "process";
|
|
28
|
-
import TerserPlugin from "terser-webpack-plugin";
|
|
29
|
-
import webpack from "webpack";
|
|
30
|
-
import chalk from "chalk";
|
|
31
|
-
import { TsconfigPathsPlugin } from "tsconfig-paths-webpack-plugin";
|
|
32
|
-
var buildWithWebpack = async (props) => {
|
|
33
|
-
const { entries, outDir } = props;
|
|
34
|
-
const exclude = /node_modules/;
|
|
35
|
-
const styleLoader = MiniCssExtractPlugin.loader;
|
|
36
|
-
const tsConfigPath = path2.join(cwd(), "tsconfig.json");
|
|
37
|
-
console.group(chalk.blue("\u{1F680} Building with Webpack..."));
|
|
38
|
-
console.log("\u{1F527} tsconfig.json path:", tsConfigPath);
|
|
39
|
-
console.groupEnd();
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
webpack(
|
|
42
|
-
{
|
|
43
|
-
mode: "production",
|
|
44
|
-
target: ["web", "es2023"],
|
|
45
|
-
entry: entries,
|
|
46
|
-
resolve: {
|
|
47
|
-
extensions: [".ts", ".tsx", ".js", ".json"],
|
|
48
|
-
fallback: {
|
|
49
|
-
path: false
|
|
50
|
-
},
|
|
51
|
-
plugins: [new TsconfigPathsPlugin({ configFile: tsConfigPath })]
|
|
52
|
-
},
|
|
53
|
-
cache: { type: "filesystem" },
|
|
54
|
-
output: { filename: "[name].js", path: path2.resolve(outDir) },
|
|
55
|
-
module: {
|
|
56
|
-
rules: [
|
|
57
|
-
{ test: /\.tsx?$/, exclude, loader: "ts-loader" },
|
|
58
|
-
{ test: /\.css$/, use: [styleLoader, "css-loader"] },
|
|
59
|
-
{
|
|
60
|
-
test: /\.scss$/,
|
|
61
|
-
use: [
|
|
62
|
-
styleLoader,
|
|
63
|
-
"css-loader",
|
|
64
|
-
{ loader: "sass-loader", options: { sassOptions: { outputStyle: "expanded" } } }
|
|
65
|
-
]
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
plugins: [new MiniCssExtractPlugin()],
|
|
70
|
-
optimization: {
|
|
71
|
-
minimize: true,
|
|
72
|
-
minimizer: [
|
|
73
|
-
new TerserPlugin({
|
|
74
|
-
terserOptions: { format: { comments: false } },
|
|
75
|
-
extractComments: false
|
|
76
|
-
})
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
(err, stats) => {
|
|
81
|
-
if (err) {
|
|
82
|
-
reject(err);
|
|
83
|
-
} else {
|
|
84
|
-
if (stats?.compilation.errors.length) {
|
|
85
|
-
reject(
|
|
86
|
-
[
|
|
87
|
-
chalk.red("\u26A0 Build failed."),
|
|
88
|
-
...stats.compilation.errors.map((error) => error.message)
|
|
89
|
-
].join("\n")
|
|
90
|
-
);
|
|
91
|
-
} else {
|
|
92
|
-
resolve();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
// src/commands/build-base.ts
|
|
101
|
-
async function action(params) {
|
|
102
|
-
const { entries, outDir } = params;
|
|
103
|
-
return buildWithWebpack({ entries, outDir });
|
|
104
|
-
}
|
|
105
|
-
|
|
106
30
|
// src/commands/build-tailwind.ts
|
|
107
|
-
import
|
|
31
|
+
import path4 from "path";
|
|
108
32
|
|
|
109
33
|
// src/lib/import.ts
|
|
110
34
|
import { pathToFileURL } from "url";
|
|
111
|
-
import
|
|
112
|
-
var esmImport = (
|
|
35
|
+
import path2 from "path";
|
|
36
|
+
var esmImport = (path11) => {
|
|
113
37
|
if (process.platform === "win32") {
|
|
114
|
-
return import(pathToFileURL(
|
|
38
|
+
return import(pathToFileURL(path11).toString());
|
|
115
39
|
} else {
|
|
116
|
-
return import(
|
|
40
|
+
return import(path11);
|
|
117
41
|
}
|
|
118
42
|
};
|
|
119
43
|
var importK2Config = async (configFileName) => {
|
|
120
|
-
return (await esmImport(
|
|
44
|
+
return (await esmImport(path2.resolve(configFileName ?? CONFIG_FILE_NAME))).default;
|
|
121
45
|
};
|
|
122
46
|
|
|
123
47
|
// src/lib/tailwind.ts
|
|
@@ -125,14 +49,14 @@ import chokidar from "chokidar";
|
|
|
125
49
|
import cssnanoPlugin from "cssnano";
|
|
126
50
|
import fs from "fs-extra";
|
|
127
51
|
import { glob } from "glob";
|
|
128
|
-
import
|
|
52
|
+
import path3 from "path";
|
|
129
53
|
import postcss from "postcss";
|
|
130
54
|
import { debounce } from "remeda";
|
|
131
55
|
import tailwindcss from "tailwindcss";
|
|
132
56
|
import invariant from "tiny-invariant";
|
|
133
57
|
var getTailwindConfigFromK2Config = async (k2Config) => {
|
|
134
58
|
invariant(k2Config?.config, "tailwind.config is required");
|
|
135
|
-
const config = (await esmImport(
|
|
59
|
+
const config = (await esmImport(path3.resolve(k2Config?.config))).default;
|
|
136
60
|
return config;
|
|
137
61
|
};
|
|
138
62
|
var outputCss = async (params) => {
|
|
@@ -177,16 +101,16 @@ var watchTailwindCSS = async (params) => {
|
|
|
177
101
|
watcher.on("error", (error) => {
|
|
178
102
|
console.error("Error watching Tailwind CSS:", error);
|
|
179
103
|
});
|
|
180
|
-
watcher.on("add", (
|
|
104
|
+
watcher.on("add", (path11) => {
|
|
181
105
|
debouncedProcessChanges.call("add");
|
|
182
106
|
});
|
|
183
|
-
watcher.on("change", (
|
|
107
|
+
watcher.on("change", (path11) => {
|
|
184
108
|
debouncedProcessChanges.call("change");
|
|
185
109
|
});
|
|
186
|
-
watcher.on("unlink", (
|
|
110
|
+
watcher.on("unlink", (path11) => {
|
|
187
111
|
debouncedProcessChanges.call("unlink");
|
|
188
112
|
});
|
|
189
|
-
watcher.on("unlinkDir", (
|
|
113
|
+
watcher.on("unlinkDir", (path11) => {
|
|
190
114
|
debouncedProcessChanges.call("unlink");
|
|
191
115
|
});
|
|
192
116
|
return watcher;
|
|
@@ -197,12 +121,12 @@ var buildTailwind = async (config) => {
|
|
|
197
121
|
if (!config.tailwind?.css || !config.tailwind?.config) {
|
|
198
122
|
return;
|
|
199
123
|
}
|
|
200
|
-
const tailwindConfig = (await esmImport(
|
|
201
|
-
const inputPath =
|
|
124
|
+
const tailwindConfig = (await esmImport(path4.resolve(config.tailwind.config))).default;
|
|
125
|
+
const inputPath = path4.resolve(config.tailwind.css);
|
|
202
126
|
const fileName = config.tailwind.fileName ?? "tailwind.css";
|
|
203
127
|
await outputCss({
|
|
204
128
|
inputPath,
|
|
205
|
-
outputPath:
|
|
129
|
+
outputPath: path4.join(config.outDir, fileName),
|
|
206
130
|
config: tailwindConfig,
|
|
207
131
|
minify: true
|
|
208
132
|
});
|
|
@@ -219,28 +143,140 @@ var getDefaultK2Config = () => {
|
|
|
219
143
|
};
|
|
220
144
|
};
|
|
221
145
|
|
|
146
|
+
// src/lib/vite.ts
|
|
147
|
+
import path5 from "path";
|
|
148
|
+
import fs2 from "fs-extra";
|
|
149
|
+
import { build as viteBuild } from "vite";
|
|
150
|
+
import chalk from "chalk";
|
|
151
|
+
var createViteConfig = (config = {}) => {
|
|
152
|
+
const plugins = [...config.plugins ?? []];
|
|
153
|
+
try {
|
|
154
|
+
const tsconfigPaths = __require("vite-tsconfig-paths");
|
|
155
|
+
plugins.push(tsconfigPaths.default ? tsconfigPaths.default() : tsconfigPaths());
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
const mode = config.mode ?? "production";
|
|
159
|
+
return {
|
|
160
|
+
...config,
|
|
161
|
+
configFile: false,
|
|
162
|
+
// ブラウザ向けにNode.js固有のオブジェクトをビルド時に解決
|
|
163
|
+
define: {
|
|
164
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
165
|
+
"process.env": JSON.stringify({}),
|
|
166
|
+
...config.define
|
|
167
|
+
},
|
|
168
|
+
build: {
|
|
169
|
+
...config.build,
|
|
170
|
+
// ブラウザ向けターゲット
|
|
171
|
+
target: config.build?.target ?? "es2020",
|
|
172
|
+
cssCodeSplit: false,
|
|
173
|
+
rollupOptions: {
|
|
174
|
+
...config.build?.rollupOptions,
|
|
175
|
+
onwarn: (warning, warn) => {
|
|
176
|
+
if (["MODULE_LEVEL_DIRECTIVE"].includes(warning.code ?? "")) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
warn(warning);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
plugins,
|
|
184
|
+
resolve: {
|
|
185
|
+
...config.resolve,
|
|
186
|
+
alias: {
|
|
187
|
+
"@": path5.resolve(process.cwd(), "src"),
|
|
188
|
+
...config.resolve?.alias
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
async function buildEntriesWithVite(params) {
|
|
194
|
+
const {
|
|
195
|
+
entries,
|
|
196
|
+
outDir,
|
|
197
|
+
mode = "production",
|
|
198
|
+
sourcemap = false,
|
|
199
|
+
minify = true,
|
|
200
|
+
viteConfig = {}
|
|
201
|
+
} = params;
|
|
202
|
+
for (const name of Object.keys(entries)) {
|
|
203
|
+
const entryPath = entries[name];
|
|
204
|
+
const config = createViteConfig({
|
|
205
|
+
...viteConfig,
|
|
206
|
+
mode,
|
|
207
|
+
build: {
|
|
208
|
+
...viteConfig.build,
|
|
209
|
+
lib: {
|
|
210
|
+
entry: entryPath,
|
|
211
|
+
name,
|
|
212
|
+
fileName: () => `${name}.js`,
|
|
213
|
+
formats: ["iife"]
|
|
214
|
+
},
|
|
215
|
+
rollupOptions: {
|
|
216
|
+
...viteConfig.build?.rollupOptions,
|
|
217
|
+
output: {
|
|
218
|
+
assetFileNames: `${name}.[ext]`,
|
|
219
|
+
...viteConfig.build?.rollupOptions?.output
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
outDir,
|
|
223
|
+
emptyOutDir: false,
|
|
224
|
+
sourcemap,
|
|
225
|
+
minify,
|
|
226
|
+
cssCodeSplit: false
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
await viteBuild(config);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
var ENTRY_FILE_NAMES = ["index.ts", "index.tsx", "index.js", "index.jsx", "index.mjs"];
|
|
233
|
+
function getEntryPointsFromDir(inputDir) {
|
|
234
|
+
const entries = {};
|
|
235
|
+
if (!fs2.existsSync(inputDir)) {
|
|
236
|
+
throw new Error(`Input directory not found: ${inputDir}`);
|
|
237
|
+
}
|
|
238
|
+
const dirs = fs2.readdirSync(inputDir, { withFileTypes: true });
|
|
239
|
+
for (const dirent of dirs) {
|
|
240
|
+
if (!dirent.isDirectory()) continue;
|
|
241
|
+
const dirName = dirent.name;
|
|
242
|
+
const dirPath = path5.join(inputDir, dirName);
|
|
243
|
+
for (const filename of ENTRY_FILE_NAMES) {
|
|
244
|
+
const entryPath = path5.join(dirPath, filename);
|
|
245
|
+
if (fs2.existsSync(entryPath)) {
|
|
246
|
+
entries[dirName] = entryPath;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return entries;
|
|
252
|
+
}
|
|
253
|
+
|
|
222
254
|
// src/commands/build.ts
|
|
223
255
|
function command() {
|
|
224
|
-
program.command("build").option("-o, --outdir <outdir>", "Output directory.", path6.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path6.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production
|
|
256
|
+
program.command("build").option("-o, --outdir <outdir>", "Output directory.", path6.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path6.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production with Vite.").action(action);
|
|
225
257
|
}
|
|
226
|
-
async function
|
|
258
|
+
async function action(options) {
|
|
227
259
|
console.group("\u{1F373} Build the project for production");
|
|
228
260
|
try {
|
|
229
261
|
const { outdir, input, config } = options;
|
|
230
262
|
const outDir = path6.resolve(outdir);
|
|
231
|
-
const
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
return acc;
|
|
239
|
-
}, {});
|
|
263
|
+
const entries = getEntryPointsFromDir(path6.resolve(input));
|
|
264
|
+
const entryNames = Object.keys(entries);
|
|
265
|
+
if (entryNames.length === 0) {
|
|
266
|
+
throw new Error(`No entry points found in ${input}`);
|
|
267
|
+
}
|
|
268
|
+
console.log(chalk2.gray(` Entry points: ${entryNames.join(", ")}`));
|
|
240
269
|
const k2Config = config ? await importK2Config(config) : getDefaultK2Config();
|
|
241
270
|
const fullConfig = { ...k2Config, outDir };
|
|
271
|
+
await fs3.emptyDir(outDir);
|
|
242
272
|
const results = await Promise.allSettled([
|
|
243
|
-
|
|
273
|
+
buildEntriesWithVite({
|
|
274
|
+
entries,
|
|
275
|
+
outDir,
|
|
276
|
+
mode: "production",
|
|
277
|
+
sourcemap: false,
|
|
278
|
+
minify: true
|
|
279
|
+
}),
|
|
244
280
|
buildTailwind(fullConfig)
|
|
245
281
|
]);
|
|
246
282
|
for (const result of results) {
|
|
@@ -258,75 +294,15 @@ async function action2(options) {
|
|
|
258
294
|
|
|
259
295
|
// src/commands/dev/index.ts
|
|
260
296
|
import { program as program2 } from "commander";
|
|
261
|
-
import "
|
|
262
|
-
import
|
|
297
|
+
import { createServer } from "vite";
|
|
298
|
+
import fs6 from "fs-extra";
|
|
263
299
|
import path9 from "path";
|
|
264
|
-
|
|
265
|
-
// src/commands/dev-base-esbuild.ts
|
|
266
|
-
import "esbuild";
|
|
267
|
-
import path7 from "path";
|
|
268
|
-
|
|
269
|
-
// src/lib/esbuild.ts
|
|
270
|
-
import chalk2 from "chalk";
|
|
271
|
-
import esbuild from "esbuild";
|
|
272
|
-
var completeBuildOptions = (params) => {
|
|
273
|
-
return {
|
|
274
|
-
bundle: true,
|
|
275
|
-
platform: "browser",
|
|
276
|
-
...params,
|
|
277
|
-
plugins: [...params.plugins ?? []]
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
var completeDevBuildOptions = (params) => {
|
|
281
|
-
return completeBuildOptions({
|
|
282
|
-
...params,
|
|
283
|
-
plugins: [
|
|
284
|
-
...params.plugins ?? [],
|
|
285
|
-
{
|
|
286
|
-
name: "on-end",
|
|
287
|
-
setup: ({ onEnd }) => onEnd(
|
|
288
|
-
() => console.log(
|
|
289
|
-
chalk2.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk2.cyan(`[js] `) + `rebuilt`
|
|
290
|
-
)
|
|
291
|
-
)
|
|
292
|
-
}
|
|
293
|
-
]
|
|
294
|
-
});
|
|
295
|
-
};
|
|
296
|
-
var getEsbuildContext = async (params) => {
|
|
297
|
-
return esbuild.context(completeDevBuildOptions(params));
|
|
298
|
-
};
|
|
299
|
-
var buildWithEsbuild = async (params) => {
|
|
300
|
-
const { watch = false, ...rest } = params;
|
|
301
|
-
if (watch) {
|
|
302
|
-
const context = await getEsbuildContext(rest);
|
|
303
|
-
context.watch();
|
|
304
|
-
} else {
|
|
305
|
-
const options = completeBuildOptions(rest);
|
|
306
|
-
await esbuild.build(options);
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// src/commands/dev-base-esbuild.ts
|
|
311
|
-
async function action3(params) {
|
|
312
|
-
const { entryPoints, staticDir: outdir, certDir, port } = params;
|
|
313
|
-
const context = await getEsbuildContext({ sourcemap: "inline", entryPoints, outdir });
|
|
314
|
-
const [_, serveResult] = await Promise.all([
|
|
315
|
-
context.watch(),
|
|
316
|
-
context.serve({
|
|
317
|
-
port,
|
|
318
|
-
keyfile: path7.join(certDir, "localhost-key.pem"),
|
|
319
|
-
certfile: path7.join(certDir, "localhost-cert.pem"),
|
|
320
|
-
servedir: outdir
|
|
321
|
-
})
|
|
322
|
-
]);
|
|
323
|
-
console.log(`\u{1F680} Start development server at https://localhost:${serveResult.port}`);
|
|
324
|
-
}
|
|
300
|
+
import chalk4 from "chalk";
|
|
325
301
|
|
|
326
302
|
// src/commands/dev/tailwind.ts
|
|
327
|
-
import
|
|
303
|
+
import path7 from "path";
|
|
328
304
|
import chalk3 from "chalk";
|
|
329
|
-
import
|
|
305
|
+
import fs4 from "fs-extra";
|
|
330
306
|
var watchCss = async (params) => {
|
|
331
307
|
const { k2Config, outdir } = params;
|
|
332
308
|
if (!k2Config.tailwind?.css || !k2Config.tailwind?.config) {
|
|
@@ -334,17 +310,17 @@ var watchCss = async (params) => {
|
|
|
334
310
|
return;
|
|
335
311
|
}
|
|
336
312
|
const tailwindConfig = await getTailwindConfigFromK2Config(k2Config.tailwind);
|
|
337
|
-
const input =
|
|
338
|
-
const output =
|
|
339
|
-
if (!await
|
|
340
|
-
await
|
|
313
|
+
const input = path7.resolve(k2Config.tailwind.css);
|
|
314
|
+
const output = path7.join(outdir, "tailwind.css");
|
|
315
|
+
if (!await fs4.pathExists(output)) {
|
|
316
|
+
await fs4.outputFile(output, "");
|
|
341
317
|
}
|
|
342
318
|
return watchTailwindCSS({
|
|
343
319
|
input,
|
|
344
|
-
output:
|
|
320
|
+
output: path7.join(outdir, "tailwind.css"),
|
|
345
321
|
config: tailwindConfig,
|
|
346
322
|
onChanges: ({ output: output2, type }) => {
|
|
347
|
-
const outputFileName =
|
|
323
|
+
const outputFileName = path7.basename(output2);
|
|
348
324
|
console.log(
|
|
349
325
|
chalk3.hex("#e5e7eb")(`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `) + chalk3.cyan(`[css] `) + outputFileName + (type === "init" ? " init" : ` rebuilt(${type})`)
|
|
350
326
|
);
|
|
@@ -352,11 +328,46 @@ var watchCss = async (params) => {
|
|
|
352
328
|
});
|
|
353
329
|
};
|
|
354
330
|
|
|
331
|
+
// src/lib/exec.ts
|
|
332
|
+
import { exec as defaultExec } from "child_process";
|
|
333
|
+
import { promisify } from "util";
|
|
334
|
+
var exec = promisify(defaultExec);
|
|
335
|
+
|
|
336
|
+
// src/lib/cert.ts
|
|
337
|
+
import fs5 from "fs-extra";
|
|
338
|
+
import path8 from "path";
|
|
339
|
+
var CERT_KEY_FILENAME = "localhost-key.pem";
|
|
340
|
+
var CERT_FILENAME = "localhost-cert.pem";
|
|
341
|
+
var generateCert = async (outDir) => {
|
|
342
|
+
await fs5.ensureDir(outDir);
|
|
343
|
+
const { stdout } = await exec(`mkcert localhost 127.0.0.1 ::1`);
|
|
344
|
+
[
|
|
345
|
+
{ input: "localhost+2.pem", output: CERT_FILENAME },
|
|
346
|
+
{ input: "localhost+2-key.pem", output: CERT_KEY_FILENAME }
|
|
347
|
+
].forEach(({ input, output }) => {
|
|
348
|
+
if (fs5.existsSync(input)) {
|
|
349
|
+
fs5.moveSync(`./${input}`, path8.join(outDir, output), {
|
|
350
|
+
overwrite: true
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
return { stdout };
|
|
355
|
+
};
|
|
356
|
+
function hasCertificates(certDir) {
|
|
357
|
+
return fs5.existsSync(path8.join(certDir, CERT_KEY_FILENAME)) && fs5.existsSync(path8.join(certDir, CERT_FILENAME));
|
|
358
|
+
}
|
|
359
|
+
function loadCertificates(certDir) {
|
|
360
|
+
return {
|
|
361
|
+
key: fs5.readFileSync(path8.join(certDir, CERT_KEY_FILENAME)),
|
|
362
|
+
cert: fs5.readFileSync(path8.join(certDir, CERT_FILENAME))
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
355
366
|
// src/commands/dev/index.ts
|
|
356
367
|
function command2() {
|
|
357
|
-
program2.command("dev").description("Start development server.").option("-i, --input <input>", "Input directory", "src/apps").option("-o, --outdir <outdir>", "Output directory.", DEVELOPMENT_DIRECTORY).option("-c, --certdir <certdir>", "Certificate directory", WORKSPACE_DIRECTORY).option("--config <config>", "k2 config file path").option("-p, --port <port>", "Port number").action(
|
|
368
|
+
program2.command("dev").description("Start development server with Vite.").option("-i, --input <input>", "Input directory", "src/apps").option("-o, --outdir <outdir>", "Output directory.", DEVELOPMENT_DIRECTORY).option("-c, --certdir <certdir>", "Certificate directory", WORKSPACE_DIRECTORY).option("--config <config>", "k2 config file path").option("-p, --port <port>", "Port number").action(action2);
|
|
358
369
|
}
|
|
359
|
-
async function
|
|
370
|
+
async function action2(options) {
|
|
360
371
|
const { certdir, outdir, config, port: specifiedPort, input } = options;
|
|
361
372
|
console.group("\u{1F373} Start development server");
|
|
362
373
|
try {
|
|
@@ -369,60 +380,85 @@ async function action4(options) {
|
|
|
369
380
|
console.log(`\u2699 ${CONFIG_FILE_NAME} not found. use default settings.`);
|
|
370
381
|
}
|
|
371
382
|
const port = Number(specifiedPort ?? k2Config?.server?.port ?? DEFAULT_PORT);
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
383
|
+
const certDirPath = path9.resolve(certdir);
|
|
384
|
+
const outputDir = path9.resolve(outdir);
|
|
385
|
+
const inputDir = path9.resolve(input);
|
|
386
|
+
if (!hasCertificates(certDirPath)) {
|
|
387
|
+
console.log(chalk4.yellow("\u{1F4DC} SSL certificates not found. Generating..."));
|
|
388
|
+
try {
|
|
389
|
+
await generateCert(certDirPath);
|
|
390
|
+
console.log(chalk4.green("\u2705 SSL certificates generated successfully"));
|
|
391
|
+
} catch (error) {
|
|
392
|
+
console.log(
|
|
393
|
+
chalk4.red("\u274C Failed to generate SSL certificates. Make sure mkcert is installed.")
|
|
394
|
+
);
|
|
395
|
+
console.log(chalk4.gray(" Install mkcert: https://github.com/FiloSottile/mkcert"));
|
|
396
|
+
throw error;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const entries = getEntryPointsFromDir(inputDir);
|
|
400
|
+
const entryNames = Object.keys(entries);
|
|
401
|
+
if (entryNames.length === 0) {
|
|
402
|
+
throw new Error(`No entry points found in ${input}`);
|
|
403
|
+
}
|
|
404
|
+
console.log(chalk4.gray(` Entry points: ${entryNames.join(", ")}`));
|
|
405
|
+
await fs6.emptyDir(outputDir);
|
|
406
|
+
const { key, cert } = loadCertificates(certDirPath);
|
|
407
|
+
console.log(chalk4.gray(" Building..."));
|
|
408
|
+
await buildEntriesWithVite({
|
|
409
|
+
entries,
|
|
410
|
+
outDir: outputDir,
|
|
411
|
+
mode: "development",
|
|
412
|
+
sourcemap: "inline",
|
|
413
|
+
minify: false
|
|
414
|
+
});
|
|
415
|
+
const serverConfig = createViteConfig({
|
|
416
|
+
root: outputDir,
|
|
417
|
+
server: {
|
|
418
|
+
port,
|
|
419
|
+
https: { key, cert }
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
const server = await createServer(serverConfig);
|
|
423
|
+
await server.listen();
|
|
424
|
+
console.log(chalk4.green(`
|
|
425
|
+
\u2728 Development server ready!`));
|
|
426
|
+
console.log(chalk4.cyan(` Local: https://localhost:${port}`));
|
|
427
|
+
console.log(chalk4.gray(` Output: ${outputDir}`));
|
|
428
|
+
console.log(chalk4.gray("\n Watching for changes...\n"));
|
|
429
|
+
const chokidar2 = await import("chokidar");
|
|
430
|
+
const watcher = chokidar2.watch([`${input}/**/*.{ts,tsx,js,jsx,css,scss}`], {
|
|
431
|
+
ignored: /node_modules/,
|
|
432
|
+
persistent: true
|
|
433
|
+
});
|
|
434
|
+
const rebuild = async () => {
|
|
435
|
+
console.log(chalk4.gray(" Rebuilding..."));
|
|
436
|
+
await buildEntriesWithVite({
|
|
437
|
+
entries,
|
|
438
|
+
outDir: outputDir,
|
|
439
|
+
mode: "development",
|
|
440
|
+
sourcemap: "inline",
|
|
441
|
+
minify: false
|
|
442
|
+
});
|
|
443
|
+
};
|
|
444
|
+
watcher.on("change", rebuild);
|
|
445
|
+
watcher.on("add", rebuild);
|
|
446
|
+
watcher.on("unlink", rebuild);
|
|
447
|
+
if (k2Config) {
|
|
448
|
+
await watchCss({ k2Config, outdir });
|
|
449
|
+
}
|
|
376
450
|
} catch (error) {
|
|
377
451
|
throw error;
|
|
378
452
|
} finally {
|
|
379
453
|
console.groupEnd();
|
|
380
454
|
}
|
|
381
455
|
}
|
|
382
|
-
var build = async (params) => {
|
|
383
|
-
const { outdir, certdir, port, input } = params;
|
|
384
|
-
const srcDir = path9.resolve(input);
|
|
385
|
-
const dirs = fs4.readdirSync(srcDir);
|
|
386
|
-
const entryPoints = dirs.reduce(
|
|
387
|
-
(acc, dir) => {
|
|
388
|
-
for (const filename of ["index.ts", "index.js", "index.mjs"]) {
|
|
389
|
-
if (fs4.existsSync(path9.join(srcDir, dir, filename))) {
|
|
390
|
-
return [...acc, { in: path9.join(srcDir, dir, filename), out: dir }];
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
return acc;
|
|
394
|
-
},
|
|
395
|
-
[]
|
|
396
|
-
);
|
|
397
|
-
return action3({ port, entryPoints, certDir: certdir, staticDir: outdir });
|
|
398
|
-
};
|
|
399
456
|
|
|
400
457
|
// src/commands/genkey.ts
|
|
401
458
|
import { program as program3 } from "commander";
|
|
402
459
|
|
|
403
|
-
// src/lib/exec.ts
|
|
404
|
-
import { exec as defaultExec } from "child_process";
|
|
405
|
-
import { promisify } from "util";
|
|
406
|
-
var exec = promisify(defaultExec);
|
|
407
|
-
|
|
408
|
-
// src/lib/cert.ts
|
|
409
|
-
import fs5 from "fs-extra";
|
|
410
|
-
import path10 from "path";
|
|
411
|
-
var generateCert = async (outDir) => {
|
|
412
|
-
const { stdout } = await exec(`mkcert localhost 127.0.0.1 ::1`);
|
|
413
|
-
[
|
|
414
|
-
{ input: "localhost+2.pem", output: "localhost-cert.pem" },
|
|
415
|
-
{ input: "localhost+2-key.pem", output: "localhost-key.pem" }
|
|
416
|
-
].forEach(({ input, output }) => {
|
|
417
|
-
fs5.moveSync(`./${input}`, path10.join(outDir, output), {
|
|
418
|
-
overwrite: true
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
return { stdout };
|
|
422
|
-
};
|
|
423
|
-
|
|
424
460
|
// src/commands/genkey-base.ts
|
|
425
|
-
async function
|
|
461
|
+
async function action3(options) {
|
|
426
462
|
const { output } = options;
|
|
427
463
|
console.group("\u{1F373} Generate SSL key for localhost");
|
|
428
464
|
try {
|
|
@@ -440,47 +476,41 @@ async function action5(options) {
|
|
|
440
476
|
|
|
441
477
|
// src/commands/genkey.ts
|
|
442
478
|
function command3() {
|
|
443
|
-
program3.command("genkey").description("Generate SSL key for localhost. (Require mkcert)").option("-o, --output <output>", "Output directory.", WORKSPACE_DIRECTORY).action(
|
|
479
|
+
program3.command("genkey").description("Generate SSL key for localhost. (Require mkcert)").option("-o, --output <output>", "Output directory.", WORKSPACE_DIRECTORY).action(action4);
|
|
444
480
|
}
|
|
445
|
-
async function
|
|
446
|
-
await
|
|
481
|
+
async function action4(options) {
|
|
482
|
+
await action3(options);
|
|
447
483
|
}
|
|
448
484
|
|
|
449
485
|
// src/commands/build-esbuild.ts
|
|
450
486
|
import { program as program4 } from "commander";
|
|
451
|
-
import
|
|
452
|
-
import
|
|
453
|
-
import "
|
|
487
|
+
import fs7 from "fs-extra";
|
|
488
|
+
import path10 from "path";
|
|
489
|
+
import chalk5 from "chalk";
|
|
454
490
|
function command4() {
|
|
455
|
-
program4.command("esbuild-build").option("-o, --outdir <outdir>", "Output directory.",
|
|
491
|
+
program4.command("esbuild-build").option("-o, --outdir <outdir>", "Output directory.", path10.join(WORKSPACE_DIRECTORY, "prod")).option("-i, --input <input>", "Input directory.", path10.join("src", "apps")).option("--config <config>", "k2 config file path").description("Build the project for production with Vite. (Legacy command name, now uses Vite)").action(action5);
|
|
456
492
|
}
|
|
457
|
-
async function
|
|
493
|
+
async function action5(options) {
|
|
458
494
|
console.group("\u{1F373} Build the project for production");
|
|
459
495
|
try {
|
|
460
496
|
const { outdir, input, config } = options;
|
|
461
|
-
const outDir =
|
|
462
|
-
|
|
463
|
-
|
|
497
|
+
const outDir = path10.resolve(outdir);
|
|
498
|
+
const entries = getEntryPointsFromDir(path10.resolve(input));
|
|
499
|
+
const entryNames = Object.keys(entries);
|
|
500
|
+
if (entryNames.length === 0) {
|
|
501
|
+
throw new Error(`No entry points found in ${input}`);
|
|
464
502
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
for (const filename of ["index.ts", "index.js", "index.mjs"]) {
|
|
468
|
-
if (fs6.existsSync(path11.join(input, dir, filename))) {
|
|
469
|
-
return { ...acc, [dir]: path11.join(input, dir, filename) };
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
return acc;
|
|
473
|
-
}, {});
|
|
474
|
-
console.log(`\u{1F4C1} ${Object.keys(entryPoints).length} entry points`);
|
|
503
|
+
console.log(chalk5.gray(` Entry points: ${entryNames.join(", ")}`));
|
|
504
|
+
await fs7.emptyDir(outDir);
|
|
475
505
|
const k2Config = config ? await importK2Config(config) : getDefaultK2Config();
|
|
476
506
|
const fullConfig = { ...k2Config, outDir };
|
|
477
507
|
const results = await Promise.allSettled([
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
508
|
+
buildEntriesWithVite({
|
|
509
|
+
entries,
|
|
510
|
+
outDir,
|
|
511
|
+
mode: "production",
|
|
481
512
|
sourcemap: false,
|
|
482
|
-
minify: true
|
|
483
|
-
legalComments: "none"
|
|
513
|
+
minify: true
|
|
484
514
|
}),
|
|
485
515
|
buildTailwind(fullConfig)
|
|
486
516
|
]);
|
|
@@ -531,9 +561,9 @@ async function lint() {
|
|
|
531
561
|
|
|
532
562
|
// src/commands/lint.ts
|
|
533
563
|
function command5() {
|
|
534
|
-
program5.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(
|
|
564
|
+
program5.command("lint").description("Lint source files").option("-c, --config <config>", "Config file path").action(action6);
|
|
535
565
|
}
|
|
536
|
-
async function
|
|
566
|
+
async function action6(options) {
|
|
537
567
|
try {
|
|
538
568
|
lint();
|
|
539
569
|
} catch (error) {
|