@yannick-z/modulo 0.3.1 → 0.3.3

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/bin/modulo.js CHANGED
@@ -3,7 +3,7 @@
3
3
  const requiredVersion = 24;
4
4
  const currentVersion = process.version.match(/^v(\d+)/)?.[1];
5
5
 
6
- if (!currentVersion || parseInt(currentVersion) < requiredVersion) {
6
+ if (!currentVersion || parseInt(currentVersion, 10) < requiredVersion) {
7
7
  console.error(
8
8
  `\x1b[31mError: Node.js version ${process.version} is not supported. Please use Node.js v${requiredVersion} or higher.\x1b[0m`,
9
9
  );
package/dist/131.js ADDED
@@ -0,0 +1,108 @@
1
+ import { cac } from "cac";
2
+ import node_fs, { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
3
+ import node_path, { dirname, extname, join, relative, resolve } from "node:path";
4
+ import picocolors from "picocolors";
5
+ const logFile = join(process.cwd(), "modulo.debug.log");
6
+ let index = 0;
7
+ function debug_log(hint, ...params) {
8
+ const argv_debug = process.env.DEBUG || process.argv.includes("--debug");
9
+ const argv_verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
10
+ if (!argv_debug && !argv_verbose) return;
11
+ const timestamp = new Date().toISOString();
12
+ const sn = String(index++).padStart(3, "0");
13
+ const logEntry = `--------------\n${sn} [${timestamp}] ${hint}\n${params.map((p)=>"object" == typeof p ? JSON.stringify(p, null, 2) : String(p)).join("\n")}\n---------------\n\n`;
14
+ if (argv_verbose) console.log(logEntry);
15
+ if (argv_debug) {
16
+ console.log(picocolors.blue(`\ndebug log ${sn}`));
17
+ appendFileSync(logFile, logEntry);
18
+ }
19
+ }
20
+ const logger = {
21
+ info: (msg)=>console.log(picocolors.cyan(msg)),
22
+ success: (msg)=>console.log(picocolors.green(msg)),
23
+ warn: (msg)=>console.log(picocolors.yellow(msg)),
24
+ error: (msg)=>console.log(picocolors.red(msg)),
25
+ debug: (msg)=>{
26
+ if (process.env.DEBUG) console.log(picocolors.gray(`[DEBUG] ${msg}`));
27
+ }
28
+ };
29
+ var package_namespaceObject = {
30
+ rE: "0.3.2"
31
+ };
32
+ const cli = cac("modulo");
33
+ cli.command("init <target>", "Initialize modulo configuration or scripts").option("-f, --force", "Force overwrite existing files").option("--path <path>", "Specify the path to initialize").option("--preset <preset>", "Specify the preset to use").action((target, options)=>{
34
+ import("./54.js").then((mod)=>({
35
+ init_tool: mod.init_tool
36
+ })).then(({ init_tool })=>{
37
+ init_tool({
38
+ cmd: "init",
39
+ target: target,
40
+ init: {
41
+ path: options.path,
42
+ force: options.force,
43
+ preset: options.preset
44
+ }
45
+ });
46
+ });
47
+ });
48
+ cli.command("build <target>", "Build the project for production").option("-c, --config <file>", "Use specified config file").option("-w, --watch", "Watch for changes").option("--env <env>", "Specify the environment (dev/prd)").action((target, options)=>{
49
+ import("./839.js").then((mod)=>({
50
+ pack_code: mod.pack_code
51
+ })).then(({ pack_code })=>{
52
+ pack_code({
53
+ cmd: "build",
54
+ target: target,
55
+ pack: {
56
+ config: options.config,
57
+ env: options.env || "prd",
58
+ watch: options.watch,
59
+ esm: true
60
+ }
61
+ });
62
+ });
63
+ });
64
+ cli.command("dev <target>", "Start development server").option("-c, --config <file>", "Use specified config file").option("--env <env>", "Specify the environment (dev/prd)").option("--debug", "Enable debug mode").action((target, options)=>{
65
+ if (options.debug) process.env.DEBUG = "true";
66
+ import("./839.js").then((mod)=>({
67
+ pack_code: mod.pack_code
68
+ })).then(({ pack_code })=>{
69
+ pack_code({
70
+ cmd: "dev",
71
+ target: target,
72
+ pack: {
73
+ config: options.config,
74
+ env: options.env || "dev",
75
+ watch: true,
76
+ esm: true
77
+ }
78
+ });
79
+ });
80
+ });
81
+ cli.command("preview <target>", "Preview the production build").option("-c, --config <file>", "Use specified config file").action((target, options)=>{
82
+ import("./839.js").then((mod)=>({
83
+ pack_code: mod.pack_code
84
+ })).then(({ pack_code })=>{
85
+ pack_code({
86
+ cmd: "preview",
87
+ target: target,
88
+ pack: {
89
+ config: options.config,
90
+ env: "prd",
91
+ watch: false,
92
+ esm: true
93
+ }
94
+ });
95
+ });
96
+ });
97
+ cli.help();
98
+ cli.version(package_namespaceObject.rE);
99
+ function exec() {
100
+ try {
101
+ cli.parse();
102
+ } catch (error) {
103
+ logger.error(`Error: ${error.message}`);
104
+ cli.outputHelp();
105
+ process.exit(1);
106
+ }
107
+ }
108
+ export { debug_log, dirname, exec, existsSync, extname, join, mkdirSync, node_fs, node_path, picocolors, readFileSync, readdirSync, relative, resolve, statSync, writeFileSync };
package/dist/54.js ADDED
@@ -0,0 +1,340 @@
1
+ import node_readline from "node:readline";
2
+ import { existsSync, extname, mkdirSync, writeFileSync, picocolors, resolve as external_node_path_resolve } from "./131.js";
3
+ import { preset_alias, preset_config, update_json_file, get_packagejson } from "./938.js";
4
+ async function cli_confirm(message) {
5
+ const rl = node_readline.createInterface({
6
+ input: process.stdin,
7
+ output: process.stdout
8
+ });
9
+ return new Promise((resolve)=>{
10
+ rl.question(`${picocolors.yellow(message)} (Y/n) `, (answer)=>{
11
+ rl.close();
12
+ resolve("y" === answer.toLowerCase() || "" === answer);
13
+ });
14
+ });
15
+ }
16
+ const star_line = "**********************";
17
+ async function modify_scripts() {
18
+ const packagejson = get_packagejson();
19
+ const new_scripts = {
20
+ ...packagejson.scripts || {},
21
+ "build:page": "modulo build page",
22
+ "build:module": "modulo build module",
23
+ "build:all": "modulo build all",
24
+ build: "modulo build all",
25
+ "dev:page": "modulo dev page",
26
+ "dev:module": "modulo dev module",
27
+ "watch:page": "modulo build page --watch=true",
28
+ "watch:module": "modulo build module --watch=true"
29
+ };
30
+ console.log(picocolors.magentaBright(`\n${star_line}\n修改package.json中的scripts\n新的内容修改后如下:\n${JSON.stringify(new_scripts, null, 2)}\n${star_line}`));
31
+ const confirmed = await cli_confirm("\n确定修改吗?");
32
+ if (!confirmed) return void console.log("取消修改");
33
+ const success = update_json_file(external_node_path_resolve(process.cwd(), "package.json"), (data)=>{
34
+ data.scripts = new_scripts;
35
+ return data;
36
+ });
37
+ if (success) console.log(picocolors.green(`\npackage.json修改成功`));
38
+ else console.log(picocolors.red(`\npackage.json修改失败`));
39
+ }
40
+ const vue2_example_externals = {
41
+ vue: {
42
+ importName: [
43
+ "vue",
44
+ "Vue"
45
+ ],
46
+ url: "https://cdn.jsdelivr.net/npm/vue@2.7.16/+esm"
47
+ }
48
+ };
49
+ const react19_example_externals = {
50
+ react: {
51
+ importName: [
52
+ "react",
53
+ "React"
54
+ ],
55
+ url: "https://esm.sh/react@19.2.4"
56
+ },
57
+ "react-dom": "https://esm.sh/react-dom@19.2.4",
58
+ "react/jsx-runtime": "https://esm.sh/react@19.2.4/jsx-runtime"
59
+ };
60
+ const common_example_externals = {
61
+ jquery: "https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js",
62
+ rxjs: "https://cdn.jsdelivr.net/npm/rxjs@7.8.2/+esm"
63
+ };
64
+ const presets = {
65
+ vue2: {
66
+ ...vue2_example_externals,
67
+ ...common_example_externals
68
+ },
69
+ react19: {
70
+ ...react19_example_externals,
71
+ ...common_example_externals
72
+ }
73
+ };
74
+ function get_example_config(preset) {
75
+ console.log(picocolors.magenta(`\n${star_line}\n默认配置文件中的externals内容为推荐内容\n请注意手动替换配置文件中externals的url,以保证符合项目需求\n如果不需要externals部分依赖,也可以将他们从列表中删除\n${star_line}\n`));
76
+ let externals = common_example_externals;
77
+ if (preset) {
78
+ if ("react19" === preset) externals = presets.react19;
79
+ else if ("vue2" === preset || "vue2" === preset) externals = presets.vue2;
80
+ }
81
+ return {
82
+ input: preset_config.input,
83
+ output: {
84
+ filenameHash: true
85
+ },
86
+ url: {
87
+ base: "/"
88
+ },
89
+ alias: preset_alias,
90
+ html: {
91
+ root: "app",
92
+ title: "Modulo Page",
93
+ meta: {},
94
+ tags: [
95
+ {
96
+ tag: "script",
97
+ attrs: {
98
+ src: "/packages/webhost/dist/webhost.system.js"
99
+ },
100
+ append: false,
101
+ publicPath: false
102
+ }
103
+ ]
104
+ },
105
+ dev_server: {
106
+ proxy: preset_config.dev_server.proxy
107
+ },
108
+ externals
109
+ };
110
+ }
111
+ const default_config_file_name = "modulo.config.ts";
112
+ async function create_config_file(args) {
113
+ const path = args.init.path || default_config_file_name;
114
+ console.log(picocolors.blue("即将创建配置文件"), path);
115
+ const filepath = external_node_path_resolve(process.cwd(), path);
116
+ if (existsSync(filepath)) if (args.init.force) console.log(picocolors.bgRed(picocolors.white("配置文件已存在,将覆盖")));
117
+ else {
118
+ console.log(picocolors.red("配置文件已存在,是否覆盖?"));
119
+ const rl = node_readline.createInterface({
120
+ input: process.stdin,
121
+ output: process.stdout
122
+ });
123
+ const answer = await new Promise((resolve)=>{
124
+ rl.question("\n请输入(Y/N) ", (answer)=>{
125
+ rl.close();
126
+ resolve(answer);
127
+ });
128
+ });
129
+ if ("y" !== answer.toLowerCase()) return void console.log("取消创建");
130
+ }
131
+ const config = get_example_config(args.init.preset);
132
+ const ext = extname(path);
133
+ let content = "";
134
+ content = ".ts" === ext ? `import type { UserConfig } from "@yannick-z/modulo";
135
+
136
+ const config: UserConfig = ${JSON.stringify(config, null, 2)};
137
+
138
+ export default config;
139
+ ` : ".js" === ext ? `/** @type {import('@yannick-z/modulo').UserConfig} */
140
+ export default ${JSON.stringify(config, null, 2)};
141
+ ` : JSON.stringify(config, null, 2);
142
+ writeFileSync(filepath, content);
143
+ console.log(picocolors.green("创建成功"), filepath);
144
+ }
145
+ async function create_project(args) {
146
+ const { path, preset } = args.init;
147
+ if (!path) {
148
+ console.error(picocolors.red("请指定项目路径: modulo init project --path <project-path>"));
149
+ process.exit(1);
150
+ }
151
+ const projectRoot = external_node_path_resolve(process.cwd(), path);
152
+ if (existsSync(projectRoot)) {
153
+ if (!args.init.force) {
154
+ console.error(picocolors.red(`目录 ${path} 已存在,请使用 --force 覆盖或选择其他路径`));
155
+ process.exit(1);
156
+ }
157
+ } else mkdirSync(projectRoot, {
158
+ recursive: true
159
+ });
160
+ console.log(picocolors.blue(`正在初始化项目到: ${projectRoot}`));
161
+ const originalCwd = process.cwd();
162
+ process.chdir(projectRoot);
163
+ try {
164
+ const packageJson = {
165
+ name: path.split("/").pop() || "modulo-project",
166
+ version: "0.0.0",
167
+ type: "module",
168
+ scripts: {
169
+ lint: "biome lint .",
170
+ format: "biome format --write .",
171
+ check: "biome check --write ."
172
+ },
173
+ dependencies: {},
174
+ devDependencies: {
175
+ "@yannick-z/modulo": "^0.2.0",
176
+ typescript: "^5.0.0",
177
+ "@biomejs/biome": "2.4.4"
178
+ }
179
+ };
180
+ if ("vue2" === preset) packageJson.dependencies = {
181
+ vue: "2.7.16"
182
+ };
183
+ else if ("react19" === preset) packageJson.dependencies = {
184
+ react: "19.2.4",
185
+ "react-dom": "19.2.4"
186
+ };
187
+ writeFileSync(external_node_path_resolve(projectRoot, "package.json"), JSON.stringify(packageJson, null, 2));
188
+ console.log(picocolors.green("创建 package.json 成功"));
189
+ get_packagejson(projectRoot);
190
+ const tsConfig = {
191
+ compilerOptions: {
192
+ target: "ESNext",
193
+ module: "ESNext",
194
+ moduleResolution: "bundler",
195
+ strict: true,
196
+ jsx: "react19" === preset ? "react-jsx" : "preserve",
197
+ esModuleInterop: true,
198
+ skipLibCheck: true,
199
+ forceConsistentCasingInFileNames: true,
200
+ baseUrl: ".",
201
+ paths: {
202
+ "@/*": [
203
+ "src/*"
204
+ ]
205
+ }
206
+ },
207
+ include: [
208
+ "src/**/*",
209
+ "modulo.config.ts"
210
+ ]
211
+ };
212
+ writeFileSync(external_node_path_resolve(projectRoot, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
213
+ console.log(picocolors.green("创建 tsconfig.json 成功"));
214
+ mkdirSync(external_node_path_resolve(projectRoot, "src/pages/index"), {
215
+ recursive: true
216
+ });
217
+ if ("vue2" === preset) {
218
+ const vueContent = `<template>
219
+ <div id="app">
220
+ <h1>Hello Modulo + Vue 2</h1>
221
+ </div>
222
+ </template>
223
+
224
+ <script lang="ts">
225
+ import Vue from 'vue';
226
+ export default Vue.extend({
227
+ name: 'App'
228
+ });
229
+ </script>
230
+
231
+ <style scoped>
232
+ h1 {
233
+ color: #42b983;
234
+ }
235
+ </style>
236
+ `;
237
+ writeFileSync(external_node_path_resolve(projectRoot, "src/pages/index/App.vue"), vueContent);
238
+ const indexContent = `import Vue from 'vue';
239
+ import App from './App.vue';
240
+
241
+ new Vue({
242
+ render: h => h(App)
243
+ }).$mount('#app');
244
+ `;
245
+ writeFileSync(external_node_path_resolve(projectRoot, "src/pages/index/index.ts"), indexContent);
246
+ const shimContent = `declare module '*.vue' {
247
+ import Vue from 'vue';
248
+ export default Vue;
249
+ }
250
+ `;
251
+ writeFileSync(external_node_path_resolve(projectRoot, "src/shim-vue.d.ts"), shimContent);
252
+ } else if ("react19" === preset) {
253
+ const appContent = `import { useState } from 'react';
254
+
255
+ export function App() {
256
+ const [count, setCount] = useState(0);
257
+ return (
258
+ <div>
259
+ <h1>Hello Modulo + React 19</h1>
260
+ <button onClick={() => setCount(count + 1)}>Count: {count}</button>
261
+ </div>
262
+ );
263
+ }
264
+ `;
265
+ writeFileSync(external_node_path_resolve(projectRoot, "src/pages/index/App.tsx"), appContent);
266
+ const indexContent = `import { createRoot } from 'react-dom/client';
267
+ import { App } from './App';
268
+
269
+ const root = createRoot(document.getElementById('app')!);
270
+ root.render(<App />);
271
+ `;
272
+ writeFileSync(external_node_path_resolve(projectRoot, "src/pages/index/index.tsx"), indexContent);
273
+ }
274
+ const configArgs = {
275
+ ...args,
276
+ init: {
277
+ ...args.init,
278
+ path: ""
279
+ }
280
+ };
281
+ await create_config_file(configArgs);
282
+ modify_scripts();
283
+ const biomeConfig = {
284
+ $schema: "https://biomejs.dev/schemas/1.9.4/schema.json",
285
+ vcs: {
286
+ enabled: false,
287
+ clientKind: "git",
288
+ useIgnoreFile: false
289
+ },
290
+ files: {
291
+ ignoreUnknown: false,
292
+ ignore: []
293
+ },
294
+ formatter: {
295
+ enabled: true,
296
+ indentStyle: "tab"
297
+ },
298
+ organizeImports: {
299
+ enabled: true
300
+ },
301
+ linter: {
302
+ enabled: true,
303
+ rules: {
304
+ recommended: true
305
+ }
306
+ },
307
+ javascript: {
308
+ formatter: {
309
+ quoteStyle: "double"
310
+ }
311
+ }
312
+ };
313
+ writeFileSync(external_node_path_resolve(projectRoot, "biome.json"), JSON.stringify(biomeConfig, null, 2));
314
+ console.log(picocolors.green("创建 biome.json 成功"));
315
+ const vscodeExtensions = {
316
+ recommendations: [
317
+ "biomejs.biome"
318
+ ]
319
+ };
320
+ mkdirSync(external_node_path_resolve(projectRoot, ".vscode"), {
321
+ recursive: true
322
+ });
323
+ writeFileSync(external_node_path_resolve(projectRoot, ".vscode/extensions.json"), JSON.stringify(vscodeExtensions, null, 2));
324
+ console.log(picocolors.green("创建 .vscode/extensions.json 成功"));
325
+ console.log(picocolors.green("\n项目初始化完成!\n"));
326
+ console.log(picocolors.cyan(` cd ${path}`));
327
+ console.log(picocolors.cyan(" npm install"));
328
+ console.log(picocolors.cyan(" npm run dev page\n"));
329
+ } catch (error) {
330
+ console.error(picocolors.red("项目初始化失败:"), error);
331
+ } finally{
332
+ process.chdir(originalCwd);
333
+ }
334
+ }
335
+ function init_tool(args) {
336
+ if ("config" === args.target) create_config_file(args);
337
+ if ("script" === args.target) modify_scripts();
338
+ if ("project" === args.target) create_project(args);
339
+ }
340
+ export { init_tool };