@vixoniccom/module-packager 2.10.2-test.5 → 2.10.2-test.6

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.
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { app, BrowserWindow } from 'electron';
3
+ import remoteMain from '@electron/remote/main/index.js';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import commandLineArgs from 'command-line-args';
7
+ import fs from 'fs';
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ const optionDefinitions = [
11
+ { name: 'externals', type: String, defaultValue: [], multiple: true },
12
+ { name: 'src', type: String, defaultValue: path.join(__dirname, 'src') },
13
+ { name: 'build', type: String, defaultValue: path.join(__dirname, 'build') },
14
+ { name: 'config', type: String, defaultValue: './webpack.config.js' },
15
+ { name: 'port', type: Number, defaultValue: 8080 },
16
+ { name: 'mode', type: String, defaultValue: 'run' }
17
+ ];
18
+ const options = commandLineArgs(optionDefinitions);
19
+ console.log('🚀 [ELECTRON] options:', options);
20
+ if (options.mode === 'watch') {
21
+ (await import('electron-debug')).default({ showDevTools: true });
22
+ }
23
+ remoteMain.initialize();
24
+ let mainWindow = null;
25
+ function createWindow() {
26
+ console.log('[ELECTRON] Creating BrowserWindow…');
27
+ mainWindow = new BrowserWindow({
28
+ show: false,
29
+ x: 100,
30
+ y: 100,
31
+ width: 1024,
32
+ height: 768,
33
+ webPreferences: {
34
+ preload: path.join(__dirname, 'preload.js'),
35
+ nodeIntegrationInSubFrames: true,
36
+ nodeIntegration: true,
37
+ contextIsolation: false,
38
+ webSecurity: false,
39
+ webviewTag: true
40
+ }
41
+ });
42
+ remoteMain.enable(mainWindow.webContents);
43
+ const devUrl = `http://localhost:${options.port}/index.html`;
44
+ const fileUrl = `file://${path.join(options.build, 'index.html')}`;
45
+ console.log('[ELECTRON] build dir:', options.build);
46
+ console.log('[ELECTRON] index.html exists?', fs.existsSync(path.join(options.build, 'index.html')));
47
+ const url = options.mode === 'watch' ? devUrl : fileUrl;
48
+ console.log('[ELECTRON] Loading URL:', url);
49
+ console.log('[ELECTRON] Loading URL:', url);
50
+ mainWindow.loadURL(url);
51
+ mainWindow.webContents.once('did-finish-load', () => {
52
+ console.log('[ELECTRON] did-finish-load → show()');
53
+ mainWindow?.show();
54
+ mainWindow?.webContents.send('init', options);
55
+ });
56
+ mainWindow.on('closed', () => (mainWindow = null));
57
+ // mainWindow.webContents.openDevTools({ mode: 'detach' });
58
+ }
59
+ app.whenReady().then(() => {
60
+ console.log('[ELECTRON] App is ready');
61
+ createWindow();
62
+ app.on('activate', () => {
63
+ if (BrowserWindow.getAllWindows().length === 0) {
64
+ createWindow();
65
+ }
66
+ });
67
+ });
68
+ app.on('window-all-closed', () => app.quit());
package/dist/main.js CHANGED
@@ -1,6 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
- const commandLineArgs = require('command-line-args');
3
+ import commandLineArgs from 'command-line-args';
4
+ import path from 'path';
5
+ import webpack from 'webpack';
6
+ import WebpackDevServer from 'webpack-dev-server';
7
+ import { spawn, exec } from 'child_process';
8
+ import { fileURLToPath } from 'url';
9
+ import fs from 'fs';
10
+ import archiver from 'archiver';
11
+ import clc from 'cli-color';
12
+ import { Configuration } from '@vixoniccom/modules';
13
+ import tsNode from 'ts-node';
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+ const electronPath = path.join(__dirname, 'electron.js');
17
+ // import pjson from '../package.json' assert { type: 'json' }
18
+ // console.log(`VIXONIC PACKAGER: Version ${pjson.version}`)
4
19
  const optionDefinitions = [
5
20
  { name: 'externals', type: String, defaultValue: [], multiple: true },
6
21
  { name: 'target', type: String, defaultValue: 'web' },
@@ -14,22 +29,11 @@ const optionDefinitions = [
14
29
  { name: 'tsOverride', type: Boolean }
15
30
  ];
16
31
  const options = commandLineArgs(optionDefinitions);
17
- const path = require('path');
18
- const webpack = require('webpack');
19
- const WebpackDevServer = require('webpack-dev-server');
20
- const { exec } = require('child_process');
21
- const electronPath = path.resolve(__dirname, '..', 'electron.js');
22
- const fs = require('fs');
23
- const archiver = require('archiver');
24
- const clc = require('cli-color');
25
- const pjson = require(path.resolve(__dirname, '../package.json'));
26
- console.log(`VIXONIC PACKAGER: Version ${pjson.version}`);
27
32
  if (options.target !== 'electron-renderer' && options.externals.length > 0) {
28
33
  throw new Error(`Can't use external dependencies if target is not electron-renderer.`);
29
34
  }
30
35
  if (options.mode === 'build') {
31
36
  pack(() => {
32
- // Install externals only if not web.
33
37
  if (options.target === 'electron-renderer') {
34
38
  installExternals(() => {
35
39
  zip();
@@ -41,6 +45,7 @@ if (options.mode === 'build') {
41
45
  });
42
46
  }
43
47
  else if (options.mode === 'watch') {
48
+ console.log('[DEBUG] Entrando a watch()');
44
49
  watch();
45
50
  }
46
51
  else if (options.mode === 'run') {
@@ -52,50 +57,75 @@ else if (options.mode === 'generate-configuration') {
52
57
  else if (options.mode === 'validate-configuration') {
53
58
  validateConfiguration();
54
59
  }
55
- function pack(callback) {
60
+ function runElectron() {
61
+ const electronProcess = spawn('npx', [
62
+ 'electron',
63
+ electronPath,
64
+ '--src', path.resolve(options.src),
65
+ '--build', path.resolve(options.build),
66
+ '--port', `${options.port}`,
67
+ '--mode', options.mode,
68
+ '--config', options.config,
69
+ '--externals', options.externals.join(',')
70
+ ], {
71
+ cwd: __dirname,
72
+ env: { ...process.env, NODE_ENV: 'development' },
73
+ stdio: 'inherit'
74
+ });
75
+ electronProcess.on('close', (code) => {
76
+ console.log(`Electron process exited with code ${code}`);
77
+ if (code !== 0) {
78
+ console.error('Electron process exited with an error.');
79
+ }
80
+ });
81
+ }
82
+ async function pack(callback) {
56
83
  console.log(clc.blue('Building module...'));
57
84
  validateConfiguration();
58
85
  const configPath = path.resolve(__dirname, '../', options.config);
59
- webpack(require(options.config)(options), function (err, stats) {
60
- if (err) {
61
- // Imprime el error como string y con detalles si existen
62
- console.error('Build error:', err);
63
- if (err.details) {
64
- console.error('Details:', err.details);
65
- }
66
- if (err.errors) {
67
- console.error('TS Errors:', JSON.stringify(err.errors, null, 2));
68
- }
69
- throw err;
70
- }
71
- else {
72
- if (stats.hasErrors()) {
73
- // Imprime los errores de Webpack de forma legible
74
- const info = stats.toJson('errors-only');
75
- console.error(clc.red('Webpack errors:'));
76
- if (info.errors && info.errors.length) {
77
- info.errors.forEach((e) => {
78
- console.error(clc.red(typeof e === 'object' ? JSON.stringify(e, null, 2) : e));
79
- });
86
+ try {
87
+ const webpackConfig = (await import(configPath)).default(options);
88
+ webpack(webpackConfig, function (err, stats) {
89
+ if (err) {
90
+ console.error('Build error:', err);
91
+ if (err.details) {
92
+ console.error('Details:', err.details);
80
93
  }
81
- else {
82
- console.error(clc.red(JSON.stringify(info, null, 2)));
94
+ if (err.errors) {
95
+ console.error('TS Errors:', JSON.stringify(err.errors, null, 2));
83
96
  }
84
- callback && callback(stats);
97
+ throw err;
85
98
  }
86
99
  else {
87
- console.log(clc.green('Build OK.'));
88
- callback && callback(null);
100
+ if (stats.hasErrors()) {
101
+ const info = stats.toJson('errors-only');
102
+ console.error(clc.red('Webpack errors:'));
103
+ if (info.errors && info.errors.length) {
104
+ info.errors.forEach((e) => {
105
+ console.error(clc.red(typeof e === 'object' ? JSON.stringify(e, null, 2) : e));
106
+ });
107
+ }
108
+ else {
109
+ console.error(clc.red(JSON.stringify(info, null, 2)));
110
+ }
111
+ callback && callback(stats);
112
+ }
113
+ else {
114
+ console.log(clc.green('Build OK.'));
115
+ callback && callback(null);
116
+ }
89
117
  }
90
- }
91
- });
118
+ });
119
+ }
120
+ catch (e) {
121
+ console.error(clc.red('Failed to load webpack config'));
122
+ throw e;
123
+ }
92
124
  }
93
125
  function installExternals(callback) {
94
- // Get external versions.
95
126
  let externals = options.externals.map((x) => {
96
- return `${x}@${JSON.parse(fs.readFileSync(path.resolve(options.src, '..', 'node_modules', x, 'package.json'))).version}`;
127
+ return `${x}@${JSON.parse(fs.readFileSync(path.resolve(options.src, '..', 'node_modules', x, 'package.json'), 'utf8')).version}`;
97
128
  });
98
- // Install external versions.
99
129
  if (externals.length) {
100
130
  externals = externals.join(' ');
101
131
  console.log(clc.blue(`Installing externals ${externals}...`));
@@ -127,37 +157,31 @@ function zip() {
127
157
  });
128
158
  clc.move(-2, 0);
129
159
  }
130
- function watch() {
131
- const devServerOptions = {
132
- static: path.join(__dirname, options.src, '..'),
133
- port: options.port
134
- };
135
- let webpackConfigPath;
136
- try {
137
- webpackConfigPath = path.resolve(process.cwd(), options.config);
138
- require.resolve(webpackConfigPath);
139
- }
140
- catch (e) {
141
- webpackConfigPath = path.resolve(__dirname, options.config);
142
- }
143
- const compiler = webpack(require(webpackConfigPath)(options));
144
- const server = new WebpackDevServer(devServerOptions, compiler);
145
- server.start().then(() => {
146
- console.log(`Dev server is listening on port ${options.port}`);
147
- });
148
- var environment = process.env;
149
- environment.NODE_ENV = 'development';
150
- console.log(`build ${path.resolve(options.build)}`);
151
- console.log('[DEBUG] Ejecutando Electron con comando:');
152
- console.log(`npx electron ${electronPath} --src ${path.resolve(options.src)} --build ${path.resolve(options.build)} --port ${options.port} --mode ${options.mode} --config ${options.config} --externals ${options.externals}`);
153
- exec(`npx electron ${electronPath} --src ${path.resolve(options.src)} --build ${path.resolve(options.build)} --port ${options.port} --mode ${options.mode} --config ${options.config} --externals ${options.externals}`, {
154
- cwd: __dirname,
155
- env: environment
156
- }, (err) => {
157
- if (err)
158
- throw err;
159
- process.exit();
160
- });
160
+ async function watch() {
161
+ console.log('[VMP] ▸ starting dev-server & electron in watch mode…');
162
+ // 1 Localiza SIEMPRE la config del propio paquete (…/webpack.config.mjs)
163
+ const cfgPath = path.resolve(__dirname, '..', 'webpack.config.js');
164
+ const webpackConfigFactory = (await import(cfgPath)).default;
165
+ // 2 Levanta webpack-dev-server
166
+ const compiler = webpack(webpackConfigFactory(options));
167
+ const server = new WebpackDevServer({ static: path.join(__dirname, options.src, '..'), port: options.port }, compiler);
168
+ await server.start();
169
+ console.log(`[VMP] ▸ dev-server listening on http://localhost:${options.port}`);
170
+ // 3 Lanza Electron con npx (igual que antes)
171
+ const cmd = [
172
+ 'npx', 'electron', electronPath,
173
+ '--src', path.resolve(options.src),
174
+ '--build', path.resolve(options.build),
175
+ '--port', String(options.port),
176
+ '--mode', 'watch',
177
+ '--config', options.config,
178
+ '--externals', options.externals.join(',')
179
+ ].join(' ');
180
+ console.log(`[VMP] ▸ ${cmd}`);
181
+ const child = exec(cmd, { cwd: __dirname, env: { ...process.env, NODE_ENV: 'development' } });
182
+ // redirige STDOUT/STDERR a la consola del packager
183
+ child.stdout?.pipe(process.stdout);
184
+ child.stderr?.pipe(process.stderr);
161
185
  }
162
186
  function run() {
163
187
  pack((err) => {
@@ -165,15 +189,19 @@ function run() {
165
189
  throw err;
166
190
  }
167
191
  else {
168
- exec(`npx electron ${electronPath} --src ${path.resolve(options.src)} --build ${path.resolve(options.build)} --port ${options.port} --mode ${options.mode} --config ${options.config} --externals ${options.externals}`, {
169
- cwd: __dirname
170
- });
192
+ runElectron();
171
193
  }
172
194
  });
173
195
  }
174
196
  function loadConfiguration() {
175
- require('@vixoniccom/modules');
176
- require('ts-node').register({ compilerOptions: { moduleResolution: 'node', module: 'commonjs', target: 'es2015', checkJs: false } });
197
+ tsNode.register({
198
+ compilerOptions: {
199
+ moduleResolution: 'node',
200
+ module: 'commonjs',
201
+ target: 'es2015',
202
+ checkJs: false
203
+ }
204
+ });
177
205
  return require(path.resolve(options.confDefinition, 'index.ts')).configuration;
178
206
  }
179
207
  function generateConfiguration() {
@@ -190,11 +218,12 @@ function generateConfiguration() {
190
218
  }
191
219
  function validateConfiguration() {
192
220
  try {
193
- const { Configuration } = require('@vixoniccom/modules');
194
- const json = require(path.resolve(options.src, '../', 'configuration.json'));
221
+ const jsonPath = path.resolve(options.src, '../', 'configuration.json');
222
+ const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); // Leer y parsear el archivo JSON
195
223
  const conf = Configuration.fromJSON(json);
196
224
  if (conf.durationFormula) {
197
- const values = require(path.resolve(options.src, 'test', 'parameters.json'));
225
+ const valuesPath = path.resolve(options.src, 'test', 'parameters.json');
226
+ const values = JSON.parse(fs.readFileSync(valuesPath, 'utf8')); // Leer y parsear otro archivo JSON
198
227
  console.log('Validate duration');
199
228
  console.log('Duration on undefined:', conf.getDuration({}), 'seconds');
200
229
  console.log('Duration:', conf.getDuration(values.parameters), 'seconds');
@@ -1,112 +1,144 @@
1
- const path = require('path')
2
- const HtmlWebpackPlugin = require('html-webpack-plugin')
3
- const { CleanWebpackPlugin } = require('clean-webpack-plugin')
4
- const CopyWebpackPlugin = require('copy-webpack-plugin')
5
- const TerserPlugin = require('terser-webpack-plugin')
6
-
7
- module.exports = (options) => {
8
- const isDev = options.mode === 'watch'
9
- const buildPath = path.resolve(options.build)
10
- const controllerHtmlPath = path.resolve(options.src, 'index.html')
11
- const controllerStaticPath = path.resolve(path.dirname(controllerHtmlPath), '../static')
12
- const controllerFontsPath = path.resolve(path.dirname(controllerHtmlPath), '../fonts')
13
-
14
- return {
15
- mode: isDev ? 'development' : 'production',
16
- target: 'electron-renderer',
17
- entry: path.resolve(options.src, 'main'),
18
- output: {
19
- path: buildPath,
20
- filename: '[name].bundle.js',
21
- publicPath: '/'
22
- },
23
- resolve: {
24
- extensions: ['.tsx', '.ts', '.js', '.jsx', '.mjs'],
25
- mainFields: ['module', 'browser', 'main'],
26
- fullySpecified: false,
27
- modules: [
28
- 'node_modules',
29
- path.resolve(__dirname, '../../node_modules')
30
- ]
31
- },
32
- module: {
33
- rules: [
34
- {
35
- test: /\.(ts|tsx|js|jsx)$/,
36
- exclude: /node_modules/,
37
- use: {
38
- loader: 'babel-loader',
39
- options: {
40
- presets: [
41
- '@babel/preset-env',
42
- '@babel/preset-react',
43
- '@babel/preset-typescript'
44
- ]
45
- }
46
- }
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import HtmlWebpackPlugin from 'html-webpack-plugin';
4
+ import { CleanWebpackPlugin } from 'clean-webpack-plugin';
5
+ import CopyWebpackPlugin from 'copy-webpack-plugin';
6
+ import TerserPlugin from 'terser-webpack-plugin';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+ export default (env = {}, argv = {}) => {
10
+ const options = {
11
+ src: env.src ?? './src',
12
+ build: env.build ?? './build',
13
+ port: env.port ?? 8080,
14
+ mode: argv.mode ?? 'production',
15
+ };
16
+ const isDev = options.mode === 'watch';
17
+ const buildPath = path.resolve(options.build);
18
+ const controllerHtmlPath = path.resolve(options.src, 'index.html');
19
+ console.log("🚀 ~ controllerHtmlPath:", controllerHtmlPath);
20
+ const controllerStaticPath = path.resolve(path.dirname(controllerHtmlPath), '../static');
21
+ const controllerFontsPath = path.resolve(path.dirname(controllerHtmlPath), '../fonts');
22
+ return {
23
+ mode: isDev ? 'development' : 'production',
24
+ target: 'electron-renderer',
25
+ entry: path.resolve(options.src, 'main.ts'),
26
+ output: {
27
+ path: buildPath,
28
+ filename: '[name].bundle.js',
29
+ publicPath: '/'
47
30
  },
48
- {
49
- test: /\.css$/,
50
- use: ['style-loader', 'css-loader'],
51
- exclude: /node_modules/
31
+ externals: {
32
+ '@vixoniccom/module-controller': 'commonjs @vixoniccom/module-controller',
33
+ webpack: 'commonjs webpack',
34
+ 'terser-webpack-plugin': 'commonjs terser-webpack-plugin',
35
+ esbuild: 'commonjs esbuild',
36
+ '@swc/core': 'commonjs @swc/core',
37
+ '@swc/wasm': 'commonjs @swc/wasm'
52
38
  },
53
- {
54
- test: /\.(png|jpe?g|gif|svg|woff2?|ttf|eot)$/,
55
- type: 'asset/resource',
56
- generator: {
57
- filename: 'assets/[hash][ext][query]'
58
- }
39
+ resolve: {
40
+ extensions: ['.tsx', '.ts', '.js', '.jsx', '.mjs'],
41
+ mainFields: ['module', 'browser', 'main'],
42
+ fullySpecified: false,
43
+ modules: [
44
+ 'node_modules',
45
+ path.resolve(__dirname, '../../node_modules')
46
+ ]
59
47
  },
60
- {
61
- test: /\.html$/,
62
- use: {
63
- loader: 'html-loader',
64
- options: {
65
- sources: false,
66
- }
67
- }
68
- }
69
- ]
70
- },
71
- plugins: [
72
- new CleanWebpackPlugin(),
73
- new HtmlWebpackPlugin({
74
- template: controllerHtmlPath,
75
- inject: 'body'
76
- }),
77
- new CopyWebpackPlugin({
78
- patterns: [
79
- { from: controllerStaticPath, to: 'static', noErrorOnMissing: true },
80
- { from: controllerFontsPath, to: 'fonts', noErrorOnMissing: true }
81
- ]
82
- })
83
- ],
84
- optimization: isDev ? undefined : {
85
- minimize: true,
86
- minimizer: [
87
- new TerserPlugin({
88
- extractComments: false,
89
- terserOptions: {
90
- format: {
91
- comments: false
48
+ module: {
49
+ rules: [
50
+ {
51
+ test: /\.(ts|tsx|js|jsx)$/,
52
+ exclude: /node_modules/,
53
+ use: {
54
+ loader: 'ts-loader',
55
+ options: {
56
+ transpileOnly: true
57
+ }
58
+ }
59
+ },
60
+ {
61
+ test: /\.s[ac]ss$/,
62
+ use: ['style-loader', 'css-loader', 'sass-loader']
63
+ },
64
+ {
65
+ test: /\.jsx?$/,
66
+ exclude: /node_modules/,
67
+ use: {
68
+ loader: 'ts-loader',
69
+ options: {
70
+ allowTsInNodeModules: true
71
+ }
72
+ }
73
+ },
74
+ {
75
+ test: /\.css$/,
76
+ use: ['style-loader', 'css-loader'],
77
+ exclude: /node_modules/
78
+ },
79
+ {
80
+ test: /\.(png|jpe?g|gif|svg|woff2?|ttf|eot)$/,
81
+ type: 'asset/resource',
82
+ generator: {
83
+ filename: 'assets/[hash][ext][query]'
84
+ }
85
+ },
86
+ {
87
+ test: /\.html$/,
88
+ use: {
89
+ loader: 'html-loader',
90
+ options: {
91
+ sources: false,
92
+ }
93
+ }
94
+ }
95
+ ]
96
+ },
97
+ plugins: [
98
+ new CleanWebpackPlugin(),
99
+ new HtmlWebpackPlugin({
100
+ template: controllerHtmlPath,
101
+ filename: 'index.html',
102
+ inject: 'body',
103
+ chunks: ['main']
104
+ }),
105
+ new CopyWebpackPlugin({
106
+ patterns: [
107
+ { from: controllerStaticPath, to: 'static', noErrorOnMissing: true },
108
+ { from: controllerFontsPath, to: 'fonts', noErrorOnMissing: true }
109
+ ]
110
+ })
111
+ ],
112
+ optimization: isDev ? undefined : {
113
+ minimize: false,
114
+ minimizer: [
115
+ new TerserPlugin({
116
+ minify: TerserPlugin.terserMinify,
117
+ terserOptions: {
118
+ ecma: 2020,
119
+ compress: true,
120
+ mangle: true,
121
+ format: { comments: false }
122
+ }
123
+ })
124
+ ]
125
+ },
126
+ devtool: isDev ? 'source-map' : false,
127
+ devServer: isDev ? {
128
+ static: {
129
+ directory: path.resolve(options.src)
130
+ },
131
+ open: false,
132
+ client: {
133
+ overlay: true
92
134
  },
93
- compress: true,
94
- mangle: true
95
- }
96
- })
97
- ]
98
- },
99
- devtool: isDev ? 'source-map' : false,
100
- devServer: isDev ? {
101
- static: {
102
- directory: path.resolve(options.src)
103
- },
104
- port: options.port || 8080,
105
- hot: true,
106
- historyApiFallback: true,
107
- devMiddleware: {
108
- publicPath: '/'
109
- }
110
- } : undefined
111
- }
112
- }
135
+ port: options.port || 8080,
136
+ hot: true,
137
+ historyApiFallback: true,
138
+ devMiddleware: {
139
+ publicPath: '/',
140
+ writeToDisk: false
141
+ }
142
+ } : undefined
143
+ };
144
+ };