hightjs 0.3.5 → 0.5.0

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.
Files changed (123) hide show
  1. package/README.md +48 -116
  2. package/dist/bin/hightjs.js +51 -23
  3. package/dist/builder.js +198 -8
  4. package/dist/client/DefaultNotFound.d.ts +1 -1
  5. package/dist/client/DefaultNotFound.js +72 -46
  6. package/dist/client/client.d.ts +3 -0
  7. package/dist/{client.js → client/client.js} +4 -4
  8. package/dist/client/entry.client.js +77 -9
  9. package/dist/global/global.d.ts +117 -0
  10. package/dist/{auth/types.js → global/global.js} +0 -1
  11. package/dist/helpers.js +80 -2
  12. package/dist/hotReload.js +84 -4
  13. package/dist/index.js +72 -61
  14. package/dist/loaders.d.ts +1 -0
  15. package/dist/loaders.js +46 -0
  16. package/dist/renderer.js +158 -4
  17. package/dist/types.d.ts +44 -0
  18. package/package.json +37 -30
  19. package/.idea/HightJS.iml +0 -9
  20. package/.idea/copilot.data.migration.agent.xml +0 -6
  21. package/.idea/copilot.data.migration.ask.xml +0 -6
  22. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  23. package/.idea/copilot.data.migration.edit.xml +0 -6
  24. package/.idea/copilotDiffState.xml +0 -67
  25. package/.idea/inspectionProfiles/Project_Default.xml +0 -13
  26. package/.idea/libraries/test_package.xml +0 -9
  27. package/.idea/libraries/ts_commonjs_default_export.xml +0 -9
  28. package/.idea/misc.xml +0 -7
  29. package/.idea/modules.xml +0 -8
  30. package/.idea/vcs.xml +0 -6
  31. package/dist/auth/client.d.ts +0 -24
  32. package/dist/auth/client.js +0 -146
  33. package/dist/auth/components.d.ts +0 -29
  34. package/dist/auth/components.js +0 -100
  35. package/dist/auth/core.d.ts +0 -55
  36. package/dist/auth/core.js +0 -189
  37. package/dist/auth/index.d.ts +0 -7
  38. package/dist/auth/index.js +0 -45
  39. package/dist/auth/jwt.d.ts +0 -41
  40. package/dist/auth/jwt.js +0 -185
  41. package/dist/auth/providers/credentials.d.ts +0 -60
  42. package/dist/auth/providers/credentials.js +0 -97
  43. package/dist/auth/providers/discord.d.ts +0 -63
  44. package/dist/auth/providers/discord.js +0 -190
  45. package/dist/auth/providers/google.d.ts +0 -63
  46. package/dist/auth/providers/google.js +0 -186
  47. package/dist/auth/providers/index.d.ts +0 -2
  48. package/dist/auth/providers/index.js +0 -35
  49. package/dist/auth/providers.d.ts +0 -3
  50. package/dist/auth/providers.js +0 -26
  51. package/dist/auth/react/index.d.ts +0 -6
  52. package/dist/auth/react/index.js +0 -48
  53. package/dist/auth/react.d.ts +0 -22
  54. package/dist/auth/react.js +0 -199
  55. package/dist/auth/routes.d.ts +0 -16
  56. package/dist/auth/routes.js +0 -152
  57. package/dist/auth/types.d.ts +0 -76
  58. package/dist/client.d.ts +0 -3
  59. package/docs/README.md +0 -58
  60. package/docs/arquivos-especiais.md +0 -10
  61. package/docs/autenticacao.md +0 -212
  62. package/docs/checklist.md +0 -9
  63. package/docs/cli.md +0 -72
  64. package/docs/config.md +0 -216
  65. package/docs/estrutura.md +0 -20
  66. package/docs/faq.md +0 -10
  67. package/docs/hot-reload.md +0 -5
  68. package/docs/integracoes.md +0 -240
  69. package/docs/middlewares.md +0 -73
  70. package/docs/rotas-backend.md +0 -45
  71. package/docs/rotas-frontend.md +0 -66
  72. package/docs/seguranca.md +0 -8
  73. package/docs/websocket.md +0 -45
  74. package/example/certs/cert.pem +0 -20
  75. package/example/certs/key.pem +0 -27
  76. package/example/hightjs.config.ts +0 -87
  77. package/example/package-lock.json +0 -1174
  78. package/example/package.json +0 -26
  79. package/example/postcss.config.js +0 -8
  80. package/example/src/auth.ts +0 -42
  81. package/example/src/web/backend/routes/auth.ts +0 -3
  82. package/example/src/web/backend/routes/version.ts +0 -13
  83. package/example/src/web/globals.css +0 -5
  84. package/example/src/web/layout.tsx +0 -100
  85. package/example/src/web/routes/index.tsx +0 -153
  86. package/example/src/web/routes/login.tsx +0 -175
  87. package/example/tailwind.config.js +0 -12
  88. package/example/tsconfig.json +0 -15
  89. package/src/adapters/express.ts +0 -87
  90. package/src/adapters/factory.ts +0 -112
  91. package/src/adapters/fastify.ts +0 -104
  92. package/src/adapters/native.ts +0 -234
  93. package/src/api/console.ts +0 -305
  94. package/src/api/http.ts +0 -535
  95. package/src/auth/client.ts +0 -171
  96. package/src/auth/components.tsx +0 -125
  97. package/src/auth/core.ts +0 -215
  98. package/src/auth/index.ts +0 -25
  99. package/src/auth/jwt.ts +0 -210
  100. package/src/auth/providers/credentials.ts +0 -139
  101. package/src/auth/providers/discord.ts +0 -239
  102. package/src/auth/providers/google.ts +0 -234
  103. package/src/auth/providers/index.ts +0 -20
  104. package/src/auth/providers.ts +0 -20
  105. package/src/auth/react/index.ts +0 -25
  106. package/src/auth/react.tsx +0 -234
  107. package/src/auth/routes.ts +0 -183
  108. package/src/auth/types.ts +0 -108
  109. package/src/bin/hightjs.js +0 -222
  110. package/src/builder.js +0 -411
  111. package/src/client/DefaultNotFound.tsx +0 -84
  112. package/src/client/clientRouter.ts +0 -153
  113. package/src/client/entry.client.tsx +0 -444
  114. package/src/client.ts +0 -24
  115. package/src/components/Link.tsx +0 -38
  116. package/src/helpers.ts +0 -542
  117. package/src/hotReload.ts +0 -489
  118. package/src/index.ts +0 -546
  119. package/src/renderer.tsx +0 -263
  120. package/src/router.ts +0 -730
  121. package/src/types/framework.ts +0 -58
  122. package/src/types.ts +0 -207
  123. package/tsconfig.json +0 -17
