@theia/application-manager 1.47.1 → 1.48.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.
Files changed (38) hide show
  1. package/README.md +25 -25
  2. package/lib/application-package-manager.d.ts +45 -45
  3. package/lib/application-package-manager.js +225 -225
  4. package/lib/application-process.d.ts +19 -19
  5. package/lib/application-process.js +72 -72
  6. package/lib/expose-loader.d.ts +8 -8
  7. package/lib/expose-loader.js +69 -69
  8. package/lib/generator/abstract-generator.d.ts +17 -17
  9. package/lib/generator/abstract-generator.js +57 -57
  10. package/lib/generator/backend-generator.d.ts +7 -7
  11. package/lib/generator/backend-generator.js +196 -196
  12. package/lib/generator/frontend-generator.d.ts +13 -13
  13. package/lib/generator/frontend-generator.d.ts.map +1 -1
  14. package/lib/generator/frontend-generator.js +212 -221
  15. package/lib/generator/frontend-generator.js.map +1 -1
  16. package/lib/generator/index.d.ts +3 -3
  17. package/lib/generator/index.js +21 -21
  18. package/lib/generator/webpack-generator.d.ts +12 -12
  19. package/lib/generator/webpack-generator.d.ts.map +1 -1
  20. package/lib/generator/webpack-generator.js +493 -506
  21. package/lib/generator/webpack-generator.js.map +1 -1
  22. package/lib/index.d.ts +3 -3
  23. package/lib/index.js +21 -21
  24. package/lib/package.spec.js +25 -25
  25. package/lib/rebuild.d.ts +24 -24
  26. package/lib/rebuild.js +309 -309
  27. package/package.json +6 -7
  28. package/src/application-package-manager.ts +263 -263
  29. package/src/application-process.ts +80 -80
  30. package/src/expose-loader.ts +80 -80
  31. package/src/generator/abstract-generator.ts +69 -69
  32. package/src/generator/backend-generator.ts +198 -198
  33. package/src/generator/frontend-generator.ts +222 -231
  34. package/src/generator/index.ts +19 -19
  35. package/src/generator/webpack-generator.ts +501 -514
  36. package/src/index.ts +19 -19
  37. package/src/package.spec.ts +28 -28
  38. package/src/rebuild.ts +345 -345
