@vixoniccom/module-packager 2.11.0-dev.9 → 2.11.0-just4dev.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/.babelrc +3 -0
- package/.eslintrc +3 -0
- package/CHANGELOG.md +499 -0
- package/electron.js +50 -0
- package/index.html +64 -0
- package/main.js +182 -0
- package/package.json +94 -51
- package/tsconfig.json +16 -0
- package/webpack.config.js +154 -0
- package/dist/electron.js +0 -58
- package/dist/launcher.html +0 -86
- package/dist/main.js +0 -323
- package/dist/webpack.config.js +0 -153
package/dist/main.js
DELETED
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
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 } 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
|
-
import { createRequire } from 'module';
|
|
15
|
-
import which from 'which';
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = path.dirname(__filename);
|
|
18
|
-
const electronPath = path.join(__dirname, 'electron.js');
|
|
19
|
-
const npxPath = which.sync('npx');
|
|
20
|
-
const optionDefinitions = [
|
|
21
|
-
{ name: 'externals', type: String, defaultValue: [], multiple: true },
|
|
22
|
-
{ name: 'target', type: String, defaultValue: 'web' },
|
|
23
|
-
{ name: 'src', type: String, defaultValue: './src' },
|
|
24
|
-
{ name: 'build', type: String, defaultValue: './build' },
|
|
25
|
-
{ name: 'confDefinition', type: String, defaultValue: './configuration' },
|
|
26
|
-
{ name: 'config', type: String, defaultValue: './webpack.config.js' },
|
|
27
|
-
{ name: 'port', type: Number, defaultValue: 8080 },
|
|
28
|
-
{ name: 'mode', type: String, defaultValue: 'build' },
|
|
29
|
-
{ name: 'transpileOnly', type: Boolean },
|
|
30
|
-
{ name: 'tsOverride', type: Boolean }
|
|
31
|
-
];
|
|
32
|
-
const options = commandLineArgs(optionDefinitions);
|
|
33
|
-
// Validación de entrada mejorada
|
|
34
|
-
function validateOptions(options) {
|
|
35
|
-
if (options.target !== 'electron-renderer' && options.externals.length > 0) {
|
|
36
|
-
throw new Error(`Can't use external dependencies if target is not electron-renderer.`);
|
|
37
|
-
}
|
|
38
|
-
// Validar puerto
|
|
39
|
-
if (options.port < 1 || options.port > 65535) {
|
|
40
|
-
throw new Error('Port must be between 1 and 65535');
|
|
41
|
-
}
|
|
42
|
-
// Validar modo
|
|
43
|
-
const validModes = ['build', 'watch', 'run', 'generate-configuration', 'validate-configuration'];
|
|
44
|
-
if (!validModes.includes(options.mode)) {
|
|
45
|
-
throw new Error(`Invalid mode. Must be one of: ${validModes.join(', ')}`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Función para sanitizar rutas
|
|
49
|
-
function sanitizePath(inputPath) {
|
|
50
|
-
// Prevenir path traversal
|
|
51
|
-
if (inputPath.includes('..') || inputPath.includes('~')) {
|
|
52
|
-
throw new Error('Invalid path: path traversal detected');
|
|
53
|
-
}
|
|
54
|
-
return path.resolve(inputPath);
|
|
55
|
-
}
|
|
56
|
-
// Función centralizada para crear argumentos de Electron
|
|
57
|
-
function createElectronArgs(mode) {
|
|
58
|
-
return [
|
|
59
|
-
electronPath,
|
|
60
|
-
'--src', sanitizePath(options.src),
|
|
61
|
-
'--build', sanitizePath(options.build),
|
|
62
|
-
'--port', String(options.port),
|
|
63
|
-
'--mode', mode,
|
|
64
|
-
'--config', options.config,
|
|
65
|
-
'--externals', Array.isArray(options.externals) ? options.externals.join(',') : ''
|
|
66
|
-
];
|
|
67
|
-
}
|
|
68
|
-
// Función centralizada para manejar procesos Electron
|
|
69
|
-
function spawnElectronProcess(mode) {
|
|
70
|
-
const args = createElectronArgs(mode);
|
|
71
|
-
const nodeEnv = mode === 'run' ? 'production' : 'development';
|
|
72
|
-
const child = spawn(npxPath, ['electron', ...args], {
|
|
73
|
-
cwd: __dirname,
|
|
74
|
-
env: {
|
|
75
|
-
...process.env,
|
|
76
|
-
NODE_ENV: nodeEnv,
|
|
77
|
-
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
|
|
78
|
-
NODE_NO_WARNINGS: '1'
|
|
79
|
-
},
|
|
80
|
-
stdio: 'inherit'
|
|
81
|
-
});
|
|
82
|
-
// Manejo centralizado de logs
|
|
83
|
-
setupChildProcessLogging(child);
|
|
84
|
-
return child;
|
|
85
|
-
}
|
|
86
|
-
// Función para manejar logging de procesos hijo
|
|
87
|
-
function setupChildProcessLogging(child) {
|
|
88
|
-
child.stdout?.on('data', (data) => {
|
|
89
|
-
const output = data.toString();
|
|
90
|
-
if (!shouldFilterLog(output)) {
|
|
91
|
-
process.stdout.write(output);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
child.stderr?.on('data', (data) => {
|
|
95
|
-
const output = data.toString();
|
|
96
|
-
if (!shouldFilterLog(output)) {
|
|
97
|
-
process.stderr.write(output);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
// Función centralizada para compilar webpack
|
|
102
|
-
async function compileWebpack() {
|
|
103
|
-
// CORREGIDO: Usar __dirname para el webpack.config.js del module-packager
|
|
104
|
-
const cfgPath = path.resolve(__dirname, 'webpack.config.js');
|
|
105
|
-
const webpackConfigFactory = (await import(cfgPath)).default;
|
|
106
|
-
const compiler = webpack(webpackConfigFactory(options));
|
|
107
|
-
return new Promise((resolve, reject) => {
|
|
108
|
-
compiler.run((err, stats) => {
|
|
109
|
-
if (err)
|
|
110
|
-
return reject(err);
|
|
111
|
-
if (stats?.hasErrors()) {
|
|
112
|
-
return reject(new Error(stats.toString({ all: false, errors: true, colors: true })));
|
|
113
|
-
}
|
|
114
|
-
compiler.close(closeErr => (closeErr ? reject(closeErr) : resolve()));
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
validateOptions(options);
|
|
119
|
-
if (options.mode === 'build') {
|
|
120
|
-
pack(() => {
|
|
121
|
-
if (options.target === 'electron-renderer') {
|
|
122
|
-
installExternals(() => {
|
|
123
|
-
zip();
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
zip();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
else if (options.mode === 'watch') {
|
|
132
|
-
watch();
|
|
133
|
-
}
|
|
134
|
-
else if (options.mode === 'run') {
|
|
135
|
-
run();
|
|
136
|
-
}
|
|
137
|
-
else if (options.mode === 'generate-configuration') {
|
|
138
|
-
await generateConfiguration();
|
|
139
|
-
}
|
|
140
|
-
else if (options.mode === 'validate-configuration') {
|
|
141
|
-
validateConfiguration();
|
|
142
|
-
}
|
|
143
|
-
async function pack(callback) {
|
|
144
|
-
console.log(clc.blue('Building module...'));
|
|
145
|
-
validateConfiguration();
|
|
146
|
-
const configPath = path.resolve(__dirname, options.config);
|
|
147
|
-
console.log("🚀 ~ pack ~ configPath:", configPath);
|
|
148
|
-
try {
|
|
149
|
-
const webpackConfig = (await import(configPath)).default(options);
|
|
150
|
-
function handleWebpackError(err) {
|
|
151
|
-
console.error('Build error:', err);
|
|
152
|
-
if (err.details) {
|
|
153
|
-
console.error('Details:', err.details);
|
|
154
|
-
}
|
|
155
|
-
if (err.errors) {
|
|
156
|
-
console.error('TS Errors:', JSON.stringify(err.errors, null, 2));
|
|
157
|
-
}
|
|
158
|
-
throw err;
|
|
159
|
-
}
|
|
160
|
-
function handleWebpackStats(stats, callback) {
|
|
161
|
-
if (stats.hasErrors()) {
|
|
162
|
-
const info = stats.toJson('errors-only');
|
|
163
|
-
console.error(clc.red('Webpack errors:'));
|
|
164
|
-
if (info.errors?.length) {
|
|
165
|
-
info.errors.forEach((e) => {
|
|
166
|
-
console.error(clc.red(typeof e === 'object' ? JSON.stringify(e, null, 2) : e));
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
console.error(clc.red(JSON.stringify(info, null, 2)));
|
|
171
|
-
}
|
|
172
|
-
callback?.(stats);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
console.log(clc.green('Build OK.'));
|
|
176
|
-
callback?.(null);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
webpack(webpackConfig, function (err, stats) {
|
|
180
|
-
if (err) {
|
|
181
|
-
handleWebpackError(err);
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
handleWebpackStats(stats, callback);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
catch (e) {
|
|
189
|
-
console.error(clc.red('Failed to load webpack config'));
|
|
190
|
-
throw e;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
function installExternals(callback) {
|
|
194
|
-
let externals = options.externals.map((x) => {
|
|
195
|
-
// Validar nombre del paquete
|
|
196
|
-
if (!/^[@a-z0-9-_./]+$/i.test(x)) {
|
|
197
|
-
throw new Error(`Invalid package name: ${x}`);
|
|
198
|
-
}
|
|
199
|
-
const packageJsonPath = sanitizePath(path.resolve(options.src, '..', 'node_modules', x, 'package.json'));
|
|
200
|
-
return `${x}@${JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')).version}`;
|
|
201
|
-
});
|
|
202
|
-
if (externals.length) {
|
|
203
|
-
console.log(clc.blue(`Installing externals ${externals.join(', ')}...`));
|
|
204
|
-
const npmPath = which.sync('npm');
|
|
205
|
-
const child = spawn(npmPath, ['install', '--prefix', './', '--production', ...externals], { cwd: sanitizePath(options.build), stdio: 'inherit' });
|
|
206
|
-
child.on('exit', (code) => {
|
|
207
|
-
if (code !== 0) {
|
|
208
|
-
return callback?.(new Error(`npm install failed with code ${code}`));
|
|
209
|
-
}
|
|
210
|
-
console.log(clc.green('Externals installed.'));
|
|
211
|
-
callback?.(null);
|
|
212
|
-
});
|
|
213
|
-
child.on('error', (err) => {
|
|
214
|
-
callback?.(err);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
callback?.(null);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function zip() {
|
|
222
|
-
console.log(clc.blue('Archiving...'));
|
|
223
|
-
console.log(clc.blue('Cleaning build...'));
|
|
224
|
-
const buildPath = sanitizePath(options.build);
|
|
225
|
-
const zipPath = path.resolve(buildPath, '../', 'build.zip');
|
|
226
|
-
console.log("[DEBUG] Cleaning build folder", zipPath);
|
|
227
|
-
let output = fs.createWriteStream(zipPath);
|
|
228
|
-
let archive = archiver('zip');
|
|
229
|
-
archive.pipe(output);
|
|
230
|
-
archive.directory(buildPath, './');
|
|
231
|
-
archive.finalize();
|
|
232
|
-
output.on('close', function () {
|
|
233
|
-
console.log(clc.green('Generated build.zip.'));
|
|
234
|
-
});
|
|
235
|
-
archive.on('error', function (err) {
|
|
236
|
-
throw err;
|
|
237
|
-
});
|
|
238
|
-
clc.move(-2, 0);
|
|
239
|
-
}
|
|
240
|
-
async function watch() {
|
|
241
|
-
// CORREGIDO: Usar __dirname para el webpack.config.js del module-packager
|
|
242
|
-
const cfgPath = path.resolve(__dirname, 'webpack.config.js');
|
|
243
|
-
const webpackConfigFactory = (await import(cfgPath)).default;
|
|
244
|
-
const compiler = webpack(webpackConfigFactory(options));
|
|
245
|
-
const server = new WebpackDevServer({
|
|
246
|
-
static: false,
|
|
247
|
-
port: options.port,
|
|
248
|
-
devMiddleware: { publicPath: '/' },
|
|
249
|
-
historyApiFallback: true
|
|
250
|
-
}, compiler);
|
|
251
|
-
await server.start();
|
|
252
|
-
spawnElectronProcess('watch');
|
|
253
|
-
}
|
|
254
|
-
async function run() {
|
|
255
|
-
await new Promise((resolve) => pack((err) => (err ? console.log(err) : resolve())));
|
|
256
|
-
await compileWebpack();
|
|
257
|
-
spawnElectronProcess('run');
|
|
258
|
-
}
|
|
259
|
-
async function loadConfiguration() {
|
|
260
|
-
const require = createRequire(import.meta.url);
|
|
261
|
-
tsNode.register({
|
|
262
|
-
compilerOptions: {
|
|
263
|
-
moduleResolution: 'node',
|
|
264
|
-
module: 'commonjs',
|
|
265
|
-
target: 'es2015',
|
|
266
|
-
checkJs: false
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
const configPath = sanitizePath(path.resolve(options.confDefinition, 'index.ts'));
|
|
270
|
-
return require(configPath).configuration;
|
|
271
|
-
}
|
|
272
|
-
async function generateConfiguration() {
|
|
273
|
-
try {
|
|
274
|
-
let configuration = await loadConfiguration();
|
|
275
|
-
const srcPath = sanitizePath(options.src);
|
|
276
|
-
fs.writeFileSync(path.resolve(srcPath, 'parameters.d.ts'), configuration.declarationFileString);
|
|
277
|
-
fs.writeFileSync(path.resolve(srcPath, '..', 'configuration.json'), JSON.stringify(configuration, undefined, 2));
|
|
278
|
-
console.log(clc.green(`Configuration generated`));
|
|
279
|
-
}
|
|
280
|
-
catch (e) {
|
|
281
|
-
console.log(clc.red('Configuration generation failed'));
|
|
282
|
-
throw e;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function validateConfiguration() {
|
|
286
|
-
try {
|
|
287
|
-
const srcPath = sanitizePath(options.src);
|
|
288
|
-
const jsonPath = path.resolve(srcPath, '../', 'configuration.json');
|
|
289
|
-
const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
|
|
290
|
-
const conf = Configuration.fromJSON(json);
|
|
291
|
-
if (conf.durationFormula) {
|
|
292
|
-
const valuesPath = path.resolve(srcPath, 'test', 'parameters.json');
|
|
293
|
-
const values = JSON.parse(fs.readFileSync(valuesPath, 'utf8'));
|
|
294
|
-
console.log('Validate duration');
|
|
295
|
-
console.log('Duration on undefined:', conf.getDuration({}), 'seconds');
|
|
296
|
-
console.log('Duration:', conf.getDuration(values.parameters), 'seconds');
|
|
297
|
-
}
|
|
298
|
-
console.log(clc.green('Valid configuration'));
|
|
299
|
-
}
|
|
300
|
-
catch (e) {
|
|
301
|
-
console.log(clc.red('Invalid configuration'));
|
|
302
|
-
throw e;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
function shouldFilterLog(output) {
|
|
306
|
-
const filtersToRemove = [
|
|
307
|
-
"'session.getAllExtensions' is deprecated",
|
|
308
|
-
"DeprecationWarning: Compilation.assets will be frozen",
|
|
309
|
-
"BREAKING CHANGE: No more changes should happen to Compilation.assets",
|
|
310
|
-
"[DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning",
|
|
311
|
-
"Compilation.assets will be frozen in future",
|
|
312
|
-
"Request Autofill.enable failed",
|
|
313
|
-
"Request Autofill.setAddresses failed",
|
|
314
|
-
"Uncaught (in promise) SyntaxError",
|
|
315
|
-
"wasn't found",
|
|
316
|
-
"asset main.js",
|
|
317
|
-
"runtime modules",
|
|
318
|
-
"orphan modules",
|
|
319
|
-
"cacheable modules",
|
|
320
|
-
"webpack compiled successfully"
|
|
321
|
-
];
|
|
322
|
-
return filtersToRemove.some(filter => output.includes(filter));
|
|
323
|
-
}
|
package/dist/webpack.config.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
5
|
-
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
|
6
|
-
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
|
7
|
-
import TerserPlugin from 'terser-webpack-plugin';
|
|
8
|
-
import webpack from 'webpack';
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
console.log("🚀 ~ __dirname:", __dirname);
|
|
12
|
-
export default (env = {}, argv = {}) => {
|
|
13
|
-
const require = createRequire(import.meta.url);
|
|
14
|
-
const options = {
|
|
15
|
-
src: env.src ?? './src',
|
|
16
|
-
build: env.build ?? './build',
|
|
17
|
-
port: env.port ?? 8080,
|
|
18
|
-
mode: argv.mode ?? 'production',
|
|
19
|
-
};
|
|
20
|
-
const isDev = options.mode === 'watch';
|
|
21
|
-
const buildPath = path.resolve(options.build);
|
|
22
|
-
const controllerHtmlPath = path.resolve(options.src, 'index.html');
|
|
23
|
-
const controllerStaticPath = path.resolve(path.dirname(controllerHtmlPath), '../static');
|
|
24
|
-
const controllerFontsPath = path.resolve(path.dirname(controllerHtmlPath), '../fonts');
|
|
25
|
-
return {
|
|
26
|
-
mode: isDev ? 'development' : 'production',
|
|
27
|
-
target: 'electron-renderer',
|
|
28
|
-
entry: isDev ? [
|
|
29
|
-
`webpack-dev-server/client?http://localhost:${options.port}/`,
|
|
30
|
-
'webpack/hot/dev-server',
|
|
31
|
-
path.resolve(options.src, 'main.ts')
|
|
32
|
-
] : path.resolve(options.src, 'main.ts'),
|
|
33
|
-
output: {
|
|
34
|
-
path: buildPath,
|
|
35
|
-
filename: '[name].js',
|
|
36
|
-
publicPath: isDev ? '/' : './'
|
|
37
|
-
},
|
|
38
|
-
externals: {
|
|
39
|
-
electron: 'commonjs electron',
|
|
40
|
-
'@vixoniccom/module-controller': 'commonjs @vixoniccom/module-controller',
|
|
41
|
-
webpack: 'commonjs webpack',
|
|
42
|
-
'terser-webpack-plugin': 'commonjs terser-webpack-plugin',
|
|
43
|
-
esbuild: 'commonjs esbuild',
|
|
44
|
-
'@swc/core': 'commonjs @swc/core',
|
|
45
|
-
'@swc/wasm': 'commonjs @swc/wasm'
|
|
46
|
-
},
|
|
47
|
-
resolve: {
|
|
48
|
-
extensions: ['.tsx', '.ts', '.js', '.jsx', '.mjs'],
|
|
49
|
-
mainFields: ['module', 'browser', 'main'],
|
|
50
|
-
fullySpecified: false,
|
|
51
|
-
fallback: {
|
|
52
|
-
process: require.resolve('process/browser.js'),
|
|
53
|
-
global: require.resolve('global')
|
|
54
|
-
},
|
|
55
|
-
modules: ['node_modules', 'src', 'static']
|
|
56
|
-
},
|
|
57
|
-
module: {
|
|
58
|
-
rules: [
|
|
59
|
-
{
|
|
60
|
-
test: /\.(ts|tsx|js|jsx)$/,
|
|
61
|
-
exclude: /node_modules/,
|
|
62
|
-
use: {
|
|
63
|
-
loader: 'ts-loader',
|
|
64
|
-
options: {
|
|
65
|
-
transpileOnly: true
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
test: /\.s[ac]ss$/,
|
|
71
|
-
use: ['style-loader', 'css-loader', 'sass-loader']
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
test: /\.css$/,
|
|
75
|
-
use: ['style-loader', 'css-loader'],
|
|
76
|
-
exclude: /node_modules/
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|mp4)$/,
|
|
80
|
-
type: 'asset/resource',
|
|
81
|
-
generator: {
|
|
82
|
-
filename: '[name][ext]'
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
test: /\.html$/,
|
|
87
|
-
use: {
|
|
88
|
-
loader: 'html-loader',
|
|
89
|
-
options: {
|
|
90
|
-
sources: false,
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
plugins: [
|
|
97
|
-
new webpack.DefinePlugin({
|
|
98
|
-
global: 'globalThis'
|
|
99
|
-
}),
|
|
100
|
-
new webpack.ProvidePlugin({
|
|
101
|
-
process: 'process/browser.js'
|
|
102
|
-
}),
|
|
103
|
-
new CleanWebpackPlugin(),
|
|
104
|
-
new HtmlWebpackPlugin({
|
|
105
|
-
template: controllerHtmlPath,
|
|
106
|
-
filename: 'index.html',
|
|
107
|
-
inject: 'body',
|
|
108
|
-
chunks: ['main']
|
|
109
|
-
}),
|
|
110
|
-
new CopyWebpackPlugin({
|
|
111
|
-
patterns: [
|
|
112
|
-
{ from: controllerStaticPath, to: 'static', noErrorOnMissing: true },
|
|
113
|
-
{ from: controllerFontsPath, to: 'fonts', noErrorOnMissing: true }
|
|
114
|
-
]
|
|
115
|
-
})
|
|
116
|
-
],
|
|
117
|
-
optimization: isDev ? undefined : {
|
|
118
|
-
minimize: false,
|
|
119
|
-
minimizer: [
|
|
120
|
-
new TerserPlugin({
|
|
121
|
-
minify: TerserPlugin.terserMinify,
|
|
122
|
-
terserOptions: {
|
|
123
|
-
ecma: 2020,
|
|
124
|
-
compress: true,
|
|
125
|
-
mangle: true,
|
|
126
|
-
format: { comments: false }
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
]
|
|
130
|
-
},
|
|
131
|
-
devtool: isDev ? 'source-map' : false,
|
|
132
|
-
devServer: isDev ? {
|
|
133
|
-
static: [
|
|
134
|
-
{
|
|
135
|
-
directory: path.resolve(options.src, 'test'),
|
|
136
|
-
publicPath: '/test',
|
|
137
|
-
watch: true,
|
|
138
|
-
}
|
|
139
|
-
],
|
|
140
|
-
open: false,
|
|
141
|
-
client: {
|
|
142
|
-
overlay: true
|
|
143
|
-
},
|
|
144
|
-
port: options.port || 8080,
|
|
145
|
-
hot: true,
|
|
146
|
-
historyApiFallback: true,
|
|
147
|
-
devMiddleware: {
|
|
148
|
-
publicPath: '/',
|
|
149
|
-
writeToDisk: false
|
|
150
|
-
}
|
|
151
|
-
} : undefined
|
|
152
|
-
};
|
|
153
|
-
};
|