@@ -1,222 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /*
4
- * This file is part of the HightJS Project.
5
- * Copyright (c) 2025 itsmuzin
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
-
20
-
21
- // Registra o ts-node para que o Node.js entenda TypeScript/TSX
22
- require('ts-node').register();
23
-
24
- const { program } = require('commander');
25
-
26
-
27
- program
28
- .version('1.0.0')
29
- .description('CLI to manage the application.');
30
-
31
- // --- Comando DEV ---
32
- const fs = require('fs');
33
- const path = require('path');
34
- // 'program' já deve estar definido no seu arquivo
35
- // const { program } = require('commander');
36
-
37
- /**
38
- * Função centralizada para iniciar a aplicação
39
- * @param {object} options - Opções vindas do commander
40
- * @param {boolean} isDev - Define se é modo de desenvolvimento
41
- */
42
- function initializeApp(options, isDev) {
43
- const appOptions = {
44
- dev: isDev,
45
- port: options.port,
46
- hostname: options.hostname,
47
- framework: 'native',
48
- ssl: null, // Default
49
- };
50
-
51
- // 1. Verifica se a flag --ssl foi ativada
52
- if (options.ssl) {
53
- const C = require("../api/console")
54
- const { Levels } = C;
55
- const Console = C.default
56
- const sslDir = path.resolve(process.cwd(), 'certs');
57
- const keyPath = path.join(sslDir, 'key.pem'); // Padrão 1: key.pem
58
- const certPath = path.join(sslDir, 'cert.pem'); // Padrão 2: cert.pem
59
- // (Você pode mudar para 'cert.key' se preferir, apenas ajuste os nomes aqui)
60
-
61
- // 2. Verifica se os arquivos existem
62
- if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
63
- appOptions.ssl = {
64
- key: keyPath,
65
- cert: certPath
66
- };
67
-
68
- // 3. Adiciona a porta de redirecionamento (útil para o initNativeServer)
69
- appOptions.ssl.redirectPort = options.httpRedirectPort || 80;
70
-
71
- } else {
72
- Console.logWithout(Levels.ERROR, null, `Ensure that './certs/key.pem' and './certs/cert.pem' exist.`, `--ssl flag was used, but the files were not found.`)
73
-
74
-
75
- process.exit(1); // Encerra o processo com erro
76
- }
77
- }
78
-
79
- // 4. Inicia o helper com as opções
80
- const teste = require("../helpers");
81
- const t = teste.default(appOptions);
82
- t.init();
83
- }
84
-
85
- // --- Comando DEV ---
86
- program
87
- .command('dev')
88
- .description('Starts the application in development mode.')
89
- .option('-p, --port <number>', 'Specifies the port to run on', '3000')
90
- .option('-H, --hostname <string>', 'Specifies the hostname to run on', '0.0.0.0')
91
- .option('--ssl', 'Activates HTTPS/SSL mode (requires ./ssl/key.pem and ./ssl/cert.pem)')
92
- .option('--http-redirect-port <number>', 'Port for HTTP->HTTPS redirection', '80')
93
- .action((options) => {
94
- initializeApp(options, true); // Chama a função com dev: true
95
- });
96
-
97
- // --- Comando START (Produção) ---
98
- program
99
- .command('start')
100
- .description('Starts the application in production mode.')
101
- .option('-p, --port <number>', 'Specifies the port to run on', '3000')
102
- .option('-H, --hostname <string>', 'Specifies the hostname to run on', '0.0.0.0')
103
- .option('--ssl', 'Activates HTTPS/SSL mode (requires ./ssl/key.pem and ./ssl/cert.pem)')
104
- .option('--http-redirect-port <number>', 'Port for HTTP->HTTPS redirection', '80')
105
- .action((options) => {
106
- initializeApp(options, false); // Chama a função com dev: false
107
- });
108
-
109
- // --- Comando EXPORT ---
110
- program
111
- .command('export')
112
- .description('Exports the application as static HTML to the "exported" folder.')
113
- .option('-o, --output <path>', 'Specifies the output directory', 'exported')
114
- .action(async (options) => {
115
- const projectDir = process.cwd();
116
- const exportDir = path.join(projectDir, options.output);
117
-
118
- console.log('🚀 Starting export...\n');
119
-
120
- try {
121
- // 1. Cria a pasta exported (limpa se já existir)
122
- if (fs.existsSync(exportDir)) {
123
- console.log('🗑️ Cleaning existing export folder...');
124
- fs.rmSync(exportDir, { recursive: true, force: true });
125
- }
126
- fs.mkdirSync(exportDir, { recursive: true });
127
- console.log('✅ Export folder created\n');
128
-
129
- // 2. Inicializa e prepara o build
130
- console.log('🔨 Building application...');
131
- const teste = require("../helpers");
132
- const app = teste.default({ dev: false, port: 3000, hostname: '0.0.0.0', framework: 'native' });
133
- await app.prepare();
134
- console.log('✅ Build complete\n');
135
-
136
- // 3. Copia a pasta .hight para exported
137
- const distDir = path.join(projectDir, '.hight');
138
- if (fs.existsSync(distDir)) {
139
- console.log('📦 Copying JavaScript files...');
140
- const exportDistDir = path.join(exportDir, '.hight');
141
- fs.mkdirSync(exportDistDir, { recursive: true });
142
-
143
- const files = fs.readdirSync(distDir);
144
- files.forEach(file => {
145
- fs.copyFileSync(
146
- path.join(distDir, file),
147
- path.join(exportDistDir, file)
148
- );
149
- });
150
- console.log('✅ JavaScript files copied\n');
151
- }
152
-
153
- // 4. Copia a pasta public se existir
154
- const publicDir = path.join(projectDir, 'public');
155
- if (fs.existsSync(publicDir)) {
156
- console.log('📁 Copying public files...');
157
- const exportPublicDir = path.join(exportDir, 'public');
158
-
159
- function copyRecursive(src, dest) {
160
- if (fs.statSync(src).isDirectory()) {
161
- fs.mkdirSync(dest, { recursive: true });
162
- fs.readdirSync(src).forEach(file => {
163
- copyRecursive(path.join(src, file), path.join(dest, file));
164
- });
165
- } else {
166
- fs.copyFileSync(src, dest);
167
- }
168
- }
169
-
170
- copyRecursive(publicDir, exportPublicDir);
171
- console.log('✅ Public files copied\n');
172
- }
173
-
174
- // 5. Gera o index.html
175
- console.log('📝 Generating index.html...');
176
- const { render } = require('../renderer');
177
- const { loadRoutes, loadLayout, loadNotFound } = require('../router');
178
-
179
- // Carrega as rotas para gerar o HTML
180
- const userWebDir = path.join(projectDir, 'src', 'web');
181
- const userWebRoutesDir = path.join(userWebDir, 'routes');
182
-
183
- const routes = loadRoutes(userWebRoutesDir);
184
- loadLayout(userWebDir);
185
- loadNotFound(userWebDir);
186
-
187
- // Gera HTML para a rota raiz
188
- const rootRoute = routes.find(r => r.pattern === '/') || routes[0];
189
-
190
- if (rootRoute) {
191
- const mockReq = {
192
- url: '/',
193
- method: 'GET',
194
- headers: { host: 'localhost' },
195
- hwebDev: false,
196
- hotReloadManager: null
197
- };
198
-
199
- const html = await render({
200
- req: mockReq,
201
- route: rootRoute,
202
- params: {},
203
- allRoutes: routes
204
- });
205
-
206
- const indexPath = path.join(exportDir, 'index.html');
207
- fs.writeFileSync(indexPath, html, 'utf8');
208
- console.log('✅ index.html generated\n');
209
- }
210
-
211
- console.log('🎉 Export completed successfully!');
212
- console.log(`📂 Files exported to: ${exportDir}\n`);
213
-
214
- } catch (error) {
215
- console.error('❌ Error during export:', error.message);
216
- process.exit(1);
217
- }
218
- });
219
-
220
-
221
- // Faz o "parse" dos argumentos passados na linha de comando
222
- program.parse(process.argv);
package/src/builder.js DELETED
@@ -1,411 +0,0 @@
1
- /*
2
- * This file is part of the HightJS Project.
3
- * Copyright (c) 2025 itsmuzin
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- const esbuild = require('esbuild');
18
- const path = require('path');
19
- const Console = require("./api/console").default
20
- const fs = require('fs');
21
- // Lista de módulos nativos do Node.js para marcar como externos (apenas os built-ins do Node)
22
- const nodeBuiltIns = [
23
- 'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
24
- 'domain', 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'punycode',
25
- 'querystring', 'readline', 'stream', 'string_decoder', 'tls', 'tty', 'url',
26
- 'util', 'v8', 'vm', 'zlib', 'module', 'worker_threads', 'perf_hooks'
27
- ];
28
-
29
- /**
30
- * Plugin para processar CSS com PostCSS e Tailwind
31
- */
32
- const postcssPlugin = {
33
- name: 'postcss-plugin',
34
- setup(build) {
35
- build.onLoad({ filter: /\.css$/ }, async (args) => {
36
- const fs = require('fs');
37
- const path = require('path');
38
-
39
- try {
40
- // Lê o CSS original
41
- let css = await fs.promises.readFile(args.path, 'utf8');
42
-
43
- // Verifica se tem PostCSS config no projeto
44
- const projectDir = process.cwd();
45
- const postcssConfigPath = path.join(projectDir, 'postcss.config.js');
46
- const postcssConfigMjsPath = path.join(projectDir, 'postcss.config.mjs');
47
-
48
- let processedCss = css;
49
-
50
- if (fs.existsSync(postcssConfigPath) || fs.existsSync(postcssConfigMjsPath)) {
51
- try {
52
- // Importa PostCSS do projeto (não do SDK)
53
- const postcssPath = path.join(projectDir, 'node_modules', 'postcss');
54
- const postcss = require(postcssPath);
55
-
56
- // Carrega a config do PostCSS
57
- const configPath = fs.existsSync(postcssConfigPath) ? postcssConfigPath : postcssConfigMjsPath;
58
- delete require.cache[require.resolve(configPath)];
59
- const config = require(configPath);
60
- const postcssConfig = config.default || config;
61
-
62
- // Resolve plugins do projeto
63
- const plugins = [];
64
-
65
- if (postcssConfig.plugins) {
66
- if (Array.isArray(postcssConfig.plugins)) {
67
- // Formato array: ["@tailwindcss/postcss"]
68
- plugins.push(...postcssConfig.plugins.map(plugin => {
69
- if (typeof plugin === 'string') {
70
- try {
71
- // Tenta resolver do node_modules do projeto primeiro
72
- return require.resolve(plugin, { paths: [projectDir] });
73
- } catch {
74
- // Fallback para require direto
75
- return require(plugin);
76
- }
77
- }
78
- return plugin;
79
- }));
80
- } else {
81
- // Formato objeto: { tailwindcss: {}, autoprefixer: {} }
82
- for (const [pluginName, pluginOptions] of Object.entries(postcssConfig.plugins)) {
83
- try {
84
- // Resolve o plugin do projeto
85
- const resolvedPath = require.resolve(pluginName, { paths: [projectDir] });
86
- const pluginModule = require(resolvedPath);
87
- plugins.push(pluginModule(pluginOptions || {}));
88
- } catch (error) {
89
- Console.warn(`Unable to load plugin ${pluginName}:`, error.message);
90
- }
91
- }
92
- }
93
- }
94
-
95
- // Processa o CSS com PostCSS
96
- const result = await postcss(plugins)
97
- .process(css, {
98
- from: args.path,
99
- to: args.path.replace(/\.css$/, '.processed.css')
100
- });
101
-
102
- processedCss = result.css;
103
-
104
- } catch (postcssError) {
105
- Console.warn(`Error processing CSS with PostCSS:`, postcssError.message);
106
- Console.warn(`Using raw CSS without processing.`);
107
- }
108
- }
109
-
110
- return {
111
- contents: `
112
- const css = ${JSON.stringify(processedCss)};
113
- if (typeof document !== 'undefined') {
114
- const style = document.createElement('style');
115
- style.textContent = css;
116
- document.head.appendChild(style);
117
- }
118
- export default css;
119
- `,
120
- loader: 'js'
121
- };
122
-
123
- } catch (error) {
124
- Console.error(`Erro ao processar CSS ${args.path}:`, error);
125
- return {
126
- contents: `export default "";`,
127
- loader: 'js'
128
- };
129
- }
130
- });
131
- }
132
- };
133
-
134
- /**
135
- * Plugin para resolver dependências npm no frontend
136
- */
137
- const npmDependenciesPlugin = {
138
- name: 'npm-dependencies',
139
- setup(build) {
140
- // Permite que dependências npm sejam bundladas (não marcadas como external)
141
- build.onResolve({ filter: /^[^./]/ }, (args) => {
142
- // Se for um módulo built-in do Node.js, marca como external
143
- if (nodeBuiltIns.includes(args.path)) {
144
- return { path: args.path, external: true };
145
- }
146
-
147
- // Para dependências npm (axios, lodash, react, react-dom, etc), deixa o esbuild resolver normalmente
148
- // Isso permite que sejam bundladas no frontend
149
- return null;
150
- });
151
- }
152
- };
153
-
154
- /**
155
- * Plugin para garantir que React seja corretamente resolvido
156
- */
157
- const reactResolvePlugin = {
158
- name: 'react-resolve',
159
- setup(build) {
160
- // Força o uso de uma única instância do React do projeto
161
- build.onResolve({ filter: /^react$/ }, (args) => {
162
- const reactPath = require.resolve('react', { paths: [process.cwd()] });
163
- return {
164
- path: reactPath
165
- };
166
- });
167
-
168
- build.onResolve({ filter: /^react-dom$/ }, (args) => {
169
- const reactDomPath = require.resolve('react-dom', { paths: [process.cwd()] });
170
- return {
171
- path: reactDomPath
172
- };
173
- });
174
-
175
- build.onResolve({ filter: /^react\/jsx-runtime$/ }, (args) => {
176
- const jsxRuntimePath = require.resolve('react/jsx-runtime', { paths: [process.cwd()] });
177
- return {
178
- path: jsxRuntimePath
179
- };
180
- });
181
-
182
- // Também resolve react-dom/client para React 18+
183
- build.onResolve({ filter: /^react-dom\/client$/ }, (args) => {
184
- const clientPath = require.resolve('react-dom/client', { paths: [process.cwd()] });
185
- return {
186
- path: clientPath
187
- };
188
- });
189
- }
190
- };
191
-
192
- /**
193
- * Builds with code splitting into multiple chunks based on module types.
194
- * @param {string} entryPoint - The path to the entry file.
195
- * @param {string} outdir - The directory for output files.
196
- * @param {boolean} isProduction - Se está em modo produção ou não.
197
- * @returns {Promise<void>}
198
- */
199
- async function buildWithChunks(entryPoint, outdir, isProduction = false) {
200
- // limpar diretorio
201
- fs.rmSync(outdir, { recursive: true, force: true });
202
-
203
- try {
204
- await esbuild.build({
205
- entryPoints: [entryPoint],
206
- bundle: true,
207
- minify: isProduction,
208
- sourcemap: !isProduction,
209
- platform: 'browser',
210
- outdir: outdir,
211
- loader: { '.js': 'jsx', '.ts': 'tsx' },
212
- external: nodeBuiltIns,
213
- plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
214
- format: 'esm', // ESM suporta melhor o code splitting
215
- jsx: 'automatic',
216
- define: {
217
- 'process.env.NODE_ENV': isProduction ? '"production"' : '"development"'
218
- },
219
- conditions: ['development'],
220
- mainFields: ['browser', 'module', 'main'],
221
- resolveExtensions: ['.tsx', '.ts', '.jsx', '.js'],
222
- splitting: true,
223
- chunkNames: 'chunks/[name]-[hash]',
224
- // Força o nome do entry para main(.js) ou main-[hash].js em prod
225
- entryNames: isProduction ? 'main-[hash]' : 'main',
226
- keepNames: true,
227
- treeShaking: true,
228
- });
229
-
230
- } catch (error) {
231
- console.error('An error occurred while building:', error);
232
- process.exit(1);
233
- }
234
- }
235
-
236
- /**
237
- * Watches with code splitting enabled
238
- * @param {string} entryPoint - The path to the entry file.
239
- * @param {string} outdir - The directory for output files.
240
- * @param {Object} hotReloadManager - Manager de hot reload (opcional).
241
- * @returns {Promise<void>}
242
- */
243
- async function watchWithChunks(entryPoint, outdir, hotReloadManager = null) {
244
- // limpar diretorio
245
- fs.rmSync(outdir, { recursive: true, force: true });
246
- try {
247
- // Plugin para notificar quando o build termina
248
- const buildCompletePlugin = {
249
- name: 'build-complete',
250
- setup(build) {
251
- let isFirstBuild = true;
252
- build.onEnd((result) => {
253
- if (hotReloadManager) {
254
- if (isFirstBuild) {
255
- isFirstBuild = false;
256
- hotReloadManager.onBuildComplete(true);
257
- } else {
258
- // Notifica o hot reload manager que o build foi concluído
259
- hotReloadManager.onBuildComplete(result.errors.length === 0);
260
- }
261
- }
262
- });
263
- }
264
- };
265
-
266
- const context = await esbuild.context({
267
- entryPoints: [entryPoint],
268
- bundle: true,
269
- minify: false,
270
- sourcemap: true,
271
- platform: 'browser',
272
- outdir: outdir,
273
- loader: { '.js': 'jsx', '.ts': 'tsx' },
274
- external: nodeBuiltIns,
275
- plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
276
- format: 'esm',
277
- jsx: 'automatic',
278
- define: {
279
- 'process.env.NODE_ENV': '"development"'
280
- },
281
- conditions: ['development'],
282
- mainFields: ['browser', 'module', 'main'],
283
- resolveExtensions: ['.tsx', '.ts', '.jsx', '.js'],
284
- splitting: true,
285
- chunkNames: 'chunks/[name]-[hash]',
286
- entryNames: 'main',
287
- keepNames: true,
288
- treeShaking: true,
289
- });
290
-
291
- await context.watch();
292
- } catch (error) {
293
- console.error(error)
294
- Console.error('Error starting watch mode with chunks:', error);
295
- throw error;
296
- }
297
- }
298
-
299
- /**
300
- * Builds a single entry point into a single output file.
301
- * @param {string} entryPoint - The path to the entry file.
302
- * @param {string} outfile - The full path to the output file.
303
- * @param {boolean} isProduction - Se está em modo produção ou não.
304
- * @returns {Promise<void>}
305
- */
306
- async function build(entryPoint, outfile, isProduction = false) {
307
- // limpar diretorio do outfile
308
- const outdir = path.dirname(outfile);
309
- fs.rmSync(outdir, { recursive: true, force: true });
310
-
311
- try {
312
- await esbuild.build({
313
- entryPoints: [entryPoint],
314
- bundle: true,
315
- minify: isProduction,
316
- sourcemap: !isProduction, // Só gera sourcemap em dev
317
- platform: 'browser',
318
- outfile: outfile,
319
- loader: { '.js': 'jsx', '.ts': 'tsx' },
320
- external: nodeBuiltIns,
321
- plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin],
322
- format: 'iife',
323
- globalName: 'HwebApp',
324
- jsx: 'automatic',
325
- define: {
326
- 'process.env.NODE_ENV': isProduction ? '"production"' : '"development"'
327
- },
328
- // Configurações específicas para React 19
329
- conditions: ['development'],
330
- mainFields: ['browser', 'module', 'main'],
331
- resolveExtensions: ['.tsx', '.ts', '.jsx', '.js'],
332
- // Garante que não há duplicação de dependências
333
- splitting: false,
334
- // Preserva nomes de funções e comportamento
335
- keepNames: true,
336
- // Remove otimizações que podem causar problemas com hooks
337
- treeShaking: true,
338
- drop: [], // Não remove nada automaticamente
339
- });
340
-
341
- } catch (error) {
342
- console.error('An error occurred during build:', error);
343
- process.exit(1);
344
- }
345
- }
346
-
347
- /**
348
- * Watches an entry point and its dependencies, rebuilding to a single output file.
349
- * @param {string} entryPoint - The path to the entry file.
350
- * @param {string} outfile - The full path to the output file.
351
- * @param {Object} hotReloadManager - Manager de hot reload (opcional).
352
- * @returns {Promise<void>}
353
- */
354
- async function watch(entryPoint, outfile, hotReloadManager = null) {
355
- try {
356
- // Plugin para notificar quando o build termina
357
- const buildCompletePlugin = {
358
- name: 'build-complete',
359
- setup(build) {
360
- let isFirstBuild = true;
361
- build.onEnd((result) => {
362
- if (hotReloadManager) {
363
- if (isFirstBuild) {
364
- isFirstBuild = false;
365
- hotReloadManager.onBuildComplete(true);
366
- } else {
367
- // Notifica o hot reload manager que o build foi concluído
368
- hotReloadManager.onBuildComplete(result.errors.length === 0);
369
- }
370
- }
371
- });
372
- }
373
- };
374
-
375
- const context = await esbuild.context({
376
- entryPoints: [entryPoint],
377
- bundle: true,
378
- minify: false,
379
- sourcemap: true,
380
- platform: 'browser',
381
- outfile: outfile,
382
- loader: { '.js': 'jsx', '.ts': 'tsx' },
383
- external: nodeBuiltIns,
384
- plugins: [postcssPlugin, npmDependenciesPlugin, reactResolvePlugin, buildCompletePlugin],
385
- format: 'iife',
386
- globalName: 'HwebApp',
387
- jsx: 'automatic',
388
- define: {
389
- 'process.env.NODE_ENV': '"development"'
390
- },
391
- // Configurações específicas para React 19 (mesmo que no build)
392
- conditions: ['development'],
393
- mainFields: ['browser', 'module', 'main'],
394
- resolveExtensions: ['.tsx', '.ts', '.jsx', '.js'],
395
- // Garante que não há duplicação de dependências
396
- splitting: false,
397
- // Preserva nomes de funções e comportamento
398
- keepNames: true,
399
- // Remove otimizações que podem causar problemas com hooks
400
- treeShaking: true,
401
- });
402
-
403
- // Configura o watcher do esbuild
404
- await context.watch();
405
- } catch (error) {
406
- Console.error('Error starting watch mode:', error);
407
- throw error;
408
- }
409
- }
410
-
411
- module.exports = { build, watch, buildWithChunks, watchWithChunks };