@@ -1,514 +1,501 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2017 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import * as paths from 'path';
18
- import * as fs from 'fs-extra';
19
- import { AbstractGenerator } from './abstract-generator';
20
-
21
- export class WebpackGenerator extends AbstractGenerator {
22
-
23
- async generate(): Promise<void> {
24
- await this.write(this.genConfigPath, this.compileWebpackConfig());
25
- if (!this.pck.isBrowserOnly()) {
26
- await this.write(this.genNodeConfigPath, this.compileNodeWebpackConfig());
27
- }
28
- if (await this.shouldGenerateUserWebpackConfig()) {
29
- await this.write(this.configPath, this.compileUserWebpackConfig());
30
- }
31
- }
32
-
33
- protected async shouldGenerateUserWebpackConfig(): Promise<boolean> {
34
- if (!(await fs.pathExists(this.configPath))) {
35
- return true;
36
- }
37
- const content = await fs.readFile(this.configPath, 'utf8');
38
- return content.indexOf('gen-webpack') === -1;
39
- }
40
-
41
- get configPath(): string {
42
- return this.pck.path('webpack.config.js');
43
- }
44
-
45
- get genConfigPath(): string {
46
- return this.pck.path('gen-webpack.config.js');
47
- }
48
-
49
- get genNodeConfigPath(): string {
50
- return this.pck.path('gen-webpack.node.config.js');
51
- }
52
-
53
- protected resolve(moduleName: string, path: string): string {
54
- return this.pck.resolveModulePath(moduleName, path).split(paths.sep).join('/');
55
- }
56
-
57
- protected compileWebpackConfig(): string {
58
- return `/**
59
- * Don't touch this file. It will be regenerated by theia build.
60
- * To customize webpack configuration change ${this.configPath}
61
- */
62
- // @ts-check
63
- const path = require('path');
64
- const webpack = require('webpack');
65
- const yargs = require('yargs');
66
- const resolvePackagePath = require('resolve-package-path');
67
- const CopyWebpackPlugin = require('copy-webpack-plugin');
68
- const CompressionPlugin = require('compression-webpack-plugin')
69
- const MiniCssExtractPlugin = require('mini-css-extract-plugin')
70
-
71
- const outputPath = path.resolve(__dirname, 'lib', 'frontend');
72
- const { mode, staticCompression } = yargs.option('mode', {
73
- description: "Mode to use",
74
- choices: ["development", "production"],
75
- default: "production"
76
- }).option('static-compression', {
77
- description: 'Controls whether to enable compression of static artifacts.',
78
- type: 'boolean',
79
- default: true
80
- }).argv;
81
- const development = mode === 'development';
82
-
83
- const plugins = [
84
- new CopyWebpackPlugin({
85
- patterns: [
86
- {
87
- // copy secondary window html file to lib folder
88
- from: path.resolve(__dirname, 'src-gen/frontend/secondary-window.html')
89
- }${this.ifPackage('@theia/plugin-ext', `,
90
- {
91
- // copy webview files to lib folder
92
- from: path.join(resolvePackagePath('@theia/plugin-ext', __dirname), '..', 'src', 'main', 'browser', 'webview', 'pre'),
93
- to: path.resolve(__dirname, 'lib', 'webview', 'pre')
94
- }`)}
95
- ${this.ifPackage('@theia/plugin-ext-vscode', `,
96
- {
97
- // copy frontend plugin host files
98
- from: path.join(resolvePackagePath('@theia/plugin-ext-vscode', __dirname), '..', 'lib', 'node', 'context', 'plugin-vscode-init-fe.js'),
99
- to: path.resolve(__dirname, 'lib', 'frontend', 'context', 'plugin-vscode-init-fe.js')
100
- }`)}
101
- ]
102
- }),
103
- new webpack.ProvidePlugin({
104
- // the Buffer class doesn't exist in the browser but some dependencies rely on it
105
- Buffer: ['buffer', 'Buffer']
106
- })
107
- ];
108
- // it should go after copy-plugin in order to compress monaco as well
109
- if (staticCompression) {
110
- plugins.push(new CompressionPlugin({}));
111
- }
112
-
113
- module.exports = [{
114
- mode,
115
- plugins,
116
- devtool: 'source-map',
117
- entry: {
118
- bundle: path.resolve(__dirname, 'src-gen/frontend/index.js'),
119
- ${this.ifMonaco(() => "'editor.worker': '@theia/monaco-editor-core/esm/vs/editor/editor.worker.js'")}
120
- },
121
- output: {
122
- filename: '[name].js',
123
- path: outputPath,
124
- devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
125
- globalObject: 'self'
126
- },
127
- target: 'web',
128
- cache: staticCompression,
129
- module: {
130
- rules: [
131
- {
132
- // Removes the host check in PhosphorJS to enable moving widgets to secondary windows.
133
- test: /widget\\.js$/,
134
- loader: 'string-replace-loader',
135
- include: /node_modules[\\\\/]@phosphor[\\\\/]widgets[\\\\/]lib/,
136
- options: {
137
- multiple: [
138
- {
139
- search: /document\\.body\\.contains\\(widget.node\\)/gm,
140
- replace: 'widget.node.ownerDocument.body.contains(widget.node)'
141
- },
142
- {
143
- search: /\\!document\\.body\\.contains\\(host\\)/gm,
144
- replace: ' !host.ownerDocument.body.contains(host)'
145
- }
146
- ]
147
- }
148
- },
149
- {
150
- test: /\\.css$/,
151
- exclude: /materialcolors\\.css$|\\.useable\\.css$/,
152
- use: ['style-loader', 'css-loader']
153
- },
154
- {
155
- test: /materialcolors\\.css$|\\.useable\\.css$/,
156
- use: [
157
- {
158
- loader: 'style-loader',
159
- options: {
160
- esModule: false,
161
- injectType: 'lazySingletonStyleTag',
162
- attributes: {
163
- id: 'theia-theme'
164
- }
165
- }
166
- },
167
- 'css-loader'
168
- ]
169
- },
170
- {
171
- test: /\\.(ttf|eot|svg)(\\?v=\\d+\\.\\d+\\.\\d+)?$/,
172
- type: 'asset',
173
- parser: {
174
- dataUrlCondition: {
175
- maxSize: 10000,
176
- }
177
- },
178
- generator: {
179
- dataUrl: {
180
- mimetype: 'image/svg+xml'
181
- }
182
- }
183
- },
184
- {
185
- test: /\\.(jpg|png|gif)$/,
186
- type: 'asset/resource',
187
- generator: {
188
- filename: '[hash].[ext]'
189
- }
190
- },
191
- {
192
- // see https://github.com/eclipse-theia/theia/issues/556
193
- test: /source-map-support/,
194
- loader: 'ignore-loader'
195
- },
196
- {
197
- test: /\\.js$/,
198
- enforce: 'pre',
199
- loader: 'source-map-loader',
200
- exclude: /jsonc-parser|fast-plist|onigasm/
201
- },
202
- {
203
- test: /\\.woff(2)?(\\?v=[0-9]\\.[0-9]\\.[0-9])?$/,
204
- type: 'asset',
205
- parser: {
206
- dataUrlCondition: {
207
- maxSize: 10000,
208
- }
209
- },
210
- generator: {
211
- dataUrl: {
212
- mimetype: 'image/svg+xml'
213
- }
214
- }
215
- },
216
- {
217
- test: /node_modules[\\\\|\/](vscode-languageserver-types|vscode-uri|jsonc-parser|vscode-languageserver-protocol)/,
218
- loader: 'umd-compat-loader'
219
- },
220
- {
221
- test: /\\.wasm$/,
222
- type: 'asset/resource'
223
- },
224
- {
225
- test: /\\.plist$/,
226
- type: 'asset/resource'
227
- }
228
- ]
229
- },
230
- resolve: {
231
- fallback: {
232
- 'child_process': false,
233
- 'crypto': false,
234
- 'net': false,
235
- 'path': require.resolve('path-browserify'),
236
- 'process': false,
237
- 'os': false,
238
- 'timers': false
239
- },
240
- extensions: ['.js']
241
- },
242
- stats: {
243
- warnings: true,
244
- children: true
245
- },
246
- ignoreWarnings: [
247
- // Some packages do not have source maps, that's ok
248
- /Failed to parse source map/,
249
- {
250
- // Monaco uses 'require' in a non-standard way
251
- module: /@theia\\/monaco-editor-core/,
252
- message: /require function is used in a way in which dependencies cannot be statically extracted/
253
- }
254
- ]
255
- },
256
- {
257
- mode,
258
- plugins: [
259
- new MiniCssExtractPlugin({
260
- // Options similar to the same options in webpackOptions.output
261
- // both options are optional
262
- filename: "[name].css",
263
- chunkFilename: "[id].css",
264
- }),
265
- ],
266
- devtool: 'source-map',
267
- entry: {
268
- "secondary-window": path.resolve(__dirname, 'src-gen/frontend/secondary-index.js'),
269
- },
270
- output: {
271
- filename: '[name].js',
272
- path: outputPath,
273
- devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
274
- globalObject: 'self'
275
- },
276
- target: 'web',
277
- cache: staticCompression,
278
- module: {
279
- rules: [
280
- {
281
- test: /\.css$/i,
282
- use: [MiniCssExtractPlugin.loader, "css-loader"]
283
- }
284
- ]
285
- },
286
- resolve: {
287
- fallback: {
288
- 'child_process': false,
289
- 'crypto': false,
290
- 'net': false,
291
- 'path': require.resolve('path-browserify'),
292
- 'process': false,
293
- 'os': false,
294
- 'timers': false
295
- },
296
- extensions: ['.js']
297
- },
298
- stats: {
299
- warnings: true,
300
- children: true
301
- },
302
- ignoreWarnings: [
303
- {
304
- // Monaco uses 'require' in a non-standard way
305
- module: /@theia\\/monaco-editor-core/,
306
- message: /require function is used in a way in which dependencies cannot be statically extracted/
307
- }
308
- ]
309
- }${this.ifElectron(`, {
310
- mode,
311
- devtool: 'source-map',
312
- entry: {
313
- "preload": path.resolve(__dirname, 'src-gen/frontend/preload.js'),
314
- },
315
- output: {
316
- filename: '[name].js',
317
- path: outputPath,
318
- devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
319
- globalObject: 'self'
320
- },
321
- target: 'electron-preload',
322
- cache: staticCompression,
323
- stats: {
324
- warnings: true,
325
- children: true
326
- }
327
- }`)}];`;
328
- }
329
-
330
- protected compileUserWebpackConfig(): string {
331
- return `/**
332
- * This file can be edited to customize webpack configuration.
333
- * To reset delete this file and rerun theia build again.
334
- */
335
- // @ts-check
336
- const configs = require('./${paths.basename(this.genConfigPath)}');
337
- ${this.ifBrowserOnly('', `const nodeConfig = require('./${paths.basename(this.genNodeConfigPath)}');`)}
338
-
339
- /**
340
- * Expose bundled modules on window.theia.moduleName namespace, e.g.
341
- * window['theia']['@theia/core/lib/common/uri'].
342
- * Such syntax can be used by external code, for instance, for testing.
343
- configs[0].module.rules.push({
344
- test: /\\.js$/,
345
- loader: require.resolve('@theia/application-manager/lib/expose-loader')
346
- }); */
347
-
348
- ${this.ifBrowserOnly('module.exports = configs;', `module.exports = [
349
- ...configs,
350
- nodeConfig.config
351
- ];`)}
352
- `;
353
- }
354
-
355
- protected compileNodeWebpackConfig(): string {
356
- return `/**
357
- * Don't touch this file. It will be regenerated by theia build.
358
- * To customize webpack configuration change ${this.configPath}
359
- */
360
- // @ts-check
361
- const path = require('path');
362
- const yargs = require('yargs');
363
- const webpack = require('webpack');
364
- const TerserPlugin = require('terser-webpack-plugin');
365
- const NativeWebpackPlugin = require('@theia/native-webpack-plugin');
366
-
367
- const { mode } = yargs.option('mode', {
368
- description: "Mode to use",
369
- choices: ["development", "production"],
370
- default: "production"
371
- }).argv;
372
-
373
- const production = mode === 'production';
374
-
375
- /** @type {import('webpack').EntryObject} */
376
- const commonJsLibraries = {};
377
- for (const [entryPointName, entryPointPath] of Object.entries({
378
- ${this.ifPackage('@theia/plugin-ext', "'backend-init-theia': '@theia/plugin-ext/lib/hosted/node/scanners/backend-init-theia',")}
379
- ${this.ifPackage('@theia/filesystem', "'nsfw-watcher': '@theia/filesystem/lib/node/nsfw-watcher',")}
380
- ${this.ifPackage('@theia/plugin-ext-vscode', "'plugin-vscode-init': '@theia/plugin-ext-vscode/lib/node/plugin-vscode-init',")}
381
- ${this.ifPackage('@theia/api-provider-sample', "'gotd-api-init': '@theia/api-provider-sample/lib/plugin/gotd-api-init',")}
382
- })) {
383
- commonJsLibraries[entryPointName] = {
384
- import: require.resolve(entryPointPath),
385
- library: {
386
- type: 'commonjs2',
387
- },
388
- };
389
- }
390
-
391
- const ignoredResources = new Set();
392
-
393
- if (process.platform !== 'win32') {
394
- ignoredResources.add('@vscode/windows-ca-certs');
395
- ignoredResources.add('@vscode/windows-ca-certs/build/Release/crypt32.node');
396
- }
397
-
398
- const nativePlugin = new NativeWebpackPlugin({
399
- out: 'native',
400
- trash: ${this.ifPackage('@theia/filesystem', 'true', 'false')},
401
- ripgrep: ${this.ifPackage(['@theia/search-in-workspace', '@theia/file-search'], 'true', 'false')},
402
- pty: ${this.ifPackage('@theia/process', 'true', 'false')},
403
- nativeBindings: {
404
- drivelist: 'drivelist/build/Release/drivelist.node'
405
- }
406
- });
407
-
408
- /** @type {import('webpack').Configuration} */
409
- const config = {
410
- mode,
411
- devtool: mode === 'development' ? 'source-map' : false,
412
- target: 'node',
413
- node: {
414
- global: false,
415
- __filename: false,
416
- __dirname: false
417
- },
418
- output: {
419
- filename: '[name].js',
420
- path: path.resolve(__dirname, 'lib', 'backend'),
421
- devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]?[loaders]',
422
- },${this.ifElectron(`
423
- externals: {
424
- electron: 'require("electron")'
425
- },`)}
426
- entry: {
427
- // Main entry point of the Theia application backend:
428
- 'main': require.resolve('./src-gen/backend/main'),
429
- // Theia's IPC mechanism:
430
- 'ipc-bootstrap': require.resolve('@theia/core/lib/node/messaging/ipc-bootstrap'),
431
- ${this.ifPackage('@theia/plugin-ext', () => `// VS Code extension support:
432
- 'plugin-host': require.resolve('@theia/plugin-ext/lib/hosted/node/plugin-host'),`)}
433
- ${this.ifPackage('@theia/plugin-ext-headless', () => `// Theia Headless Plugin support:
434
- 'plugin-host-headless': require.resolve('@theia/plugin-ext-headless/lib/hosted/node/plugin-host-headless'),`)}
435
- ${this.ifPackage('@theia/process', () => `// Make sure the node-pty thread worker can be executed:
436
- 'worker/conoutSocketWorker': require.resolve('node-pty/lib/worker/conoutSocketWorker'),`)}
437
- ${this.ifPackage('@theia/git', () => `// Ensure the git locator process can the started
438
- 'git-locator-host': require.resolve('@theia/git/lib/node/git-locator/git-locator-host'),`)}
439
- ${this.ifElectron("'electron-main': require.resolve('./src-gen/backend/electron-main'),")}
440
- ...commonJsLibraries
441
- },
442
- module: {
443
- rules: [
444
- // Make sure we can still find and load our native addons.
445
- {
446
- test: /\\.node$/,
447
- loader: 'node-loader',
448
- options: {
449
- name: 'native/[name].[ext]'
450
- }
451
- },
452
- {
453
- test: /\\.js$/,
454
- enforce: 'pre',
455
- loader: 'source-map-loader'
456
- },
457
- // jsonc-parser exposes its UMD implementation by default, which
458
- // confuses Webpack leading to missing js in the bundles.
459
- {
460
- test: /node_modules[\\/](jsonc-parser)/,
461
- loader: 'umd-compat-loader'
462
- }
463
- ]
464
- },
465
- plugins: [
466
- // Some native dependencies need special handling
467
- nativePlugin,
468
- // Optional node dependencies can be safely ignored
469
- new webpack.IgnorePlugin({
470
- checkResource: resource => ignoredResources.has(resource)
471
- })
472
- ],
473
- optimization: {
474
- // Split and reuse code across the various entry points
475
- splitChunks: {
476
- chunks: 'all'
477
- },
478
- // Only minimize if we run webpack in production mode
479
- minimize: production,
480
- minimizer: [
481
- new TerserPlugin({
482
- exclude: /^(lib|builtins)\\//
483
- })
484
- ]
485
- },
486
- ignoreWarnings: [
487
- // Some packages do not have source maps, that's ok
488
- /Failed to parse source map/,
489
- // Some packages use dynamic requires, we can safely ignore them (they are handled by the native webpack plugin)
490
- /require function is used in a way in which dependencies cannot be statically extracted/, {
491
- module: /yargs/
492
- }, {
493
- module: /node-pty/
494
- }, {
495
- module: /require-main-filename/
496
- }, {
497
- module: /ws/
498
- }, {
499
- module: /express/
500
- }, {
501
- module: /cross-spawn/
502
- }
503
- ]
504
- };
505
-
506
- module.exports = {
507
- config,
508
- nativePlugin,
509
- ignoredResources
510
- };
511
- `;
512
- }
513
-
514
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2017 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import * as paths from 'path';
18
+ import * as fs from 'fs-extra';
19
+ import { AbstractGenerator } from './abstract-generator';
20
+
21
+ export class WebpackGenerator extends AbstractGenerator {
22
+
23
+ async generate(): Promise<void> {
24
+ await this.write(this.genConfigPath, this.compileWebpackConfig());
25
+ if (!this.pck.isBrowserOnly()) {
26
+ await this.write(this.genNodeConfigPath, this.compileNodeWebpackConfig());
27
+ }
28
+ if (await this.shouldGenerateUserWebpackConfig()) {
29
+ await this.write(this.configPath, this.compileUserWebpackConfig());
30
+ }
31
+ }
32
+
33
+ protected async shouldGenerateUserWebpackConfig(): Promise<boolean> {
34
+ if (!(await fs.pathExists(this.configPath))) {
35
+ return true;
36
+ }
37
+ const content = await fs.readFile(this.configPath, 'utf8');
38
+ return content.indexOf('gen-webpack') === -1;
39
+ }
40
+
41
+ get configPath(): string {
42
+ return this.pck.path('webpack.config.js');
43
+ }
44
+
45
+ get genConfigPath(): string {
46
+ return this.pck.path('gen-webpack.config.js');
47
+ }
48
+
49
+ get genNodeConfigPath(): string {
50
+ return this.pck.path('gen-webpack.node.config.js');
51
+ }
52
+
53
+ protected resolve(moduleName: string, path: string): string {
54
+ return this.pck.resolveModulePath(moduleName, path).split(paths.sep).join('/');
55
+ }
56
+
57
+ protected compileWebpackConfig(): string {
58
+ return `/**
59
+ * Don't touch this file. It will be regenerated by theia build.
60
+ * To customize webpack configuration change ${this.configPath}
61
+ */
62
+ // @ts-check
63
+ const path = require('path');
64
+ const webpack = require('webpack');
65
+ const yargs = require('yargs');
66
+ const resolvePackagePath = require('resolve-package-path');
67
+ const CopyWebpackPlugin = require('copy-webpack-plugin');
68
+ const CompressionPlugin = require('compression-webpack-plugin')
69
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
70
+
71
+ const outputPath = path.resolve(__dirname, 'lib', 'frontend');
72
+ const { mode, staticCompression } = yargs.option('mode', {
73
+ description: "Mode to use",
74
+ choices: ["development", "production"],
75
+ default: "production"
76
+ }).option('static-compression', {
77
+ description: 'Controls whether to enable compression of static artifacts.',
78
+ type: 'boolean',
79
+ default: true
80
+ }).argv;
81
+ const development = mode === 'development';
82
+
83
+ const plugins = [
84
+ new CopyWebpackPlugin({
85
+ patterns: [
86
+ {
87
+ // copy secondary window html file to lib folder
88
+ from: path.resolve(__dirname, 'src-gen/frontend/secondary-window.html')
89
+ }${this.ifPackage('@theia/plugin-ext', `,
90
+ {
91
+ // copy webview files to lib folder
92
+ from: path.join(resolvePackagePath('@theia/plugin-ext', __dirname), '..', 'src', 'main', 'browser', 'webview', 'pre'),
93
+ to: path.resolve(__dirname, 'lib', 'webview', 'pre')
94
+ }`)}
95
+ ${this.ifPackage('@theia/plugin-ext-vscode', `,
96
+ {
97
+ // copy frontend plugin host files
98
+ from: path.join(resolvePackagePath('@theia/plugin-ext-vscode', __dirname), '..', 'lib', 'node', 'context', 'plugin-vscode-init-fe.js'),
99
+ to: path.resolve(__dirname, 'lib', 'frontend', 'context', 'plugin-vscode-init-fe.js')
100
+ }`)}
101
+ ]
102
+ }),
103
+ new webpack.ProvidePlugin({
104
+ // the Buffer class doesn't exist in the browser but some dependencies rely on it
105
+ Buffer: ['buffer', 'Buffer']
106
+ })
107
+ ];
108
+ // it should go after copy-plugin in order to compress monaco as well
109
+ if (staticCompression) {
110
+ plugins.push(new CompressionPlugin({}));
111
+ }
112
+
113
+ module.exports = [{
114
+ mode,
115
+ plugins,
116
+ devtool: 'source-map',
117
+ entry: {
118
+ bundle: path.resolve(__dirname, 'src-gen/frontend/index.js'),
119
+ ${this.ifMonaco(() => "'editor.worker': '@theia/monaco-editor-core/esm/vs/editor/editor.worker.js'")}
120
+ },
121
+ output: {
122
+ filename: '[name].js',
123
+ path: outputPath,
124
+ devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
125
+ globalObject: 'self'
126
+ },
127
+ target: 'web',
128
+ cache: staticCompression,
129
+ module: {
130
+ rules: [
131
+ {
132
+ test: /\\.css$/,
133
+ exclude: /materialcolors\\.css$|\\.useable\\.css$/,
134
+ use: ['style-loader', 'css-loader']
135
+ },
136
+ {
137
+ test: /materialcolors\\.css$|\\.useable\\.css$/,
138
+ use: [
139
+ {
140
+ loader: 'style-loader',
141
+ options: {
142
+ esModule: false,
143
+ injectType: 'lazySingletonStyleTag',
144
+ attributes: {
145
+ id: 'theia-theme'
146
+ }
147
+ }
148
+ },
149
+ 'css-loader'
150
+ ]
151
+ },
152
+ {
153
+ test: /\\.(ttf|eot|svg)(\\?v=\\d+\\.\\d+\\.\\d+)?$/,
154
+ type: 'asset',
155
+ parser: {
156
+ dataUrlCondition: {
157
+ maxSize: 10000,
158
+ }
159
+ },
160
+ generator: {
161
+ dataUrl: {
162
+ mimetype: 'image/svg+xml'
163
+ }
164
+ }
165
+ },
166
+ {
167
+ test: /\\.(jpg|png|gif)$/,
168
+ type: 'asset/resource',
169
+ generator: {
170
+ filename: '[hash].[ext]'
171
+ }
172
+ },
173
+ {
174
+ // see https://github.com/eclipse-theia/theia/issues/556
175
+ test: /source-map-support/,
176
+ loader: 'ignore-loader'
177
+ },
178
+ {
179
+ test: /\\.js$/,
180
+ enforce: 'pre',
181
+ loader: 'source-map-loader',
182
+ exclude: /jsonc-parser|fast-plist|onigasm/
183
+ },
184
+ {
185
+ test: /\\.woff(2)?(\\?v=[0-9]\\.[0-9]\\.[0-9])?$/,
186
+ type: 'asset',
187
+ parser: {
188
+ dataUrlCondition: {
189
+ maxSize: 10000,
190
+ }
191
+ },
192
+ generator: {
193
+ dataUrl: {
194
+ mimetype: 'image/svg+xml'
195
+ }
196
+ }
197
+ },
198
+ {
199
+ test: /node_modules[\\\\|\/](vscode-languageserver-types|vscode-uri|jsonc-parser|vscode-languageserver-protocol)/,
200
+ loader: 'umd-compat-loader'
201
+ },
202
+ {
203
+ test: /\\.wasm$/,
204
+ type: 'asset/resource'
205
+ },
206
+ {
207
+ test: /\\.plist$/,
208
+ type: 'asset/resource'
209
+ }
210
+ ]
211
+ },
212
+ resolve: {
213
+ fallback: {
214
+ 'child_process': false,
215
+ 'crypto': false,
216
+ 'net': false,
217
+ 'path': require.resolve('path-browserify'),
218
+ 'process': false,
219
+ 'os': false,
220
+ 'timers': false
221
+ },
222
+ extensions: ['.js']
223
+ },
224
+ stats: {
225
+ warnings: true,
226
+ children: true
227
+ },
228
+ ignoreWarnings: [
229
+ // Some packages do not have source maps, that's ok
230
+ /Failed to parse source map/,
231
+ {
232
+ // Monaco uses 'require' in a non-standard way
233
+ module: /@theia\\/monaco-editor-core/,
234
+ message: /require function is used in a way in which dependencies cannot be statically extracted/
235
+ }
236
+ ]
237
+ },
238
+ {
239
+ mode,
240
+ plugins: [
241
+ new MiniCssExtractPlugin({
242
+ // Options similar to the same options in webpackOptions.output
243
+ // both options are optional
244
+ filename: "[name].css",
245
+ chunkFilename: "[id].css",
246
+ }),
247
+ ],
248
+ devtool: 'source-map',
249
+ entry: {
250
+ "secondary-window": path.resolve(__dirname, 'src-gen/frontend/secondary-index.js'),
251
+ },
252
+ output: {
253
+ filename: '[name].js',
254
+ path: outputPath,
255
+ devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
256
+ globalObject: 'self'
257
+ },
258
+ target: 'web',
259
+ cache: staticCompression,
260
+ module: {
261
+ rules: [
262
+ {
263
+ test: /\.css$/i,
264
+ use: [MiniCssExtractPlugin.loader, "css-loader"]
265
+ },
266
+ {
267
+ test: /\.wasm$/,
268
+ type: 'asset/resource'
269
+ }
270
+ ]
271
+ },
272
+ resolve: {
273
+ fallback: {
274
+ 'child_process': false,
275
+ 'crypto': false,
276
+ 'net': false,
277
+ 'path': require.resolve('path-browserify'),
278
+ 'process': false,
279
+ 'os': false,
280
+ 'timers': false
281
+ },
282
+ extensions: ['.js']
283
+ },
284
+ stats: {
285
+ warnings: true,
286
+ children: true
287
+ },
288
+ ignoreWarnings: [
289
+ {
290
+ // Monaco uses 'require' in a non-standard way
291
+ module: /@theia\\/monaco-editor-core/,
292
+ message: /require function is used in a way in which dependencies cannot be statically extracted/
293
+ }
294
+ ]
295
+ }${this.ifElectron(`, {
296
+ mode,
297
+ devtool: 'source-map',
298
+ entry: {
299
+ "preload": path.resolve(__dirname, 'src-gen/frontend/preload.js'),
300
+ },
301
+ output: {
302
+ filename: '[name].js',
303
+ path: outputPath,
304
+ devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[loaders]',
305
+ globalObject: 'self'
306
+ },
307
+ target: 'electron-preload',
308
+ cache: staticCompression,
309
+ stats: {
310
+ warnings: true,
311
+ children: true
312
+ }
313
+ }`)}];`;
314
+ }
315
+
316
+ protected compileUserWebpackConfig(): string {
317
+ return `/**
318
+ * This file can be edited to customize webpack configuration.
319
+ * To reset delete this file and rerun theia build again.
320
+ */
321
+ // @ts-check
322
+ const configs = require('./${paths.basename(this.genConfigPath)}');
323
+ ${this.ifBrowserOnly('', `const nodeConfig = require('./${paths.basename(this.genNodeConfigPath)}');`)}
324
+
325
+ /**
326
+ * Expose bundled modules on window.theia.moduleName namespace, e.g.
327
+ * window['theia']['@theia/core/lib/common/uri'].
328
+ * Such syntax can be used by external code, for instance, for testing.
329
+ configs[0].module.rules.push({
330
+ test: /\\.js$/,
331
+ loader: require.resolve('@theia/application-manager/lib/expose-loader')
332
+ }); */
333
+
334
+ ${this.ifBrowserOnly('module.exports = configs;', `module.exports = [
335
+ ...configs,
336
+ nodeConfig.config
337
+ ];`)}
338
+ `;
339
+ }
340
+
341
+ protected compileNodeWebpackConfig(): string {
342
+ return `/**
343
+ * Don't touch this file. It will be regenerated by theia build.
344
+ * To customize webpack configuration change ${this.configPath}
345
+ */
346
+ // @ts-check
347
+ const path = require('path');
348
+ const yargs = require('yargs');
349
+ const webpack = require('webpack');
350
+ const TerserPlugin = require('terser-webpack-plugin');
351
+ const NativeWebpackPlugin = require('@theia/native-webpack-plugin');
352
+
353
+ const { mode } = yargs.option('mode', {
354
+ description: "Mode to use",
355
+ choices: ["development", "production"],
356
+ default: "production"
357
+ }).argv;
358
+
359
+ const production = mode === 'production';
360
+
361
+ /** @type {import('webpack').EntryObject} */
362
+ const commonJsLibraries = {};
363
+ for (const [entryPointName, entryPointPath] of Object.entries({
364
+ ${this.ifPackage('@theia/plugin-ext', "'backend-init-theia': '@theia/plugin-ext/lib/hosted/node/scanners/backend-init-theia',")}
365
+ ${this.ifPackage('@theia/filesystem', "'nsfw-watcher': '@theia/filesystem/lib/node/nsfw-watcher',")}
366
+ ${this.ifPackage('@theia/plugin-ext-vscode', "'plugin-vscode-init': '@theia/plugin-ext-vscode/lib/node/plugin-vscode-init',")}
367
+ ${this.ifPackage('@theia/api-provider-sample', "'gotd-api-init': '@theia/api-provider-sample/lib/plugin/gotd-api-init',")}
368
+ ${this.ifPackage('@theia/git', "'git-locator-host': '@theia/git/lib/node/git-locator/git-locator-host',")}
369
+ })) {
370
+ commonJsLibraries[entryPointName] = {
371
+ import: require.resolve(entryPointPath),
372
+ library: {
373
+ type: 'commonjs2',
374
+ },
375
+ };
376
+ }
377
+
378
+ const ignoredResources = new Set();
379
+
380
+ if (process.platform !== 'win32') {
381
+ ignoredResources.add('@vscode/windows-ca-certs');
382
+ ignoredResources.add('@vscode/windows-ca-certs/build/Release/crypt32.node');
383
+ }
384
+
385
+ const nativePlugin = new NativeWebpackPlugin({
386
+ out: 'native',
387
+ trash: ${this.ifPackage('@theia/filesystem', 'true', 'false')},
388
+ ripgrep: ${this.ifPackage(['@theia/search-in-workspace', '@theia/file-search'], 'true', 'false')},
389
+ pty: ${this.ifPackage('@theia/process', 'true', 'false')},
390
+ nativeBindings: {
391
+ drivelist: 'drivelist/build/Release/drivelist.node'
392
+ }
393
+ });
394
+
395
+ /** @type {import('webpack').Configuration} */
396
+ const config = {
397
+ mode,
398
+ devtool: mode === 'development' ? 'source-map' : false,
399
+ target: 'node',
400
+ node: {
401
+ global: false,
402
+ __filename: false,
403
+ __dirname: false
404
+ },
405
+ output: {
406
+ filename: '[name].js',
407
+ path: path.resolve(__dirname, 'lib', 'backend'),
408
+ devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]?[loaders]',
409
+ },${this.ifElectron(`
410
+ externals: {
411
+ electron: 'require("electron")'
412
+ },`)}
413
+ entry: {
414
+ // Main entry point of the Theia application backend:
415
+ 'main': require.resolve('./src-gen/backend/main'),
416
+ // Theia's IPC mechanism:
417
+ 'ipc-bootstrap': require.resolve('@theia/core/lib/node/messaging/ipc-bootstrap'),
418
+ ${this.ifPackage('@theia/plugin-ext', () => `// VS Code extension support:
419
+ 'plugin-host': require.resolve('@theia/plugin-ext/lib/hosted/node/plugin-host'),`)}
420
+ ${this.ifPackage('@theia/plugin-ext-headless', () => `// Theia Headless Plugin support:
421
+ 'plugin-host-headless': require.resolve('@theia/plugin-ext-headless/lib/hosted/node/plugin-host-headless'),`)}
422
+ ${this.ifPackage('@theia/process', () => `// Make sure the node-pty thread worker can be executed:
423
+ 'worker/conoutSocketWorker': require.resolve('node-pty/lib/worker/conoutSocketWorker'),`)}
424
+ ${this.ifElectron("'electron-main': require.resolve('./src-gen/backend/electron-main'),")}
425
+ ${this.ifPackage('@theia/dev-container', () => `// VS Code Dev-Container communication:
426
+ 'dev-container-server': require.resolve('@theia/dev-container/lib/dev-container-server/dev-container-server'),`)}
427
+ ...commonJsLibraries
428
+ },
429
+ module: {
430
+ rules: [
431
+ // Make sure we can still find and load our native addons.
432
+ {
433
+ test: /\\.node$/,
434
+ loader: 'node-loader',
435
+ options: {
436
+ name: 'native/[name].[ext]'
437
+ }
438
+ },
439
+ {
440
+ test: /\\.js$/,
441
+ enforce: 'pre',
442
+ loader: 'source-map-loader'
443
+ },
444
+ // jsonc-parser exposes its UMD implementation by default, which
445
+ // confuses Webpack leading to missing js in the bundles.
446
+ {
447
+ test: /node_modules[\\/](jsonc-parser)/,
448
+ loader: 'umd-compat-loader'
449
+ }
450
+ ]
451
+ },
452
+ plugins: [
453
+ // Some native dependencies need special handling
454
+ nativePlugin,
455
+ // Optional node dependencies can be safely ignored
456
+ new webpack.IgnorePlugin({
457
+ checkResource: resource => ignoredResources.has(resource)
458
+ })
459
+ ],
460
+ optimization: {
461
+ // Split and reuse code across the various entry points
462
+ splitChunks: {
463
+ chunks: 'all'
464
+ },
465
+ // Only minimize if we run webpack in production mode
466
+ minimize: production,
467
+ minimizer: [
468
+ new TerserPlugin({
469
+ exclude: /^(lib|builtins)\\//
470
+ })
471
+ ]
472
+ },
473
+ ignoreWarnings: [
474
+ // Some packages do not have source maps, that's ok
475
+ /Failed to parse source map/,
476
+ // Some packages use dynamic requires, we can safely ignore them (they are handled by the native webpack plugin)
477
+ /require function is used in a way in which dependencies cannot be statically extracted/, {
478
+ module: /yargs/
479
+ }, {
480
+ module: /node-pty/
481
+ }, {
482
+ module: /require-main-filename/
483
+ }, {
484
+ module: /ws/
485
+ }, {
486
+ module: /express/
487
+ }, {
488
+ module: /cross-spawn/
489
+ }
490
+ ]
491
+ };
492
+
493
+ module.exports = {
494
+ config,
495
+ nativePlugin,
496
+ ignoredResources
497
+ };
498
+ `;
499
+ }
500
+
501
+ }