@theia/application-manager 1.75.0-next.8 → 1.75.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.
- package/lib/application-package-manager.d.ts +1 -0
- package/lib/application-package-manager.d.ts.map +1 -1
- package/lib/application-package-manager.js +14 -9
- package/lib/application-package-manager.js.map +1 -1
- package/lib/browser-only/prepare-browser-only-plugins.d.ts +12 -0
- package/lib/browser-only/prepare-browser-only-plugins.d.ts.map +1 -0
- package/lib/browser-only/prepare-browser-only-plugins.js +313 -0
- package/lib/browser-only/prepare-browser-only-plugins.js.map +1 -0
- package/lib/browser-only/prepare-browser-only-plugins.spec.d.ts +2 -0
- package/lib/browser-only/prepare-browser-only-plugins.spec.d.ts.map +1 -0
- package/lib/browser-only/prepare-browser-only-plugins.spec.js +136 -0
- package/lib/browser-only/prepare-browser-only-plugins.spec.js.map +1 -0
- package/lib/browser-only/write-browser-only-extensions-list.d.ts +7 -0
- package/lib/browser-only/write-browser-only-extensions-list.d.ts.map +1 -0
- package/lib/browser-only/write-browser-only-extensions-list.js +28 -0
- package/lib/browser-only/write-browser-only-extensions-list.js.map +1 -0
- package/lib/generator/bundler-generator.d.ts +7 -8
- package/lib/generator/bundler-generator.d.ts.map +1 -1
- package/lib/generator/bundler-generator.js +32 -563
- package/lib/generator/bundler-generator.js.map +1 -1
- package/lib/generator/frontend-generator.d.ts.map +1 -1
- package/lib/generator/frontend-generator.js +1 -3
- package/lib/generator/frontend-generator.js.map +1 -1
- package/package.json +11 -33
- package/src/application-package-manager.ts +16 -8
- package/src/browser-only/prepare-browser-only-plugins.spec.ts +169 -0
- package/src/browser-only/prepare-browser-only-plugins.ts +376 -0
- package/src/browser-only/write-browser-only-extensions-list.ts +27 -0
- package/src/generator/bundler-generator.ts +36 -568
- package/src/generator/frontend-generator.ts +1 -3
- package/lib/expose-loader.d.ts +0 -9
- package/lib/expose-loader.d.ts.map +0 -1
- package/lib/expose-loader.js +0 -73
- package/lib/expose-loader.js.map +0 -1
- package/src/expose-loader.ts +0 -83
|
@@ -14,54 +14,36 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import * as paths from 'path';
|
|
18
17
|
import * as fs from 'fs-extra';
|
|
19
18
|
import { AbstractGenerator } from './abstract-generator';
|
|
20
19
|
|
|
21
20
|
export class BundlerGenerator extends AbstractGenerator {
|
|
22
21
|
|
|
23
22
|
async generate(): Promise<void> {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
23
|
+
await this.warnAboutWebpackConfig();
|
|
24
|
+
await this.write(this.genESBuildBrowserPath, this.compileESBuildBrowserConfig());
|
|
25
|
+
if (!this.pck.isBrowserOnly()) {
|
|
26
|
+
await this.write(this.genESBuildNodePath, this.compileESBuildNodeConfig());
|
|
27
|
+
if (this.pck.isElectron()) {
|
|
28
|
+
await this.write(this.genESBuildElectronPath, this.compileESBuildElectronConfig());
|
|
31
29
|
}
|
|
32
|
-
if (await this.shouldGenerateUserESBuildConfig()) {
|
|
33
|
-
await this.write(this.esbuildPath, this.compileESBuildUserConfig());
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
await this.write(this.genConfigPath, this.compileWebpackConfig());
|
|
37
|
-
if (!this.pck.isBrowserOnly()) {
|
|
38
|
-
await this.write(this.genNodeConfigPath, this.compileNodeWebpackConfig());
|
|
39
|
-
}
|
|
40
|
-
if (await this.shouldGenerateUserWebpackConfig()) {
|
|
41
|
-
await this.write(this.configPath, this.compileUserWebpackConfig());
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async preferESBuild(): Promise<boolean> {
|
|
47
|
-
// If an esbuild file already exists, prefer esbuild
|
|
48
|
-
if (await fs.pathExists(this.esbuildPath)) {
|
|
49
|
-
return true;
|
|
50
30
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return false;
|
|
31
|
+
if (await this.shouldGenerateUserESBuildConfig()) {
|
|
32
|
+
await this.write(this.esbuildPath, this.compileESBuildUserConfig());
|
|
54
33
|
}
|
|
55
|
-
// Otherwise, prefer ESBuild (for performance)
|
|
56
|
-
return true;
|
|
57
34
|
}
|
|
58
35
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Warns about a `webpack.config.js` left over from Theia < 1.75.0. Such a file is no longer
|
|
38
|
+
* read, so any customization it contains no longer has an effect. Without this warning,
|
|
39
|
+
* adopters would only notice through a differently behaving bundle.
|
|
40
|
+
*/
|
|
41
|
+
protected async warnAboutWebpackConfig(): Promise<void> {
|
|
42
|
+
if (await fs.pathExists(this.webpackConfigPath)) {
|
|
43
|
+
console.warn(`Ignoring '${this.webpackConfigPath}': webpack bundling was removed in Theia 1.75.0, '${this.esbuildPath}' is used instead.`);
|
|
44
|
+
console.warn('Port any customization to the esbuild configuration and delete the webpack files. See the migration guide for details: '
|
|
45
|
+
+ 'https://github.com/eclipse-theia/theia/blob/master/doc/Migration.md');
|
|
62
46
|
}
|
|
63
|
-
const content = await fs.readFile(this.configPath, 'utf8');
|
|
64
|
-
return !content.includes('gen-webpack');
|
|
65
47
|
}
|
|
66
48
|
|
|
67
49
|
protected async shouldGenerateUserESBuildConfig(): Promise<boolean> {
|
|
@@ -72,18 +54,10 @@ export class BundlerGenerator extends AbstractGenerator {
|
|
|
72
54
|
return !content.includes('gen-esbuild');
|
|
73
55
|
}
|
|
74
56
|
|
|
75
|
-
get
|
|
57
|
+
get webpackConfigPath(): string {
|
|
76
58
|
return this.pck.path('webpack.config.js');
|
|
77
59
|
}
|
|
78
60
|
|
|
79
|
-
get genConfigPath(): string {
|
|
80
|
-
return this.pck.path('gen-webpack.config.js');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get genNodeConfigPath(): string {
|
|
84
|
-
return this.pck.path('gen-webpack.node.config.js');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
61
|
get esbuildPath(): string {
|
|
88
62
|
return this.pck.path('esbuild.mjs');
|
|
89
63
|
}
|
|
@@ -100,525 +74,6 @@ export class BundlerGenerator extends AbstractGenerator {
|
|
|
100
74
|
return this.pck.path('gen-esbuild.electron.mjs');
|
|
101
75
|
}
|
|
102
76
|
|
|
103
|
-
protected compileWebpackConfig(): string {
|
|
104
|
-
return `/**
|
|
105
|
-
* Don't touch this file. It will be regenerated by theia build.
|
|
106
|
-
* To customize webpack configuration change ${this.configPath}
|
|
107
|
-
*/
|
|
108
|
-
// @ts-check
|
|
109
|
-
const path = require('path');
|
|
110
|
-
const webpack = require('webpack');
|
|
111
|
-
const yargs = require('yargs');
|
|
112
|
-
const resolvePackagePath = require('resolve-package-path');
|
|
113
|
-
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
114
|
-
const CompressionPlugin = require('compression-webpack-plugin');
|
|
115
|
-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
116
|
-
const { MonacoWebpackPlugin } = require('@theia/bundle-plugin');
|
|
117
|
-
|
|
118
|
-
const outputPath = path.resolve(__dirname, 'lib', 'frontend');
|
|
119
|
-
const { mode, staticCompression } = yargs.option('mode', {
|
|
120
|
-
description: "Mode to use",
|
|
121
|
-
choices: ["development", "production"],
|
|
122
|
-
default: "production"
|
|
123
|
-
}).option('static-compression', {
|
|
124
|
-
description: 'Controls whether to enable compression of static artifacts.',
|
|
125
|
-
type: 'boolean',
|
|
126
|
-
default: true
|
|
127
|
-
}).argv;
|
|
128
|
-
const development = mode === 'development';
|
|
129
|
-
|
|
130
|
-
const plugins = [
|
|
131
|
-
new CopyWebpackPlugin({
|
|
132
|
-
patterns: [
|
|
133
|
-
{
|
|
134
|
-
// copy secondary window html file to lib folder
|
|
135
|
-
from: path.resolve(__dirname, 'src-gen/frontend/secondary-window.html')
|
|
136
|
-
}${this.ifPackage('@theia/plugin-ext', `,
|
|
137
|
-
{
|
|
138
|
-
// copy webview files to lib folder
|
|
139
|
-
from: path.join(resolvePackagePath('@theia/plugin-ext', __dirname), '..', 'src', 'main', 'browser', 'webview', 'pre'),
|
|
140
|
-
to: path.resolve(__dirname, 'lib', 'webview', 'pre')
|
|
141
|
-
}`)}
|
|
142
|
-
${this.ifPackage('@theia/plugin-ext-vscode', `,
|
|
143
|
-
{
|
|
144
|
-
// copy frontend plugin host files
|
|
145
|
-
from: path.join(resolvePackagePath('@theia/plugin-ext-vscode', __dirname), '..', 'lib', 'node', 'context', 'plugin-vscode-init-fe.js'),
|
|
146
|
-
to: path.resolve(__dirname, 'lib', 'frontend', 'context', 'plugin-vscode-init-fe.js')
|
|
147
|
-
}`)}
|
|
148
|
-
${this.ifPackage('@theia/terminal', `,
|
|
149
|
-
{
|
|
150
|
-
// copy shell integration scripts
|
|
151
|
-
from: path.join(resolvePackagePath('@theia/terminal', __dirname), '..', 'src', 'node', 'shell-integrations'),
|
|
152
|
-
to: path.resolve(__dirname, 'lib', 'backend', 'shell-integrations')
|
|
153
|
-
}`)}
|
|
154
|
-
]
|
|
155
|
-
}),
|
|
156
|
-
new webpack.ProvidePlugin({
|
|
157
|
-
// the Buffer class doesn't exist in the browser but some dependencies rely on it
|
|
158
|
-
Buffer: ['buffer', 'Buffer']
|
|
159
|
-
}),
|
|
160
|
-
new MonacoWebpackPlugin()
|
|
161
|
-
];
|
|
162
|
-
// it should go after copy-plugin in order to compress monaco as well
|
|
163
|
-
if (staticCompression) {
|
|
164
|
-
plugins.push(new CompressionPlugin({}));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
module.exports = [{
|
|
168
|
-
mode,
|
|
169
|
-
plugins,
|
|
170
|
-
devtool: 'source-map',
|
|
171
|
-
entry: {
|
|
172
|
-
bundle: path.resolve(__dirname, 'src-gen/frontend/index.js'),
|
|
173
|
-
${this.ifPackage('@theia/plugin-ext', "'plugin-worker': '@theia/plugin-ext/lib/hosted/browser/worker/worker-main.js',")}
|
|
174
|
-
},
|
|
175
|
-
output: {
|
|
176
|
-
filename: '[name].js',
|
|
177
|
-
path: outputPath,
|
|
178
|
-
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
|
|
179
|
-
globalObject: 'self'
|
|
180
|
-
},
|
|
181
|
-
target: 'web',
|
|
182
|
-
cache: staticCompression,
|
|
183
|
-
module: {
|
|
184
|
-
rules: [
|
|
185
|
-
{
|
|
186
|
-
test: /\\.css$/,
|
|
187
|
-
use: ['style-loader', 'css-loader']
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
test: /\\.(ttf|eot|svg)(\\?v=\\d+\\.\\d+\\.\\d+)?$/,
|
|
191
|
-
type: 'asset',
|
|
192
|
-
parser: {
|
|
193
|
-
dataUrlCondition: {
|
|
194
|
-
maxSize: 10000,
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
generator: {
|
|
198
|
-
dataUrl: {
|
|
199
|
-
mimetype: 'image/svg+xml'
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
test: /\\.(jpg|png|gif)$/,
|
|
205
|
-
type: 'asset/resource',
|
|
206
|
-
generator: {
|
|
207
|
-
filename: '[hash].[ext]'
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
// see https://github.com/eclipse-theia/theia/issues/556
|
|
212
|
-
test: /source-map-support/,
|
|
213
|
-
loader: 'ignore-loader'
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
test: /\\.d\\.ts$/,
|
|
217
|
-
loader: 'ignore-loader'
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
test: /\\.js$/,
|
|
221
|
-
enforce: 'pre',
|
|
222
|
-
loader: 'source-map-loader',
|
|
223
|
-
exclude: /jsonc-parser|fast-plist|onigasm/
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
test: /\\.woff(2)?(\\?v=[0-9]\\.[0-9]\\.[0-9])?$/,
|
|
227
|
-
type: 'asset',
|
|
228
|
-
parser: {
|
|
229
|
-
dataUrlCondition: {
|
|
230
|
-
maxSize: 10000,
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
generator: {
|
|
234
|
-
dataUrl: {
|
|
235
|
-
mimetype: 'image/svg+xml'
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
test: /node_modules[\\\\|\/](vscode-languageserver-types|vscode-uri|jsonc-parser|vscode-languageserver-protocol)/,
|
|
241
|
-
loader: 'umd-compat-loader'
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
test: /\\.wasm$/,
|
|
245
|
-
type: 'asset/resource'
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
test: /\\.plist$/,
|
|
249
|
-
type: 'asset/resource'
|
|
250
|
-
}
|
|
251
|
-
]
|
|
252
|
-
},
|
|
253
|
-
resolve: {
|
|
254
|
-
fallback: {
|
|
255
|
-
'child_process': false,
|
|
256
|
-
'crypto': false,
|
|
257
|
-
'net': false,
|
|
258
|
-
'path': require.resolve('path-browserify'),
|
|
259
|
-
'process': false,
|
|
260
|
-
'os': false,
|
|
261
|
-
'timers': false
|
|
262
|
-
},
|
|
263
|
-
${this.ifMonaco(() => `alias: {
|
|
264
|
-
// Replace Monaco's nls module with Theia's localization-aware version.
|
|
265
|
-
// ESM exports are immutable so we cannot override localize/localize2 at runtime.
|
|
266
|
-
// Using the resolved absolute path ensures that both external imports
|
|
267
|
-
// (e.g. '@theia/monaco-editor-core/esm/vs/nls') and internal relative
|
|
268
|
-
// imports within Monaco (e.g. '../nls.js') are redirected.
|
|
269
|
-
[path.join(resolvePackagePath('@theia/monaco-editor-core', __dirname), '..', 'esm', 'vs', 'nls.js')]:
|
|
270
|
-
path.join(resolvePackagePath('@theia/monaco', __dirname), '..', 'lib', 'browser', 'monaco-nls.js')
|
|
271
|
-
},`)}
|
|
272
|
-
extensions: ['.js']
|
|
273
|
-
},
|
|
274
|
-
stats: {
|
|
275
|
-
warnings: true,
|
|
276
|
-
children: true
|
|
277
|
-
},
|
|
278
|
-
ignoreWarnings: [
|
|
279
|
-
// Some packages do not have source maps, that's ok
|
|
280
|
-
/Failed to parse source map/,
|
|
281
|
-
{
|
|
282
|
-
// Monaco uses 'require' in a non-standard way
|
|
283
|
-
module: /@theia\\/monaco-editor-core/,
|
|
284
|
-
message: /require function is used in a way in which dependencies cannot be statically extracted/
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
},
|
|
288
|
-
${this.ifMonaco(() => `{
|
|
289
|
-
// The Monaco editor worker must be built separately without the NLS alias.
|
|
290
|
-
// The NLS alias redirects to monaco-nls.ts which imports from @theia/core,
|
|
291
|
-
// and those modules are not available in the web worker context.
|
|
292
|
-
mode,
|
|
293
|
-
devtool: 'source-map',
|
|
294
|
-
entry: {
|
|
295
|
-
'editor.worker': '@theia/monaco-editor-core/esm/vs/editor/common/services/editorWebWorkerMain.js'
|
|
296
|
-
},
|
|
297
|
-
output: {
|
|
298
|
-
filename: '[name].js',
|
|
299
|
-
path: outputPath,
|
|
300
|
-
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
|
|
301
|
-
globalObject: 'self'
|
|
302
|
-
},
|
|
303
|
-
target: 'webworker',
|
|
304
|
-
cache: staticCompression,
|
|
305
|
-
resolve: {
|
|
306
|
-
extensions: ['.js']
|
|
307
|
-
},
|
|
308
|
-
ignoreWarnings: [
|
|
309
|
-
{
|
|
310
|
-
module: /@theia\\/monaco-editor-core/,
|
|
311
|
-
message: /require function is used in a way in which dependencies cannot be statically extracted/
|
|
312
|
-
}
|
|
313
|
-
]
|
|
314
|
-
},`)}
|
|
315
|
-
{
|
|
316
|
-
mode,
|
|
317
|
-
plugins: [
|
|
318
|
-
new MiniCssExtractPlugin({
|
|
319
|
-
// Options similar to the same options in webpackOptions.output
|
|
320
|
-
// both options are optional
|
|
321
|
-
filename: "[name].css",
|
|
322
|
-
chunkFilename: "[id].css",
|
|
323
|
-
}),
|
|
324
|
-
new MonacoWebpackPlugin(),
|
|
325
|
-
],
|
|
326
|
-
devtool: 'source-map',
|
|
327
|
-
entry: {
|
|
328
|
-
"secondary-window": path.resolve(__dirname, 'src-gen/frontend/secondary-index.js'),
|
|
329
|
-
},
|
|
330
|
-
output: {
|
|
331
|
-
filename: '[name].js',
|
|
332
|
-
path: outputPath,
|
|
333
|
-
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
|
|
334
|
-
globalObject: 'self'
|
|
335
|
-
},
|
|
336
|
-
target: 'web',
|
|
337
|
-
cache: staticCompression,
|
|
338
|
-
module: {
|
|
339
|
-
rules: [
|
|
340
|
-
{
|
|
341
|
-
test: /\.css$/i,
|
|
342
|
-
use: [MiniCssExtractPlugin.loader, "css-loader"]
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
test: /\.wasm$/,
|
|
346
|
-
type: 'asset/resource'
|
|
347
|
-
}
|
|
348
|
-
]
|
|
349
|
-
},
|
|
350
|
-
resolve: {
|
|
351
|
-
fallback: {
|
|
352
|
-
'child_process': false,
|
|
353
|
-
'crypto': false,
|
|
354
|
-
'net': false,
|
|
355
|
-
'path': require.resolve('path-browserify'),
|
|
356
|
-
'process': false,
|
|
357
|
-
'os': false,
|
|
358
|
-
'timers': false
|
|
359
|
-
},
|
|
360
|
-
${this.ifMonaco(() => `alias: {
|
|
361
|
-
// Replace Monaco's nls module with Theia's localization-aware version.
|
|
362
|
-
// ESM exports are immutable so we cannot override localize/localize2 at runtime.
|
|
363
|
-
// Using the resolved absolute path ensures that both external imports
|
|
364
|
-
// (e.g. '@theia/monaco-editor-core/esm/vs/nls') and internal relative
|
|
365
|
-
// imports within Monaco (e.g. '../nls.js') are redirected.
|
|
366
|
-
[path.join(resolvePackagePath('@theia/monaco-editor-core', __dirname), '..', 'esm', 'vs', 'nls.js')]:
|
|
367
|
-
path.join(resolvePackagePath('@theia/monaco', __dirname), '..', 'lib', 'browser', 'monaco-nls.js')
|
|
368
|
-
},`)}
|
|
369
|
-
extensions: ['.js']
|
|
370
|
-
},
|
|
371
|
-
stats: {
|
|
372
|
-
warnings: true,
|
|
373
|
-
children: true
|
|
374
|
-
},
|
|
375
|
-
ignoreWarnings: [
|
|
376
|
-
{
|
|
377
|
-
// Monaco uses 'require' in a non-standard way
|
|
378
|
-
module: /@theia\\/monaco-editor-core/,
|
|
379
|
-
message: /require function is used in a way in which dependencies cannot be statically extracted/
|
|
380
|
-
}
|
|
381
|
-
]
|
|
382
|
-
}${this.ifElectron(`, {
|
|
383
|
-
mode,
|
|
384
|
-
devtool: 'source-map',
|
|
385
|
-
entry: {
|
|
386
|
-
"preload": path.resolve(__dirname, 'src-gen/frontend/preload.js'),
|
|
387
|
-
},
|
|
388
|
-
output: {
|
|
389
|
-
filename: '[name].js',
|
|
390
|
-
path: outputPath,
|
|
391
|
-
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
|
|
392
|
-
globalObject: 'self'
|
|
393
|
-
},
|
|
394
|
-
target: 'electron-preload',
|
|
395
|
-
cache: staticCompression,
|
|
396
|
-
stats: {
|
|
397
|
-
warnings: true,
|
|
398
|
-
children: true
|
|
399
|
-
}
|
|
400
|
-
}`)}];`;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
protected compileUserWebpackConfig(): string {
|
|
404
|
-
return `/**
|
|
405
|
-
* This file can be edited to customize webpack configuration.
|
|
406
|
-
* To reset delete this file and rerun theia build again.
|
|
407
|
-
*/
|
|
408
|
-
// @ts-check
|
|
409
|
-
const configs = require('./${paths.basename(this.genConfigPath)}');
|
|
410
|
-
${this.ifBrowserOnly('', `const nodeConfig = require('./${paths.basename(this.genNodeConfigPath)}');`)}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Expose bundled modules on window.theia.moduleName namespace, e.g.
|
|
414
|
-
* window['theia']['@theia/core/lib/common/uri'].
|
|
415
|
-
* Such syntax can be used by external code, for instance, for testing.
|
|
416
|
-
configs[0].module.rules.push({
|
|
417
|
-
test: /\\.js$/,
|
|
418
|
-
loader: require.resolve('@theia/application-manager/lib/expose-loader')
|
|
419
|
-
}); */
|
|
420
|
-
|
|
421
|
-
${this.ifBrowserOnly('module.exports = configs;', `module.exports = [
|
|
422
|
-
...configs,
|
|
423
|
-
nodeConfig.config
|
|
424
|
-
];`)}
|
|
425
|
-
`;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
protected compileNodeWebpackConfig(): string {
|
|
429
|
-
return `/**
|
|
430
|
-
* Don't touch this file. It will be regenerated by theia build.
|
|
431
|
-
* To customize webpack configuration change ${this.configPath}
|
|
432
|
-
*/
|
|
433
|
-
// @ts-check
|
|
434
|
-
const path = require('path');
|
|
435
|
-
const yargs = require('yargs');
|
|
436
|
-
const webpack = require('webpack');
|
|
437
|
-
const TerserPlugin = require('terser-webpack-plugin');
|
|
438
|
-
const { NativeWebpackPlugin, MonacoWebpackPlugin } = require('@theia/bundle-plugin');
|
|
439
|
-
|
|
440
|
-
const { mode } = yargs.option('mode', {
|
|
441
|
-
description: "Mode to use",
|
|
442
|
-
choices: ["development", "production"],
|
|
443
|
-
default: "production"
|
|
444
|
-
}).argv;
|
|
445
|
-
|
|
446
|
-
const production = mode === 'production';
|
|
447
|
-
|
|
448
|
-
/** @type {import('webpack').EntryObject} */
|
|
449
|
-
const commonJsLibraries = {};
|
|
450
|
-
for (const [entryPointName, entryPointPath] of Object.entries({
|
|
451
|
-
${this.ifPackage('@theia/plugin-ext', "'backend-init-theia': '@theia/plugin-ext/lib/hosted/node/scanners/backend-init-theia',")}
|
|
452
|
-
${this.ifPackage('@theia/filesystem', "'parcel-watcher': '@theia/filesystem/lib/node/parcel-watcher',")}
|
|
453
|
-
${this.ifPackage('@theia/plugin-ext-vscode', "'plugin-vscode-init': '@theia/plugin-ext-vscode/lib/node/plugin-vscode-init',")}
|
|
454
|
-
${this.ifPackage('@theia/api-provider-sample', "'gotd-api-init': '@theia/api-provider-sample/lib/plugin/gotd-api-init',")}
|
|
455
|
-
})) {
|
|
456
|
-
commonJsLibraries[entryPointName] = {
|
|
457
|
-
import: require.resolve(entryPointPath),
|
|
458
|
-
library: {
|
|
459
|
-
type: 'commonjs2',
|
|
460
|
-
},
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
const ignoredResources = new Set();
|
|
465
|
-
|
|
466
|
-
if (process.platform !== 'win32') {
|
|
467
|
-
ignoredResources.add('@vscode/windows-ca-certs');
|
|
468
|
-
ignoredResources.add('@vscode/windows-ca-certs/build/Release/crypt32.node');
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const nativePlugin = new NativeWebpackPlugin({
|
|
472
|
-
out: 'native',
|
|
473
|
-
trash: ${this.ifPackage('@theia/filesystem', 'true', 'false')},
|
|
474
|
-
ripgrep: ${this.ifPackage(['@theia/search-in-workspace', '@theia/file-search'], 'true', 'false')},
|
|
475
|
-
pty: ${this.ifPackage('@theia/process', 'true', 'false')},
|
|
476
|
-
nativeBindings: {
|
|
477
|
-
drivelist: 'drivelist/build/Release/drivelist.node'
|
|
478
|
-
}
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
${this.ifPackage('@theia/process', () => `// Ensure that node-pty is correctly hoisted
|
|
482
|
-
try {
|
|
483
|
-
require.resolve('node-pty');
|
|
484
|
-
} catch {
|
|
485
|
-
console.error('"node-pty" dependency is not installed correctly. Ensure that it is available in the root node_modules directory.');
|
|
486
|
-
console.error('Exiting webpack build process.');
|
|
487
|
-
process.exit(1);
|
|
488
|
-
}`)}
|
|
489
|
-
|
|
490
|
-
/** @type {import('webpack').Configuration} */
|
|
491
|
-
const config = {
|
|
492
|
-
mode,
|
|
493
|
-
devtool: mode === 'development' ? 'source-map' : false,
|
|
494
|
-
target: 'node',
|
|
495
|
-
node: {
|
|
496
|
-
global: false,
|
|
497
|
-
__filename: false,
|
|
498
|
-
__dirname: false
|
|
499
|
-
},
|
|
500
|
-
resolve: {
|
|
501
|
-
extensions: ['.js', '.json', '.wasm', '.node'],
|
|
502
|
-
},
|
|
503
|
-
output: {
|
|
504
|
-
filename: '[name].js',
|
|
505
|
-
path: path.resolve(__dirname, 'lib', 'backend'),
|
|
506
|
-
devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]?[loaders]',
|
|
507
|
-
},${this.ifElectron(`
|
|
508
|
-
externals: {
|
|
509
|
-
electron: 'require("electron")'
|
|
510
|
-
},`)}
|
|
511
|
-
entry: {
|
|
512
|
-
// Main entry point of the Theia application backend:
|
|
513
|
-
'main': require.resolve('./src-gen/backend/main'),
|
|
514
|
-
// Theia's IPC mechanism:
|
|
515
|
-
'ipc-bootstrap': require.resolve('@theia/core/lib/node/messaging/ipc-bootstrap'),
|
|
516
|
-
${this.ifPackage('@theia/plugin-ext', () => `// VS Code extension support:
|
|
517
|
-
'plugin-host': require.resolve('@theia/plugin-ext/lib/hosted/node/plugin-host'),`)}
|
|
518
|
-
${this.ifPackage('@theia/plugin-ext-headless', () => `// Theia Headless Plugin support:
|
|
519
|
-
'plugin-host-headless': require.resolve('@theia/plugin-ext-headless/lib/hosted/node/plugin-host-headless'),`)}
|
|
520
|
-
${this.ifPackage('@theia/process', () => `// Make sure the node-pty thread workers can be executed:
|
|
521
|
-
'worker/conoutSocketWorker': require.resolve('node-pty/lib/worker/conoutSocketWorker'),
|
|
522
|
-
'conpty_console_list_agent': require.resolve('node-pty/lib/conpty_console_list_agent'),`)}
|
|
523
|
-
${this.ifElectron("'electron-main': require.resolve('./src-gen/backend/electron-main'),")}
|
|
524
|
-
${this.ifPackage('@theia/dev-container', () => `// VS Code Dev-Container communication:
|
|
525
|
-
'dev-container-server': require.resolve('@theia/dev-container/lib/dev-container-server/dev-container-server'),`)}
|
|
526
|
-
...commonJsLibraries
|
|
527
|
-
},
|
|
528
|
-
module: {
|
|
529
|
-
rules: [
|
|
530
|
-
// Make sure we can still find and load our native addons.
|
|
531
|
-
{
|
|
532
|
-
test: /\\.node$/,
|
|
533
|
-
loader: 'node-loader',
|
|
534
|
-
options: {
|
|
535
|
-
name: 'native/[name].[ext]'
|
|
536
|
-
}
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
test: /\\.d\\.ts$/,
|
|
540
|
-
loader: 'ignore-loader'
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
test: /\\.js$/,
|
|
544
|
-
enforce: 'pre',
|
|
545
|
-
loader: 'source-map-loader'
|
|
546
|
-
},
|
|
547
|
-
// node-pty uses a dynamic require which needs to be rewritten to work with webpack.
|
|
548
|
-
{
|
|
549
|
-
test: /node_modules[/\\\\]node-pty[/\\\\]lib[/\\\\]utils\.js$/,
|
|
550
|
-
loader: 'string-replace-loader',
|
|
551
|
-
options: {
|
|
552
|
-
search: /require\\(/,
|
|
553
|
-
replace: '__non_webpack_require__(',
|
|
554
|
-
flags: 'g'
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
|
-
// jsonc-parser exposes its UMD implementation by default, which
|
|
558
|
-
// confuses Webpack leading to missing js in the bundles.
|
|
559
|
-
{
|
|
560
|
-
test: /node_modules[\\/](jsonc-parser)/,
|
|
561
|
-
loader: 'umd-compat-loader'
|
|
562
|
-
}
|
|
563
|
-
]
|
|
564
|
-
},
|
|
565
|
-
plugins: [
|
|
566
|
-
// Some native dependencies need special handling
|
|
567
|
-
nativePlugin,
|
|
568
|
-
// Optional node dependencies can be safely ignored
|
|
569
|
-
new webpack.IgnorePlugin({
|
|
570
|
-
checkResource: resource => ignoredResources.has(resource)
|
|
571
|
-
}),
|
|
572
|
-
new MonacoWebpackPlugin()
|
|
573
|
-
],
|
|
574
|
-
optimization: {
|
|
575
|
-
// Split and reuse code across the various entry points
|
|
576
|
-
splitChunks: {
|
|
577
|
-
chunks: 'all'
|
|
578
|
-
},
|
|
579
|
-
// Only minimize if we run webpack in production mode
|
|
580
|
-
minimize: production,
|
|
581
|
-
minimizer: [
|
|
582
|
-
new TerserPlugin({
|
|
583
|
-
exclude: /^(lib|builtins)\\//${this.ifPackage(['@theia/scanoss', '@theia/ai-anthropic', '@theia/ai-openai'], () => `,
|
|
584
|
-
terserOptions: {
|
|
585
|
-
keep_classnames: /AbortSignal/
|
|
586
|
-
}`)}
|
|
587
|
-
})
|
|
588
|
-
]
|
|
589
|
-
},
|
|
590
|
-
ignoreWarnings: [
|
|
591
|
-
// Some packages do not have source maps, that's ok
|
|
592
|
-
/Failed to parse source map/,
|
|
593
|
-
// require with expressions are not supported
|
|
594
|
-
/the request of a dependency is an expression/,
|
|
595
|
-
// Some packages use dynamic requires, we can safely ignore them (they are handled by the native webpack plugin)
|
|
596
|
-
/require function is used in a way in which dependencies cannot be statically extracted/, {
|
|
597
|
-
module: /yargs/
|
|
598
|
-
}, {
|
|
599
|
-
module: /node-pty/
|
|
600
|
-
}, {
|
|
601
|
-
module: /require-main-filename/
|
|
602
|
-
}, {
|
|
603
|
-
module: /ws/
|
|
604
|
-
}, {
|
|
605
|
-
module: /express/
|
|
606
|
-
}, {
|
|
607
|
-
module: /cross-spawn/
|
|
608
|
-
}, {
|
|
609
|
-
module: /@parcel\\/watcher/
|
|
610
|
-
}
|
|
611
|
-
]
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
module.exports = {
|
|
615
|
-
config,
|
|
616
|
-
nativePlugin,
|
|
617
|
-
ignoredResources
|
|
618
|
-
};
|
|
619
|
-
`;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
77
|
protected compileESBuildBrowserConfig(): string {
|
|
623
78
|
return `/**
|
|
624
79
|
* Don't touch this file. It will be regenerated by theia build.
|
|
@@ -626,7 +81,7 @@ module.exports = {
|
|
|
626
81
|
*/
|
|
627
82
|
import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill';
|
|
628
83
|
import { copy } from 'esbuild-plugin-copy';
|
|
629
|
-
import { monacoNlsPlugin, problemMatcherPlugin, sourceMapPathsPlugin } from '@theia/bundle-plugin';
|
|
84
|
+
import { compressAssetsPlugin, monacoNlsPlugin, problemMatcherPlugin, sourceMapPathsPlugin } from '@theia/bundle-plugin';
|
|
630
85
|
import yargs from 'yargs';
|
|
631
86
|
import { hideBin } from 'yargs/helpers';
|
|
632
87
|
import resolvePackagePath from 'resolve-package-path';
|
|
@@ -639,7 +94,7 @@ export function join(...parts) {
|
|
|
639
94
|
return path.join(...parts).replace(/\\\\/g, '/');
|
|
640
95
|
}
|
|
641
96
|
|
|
642
|
-
const { mode, watch } = yargs(hideBin(process.argv)).option('mode', {
|
|
97
|
+
const { mode, watch, staticCompression } = yargs(hideBin(process.argv)).option('mode', {
|
|
643
98
|
description: "Mode to use",
|
|
644
99
|
choices: ["development", "production"],
|
|
645
100
|
default: "production"
|
|
@@ -647,13 +102,24 @@ const { mode, watch } = yargs(hideBin(process.argv)).option('mode', {
|
|
|
647
102
|
description: 'Controls whether to enable watch mode',
|
|
648
103
|
type: 'boolean',
|
|
649
104
|
default: false
|
|
105
|
+
}).option('static-compression', {
|
|
106
|
+
description: ${this.ifElectron(
|
|
107
|
+
"'Controls whether to emit gzipped copies of the frontend assets. Disabled by default for Electron applications.'",
|
|
108
|
+
"'Controls whether to emit gzipped copies of the frontend assets. Enabled by default in production mode.'")},
|
|
109
|
+
type: 'boolean'
|
|
650
110
|
}).argv;
|
|
651
111
|
|
|
652
112
|
const production = mode === 'production';
|
|
653
113
|
const sourcemap = production ? false : 'linked';
|
|
654
114
|
const minify = production;
|
|
115
|
+
${this.ifElectron(
|
|
116
|
+
`// Electron loads the frontend from the local backend over loopback, where gzip saves nothing
|
|
117
|
+
// while the compressed copies still add to the size of the packaged application.
|
|
118
|
+
const compression = staticCompression ?? false;`,
|
|
119
|
+
`// Compressing on every rebuild would slow down watch mode, so this only pays off for production builds.
|
|
120
|
+
const compression = staticCompression ?? production;`)}
|
|
655
121
|
|
|
656
|
-
export { mode, watch, sourcemap, minify };
|
|
122
|
+
export { mode, watch, sourcemap, minify, compression };
|
|
657
123
|
|
|
658
124
|
/**
|
|
659
125
|
* @type {Record<string, import('esbuild').Loader>}
|
|
@@ -721,7 +187,9 @@ export const browserOptions = {
|
|
|
721
187
|
}`)}
|
|
722
188
|
]
|
|
723
189
|
}),
|
|
724
|
-
sourceMapPathsPlugin()
|
|
190
|
+
sourceMapPathsPlugin(),
|
|
191
|
+
// Keep last: it compresses whatever the preceding plugins emitted.
|
|
192
|
+
compressAssetsPlugin({ compress: compression })
|
|
725
193
|
]
|
|
726
194
|
};
|
|
727
195
|
`;
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
import { EOL } from 'os';
|
|
20
20
|
import { AbstractGenerator, GeneratorOptions } from './abstract-generator';
|
|
21
21
|
import { existsSync, readFileSync } from 'fs';
|
|
22
|
-
import { BundlerGenerator } from './bundler-generator';
|
|
23
22
|
|
|
24
23
|
export class FrontendGenerator extends AbstractGenerator {
|
|
25
24
|
|
|
@@ -63,12 +62,11 @@ export class FrontendGenerator extends AbstractGenerator {
|
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
protected async compileIndexHead(frontendModules: Map<string, string>): Promise<string> {
|
|
66
|
-
const preferEsbuild = await new BundlerGenerator(this.pck, this.options).preferESBuild();
|
|
67
65
|
return `
|
|
68
66
|
<meta charset="UTF-8">
|
|
69
67
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
70
68
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
71
|
-
|
|
69
|
+
<link rel="stylesheet" href="./bundle.css">
|
|
72
70
|
<title>${this.pck.props.frontend.config.applicationName}</title>`;
|
|
73
71
|
}
|
|
74
72
|
|