Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/gulpfile.vscode.web.js
3520 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
'use strict';
7
8
const gulp = require('gulp');
9
const path = require('path');
10
const es = require('event-stream');
11
const util = require('./lib/util');
12
const { getVersion } = require('./lib/getVersion');
13
const task = require('./lib/task');
14
const optimize = require('./lib/optimize');
15
const { readISODate } = require('./lib/date');
16
const product = require('../product.json');
17
const rename = require('gulp-rename');
18
const filter = require('gulp-filter');
19
const { getProductionDependencies } = require('./lib/dependencies');
20
const vfs = require('vinyl-fs');
21
const packageJson = require('../package.json');
22
const { compileBuildWithManglingTask } = require('./gulpfile.compile');
23
const extensions = require('./lib/extensions');
24
const VinylFile = require('vinyl');
25
26
const REPO_ROOT = path.dirname(__dirname);
27
const BUILD_ROOT = path.dirname(REPO_ROOT);
28
const WEB_FOLDER = path.join(REPO_ROOT, 'remote', 'web');
29
30
const commit = getVersion(REPO_ROOT);
31
const quality = product.quality;
32
const version = (quality && quality !== 'stable') ? `${packageJson.version}-${quality}` : packageJson.version;
33
34
const vscodeWebResourceIncludes = [
35
36
// NLS
37
'out-build/nls.messages.js',
38
39
// Accessibility Signals
40
'out-build/vs/platform/accessibilitySignal/browser/media/*.mp3',
41
42
// Welcome
43
'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}',
44
45
// Extensions
46
'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}',
47
'out-build/vs/workbench/services/extensionManagement/common/media/*.{svg,png}',
48
49
// Webview
50
'out-build/vs/workbench/contrib/webview/browser/pre/*.{js,html}',
51
52
// Tree Sitter highlights
53
'out-build/vs/editor/common/languages/highlights/*.scm',
54
55
// Tree Sitter injections
56
'out-build/vs/editor/common/languages/injections/*.scm',
57
58
// Extension Host Worker
59
'out-build/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html'
60
];
61
exports.vscodeWebResourceIncludes = vscodeWebResourceIncludes;
62
63
const vscodeWebResources = [
64
65
// Includes
66
...vscodeWebResourceIncludes,
67
68
// Excludes
69
'!out-build/vs/**/{node,electron-browser,electron-main,electron-utility}/**',
70
'!out-build/vs/editor/standalone/**',
71
'!out-build/vs/workbench/**/*-tb.png',
72
'!out-build/vs/code/**/*-dev.html',
73
'!**/test/**'
74
];
75
76
const buildfile = require('./buildfile');
77
78
const vscodeWebEntryPoints = [
79
buildfile.workerEditor,
80
buildfile.workerExtensionHost,
81
buildfile.workerNotebook,
82
buildfile.workerLanguageDetection,
83
buildfile.workerLocalFileSearch,
84
buildfile.workerOutputLinks,
85
buildfile.workerBackgroundTokenization,
86
buildfile.keyboardMaps,
87
buildfile.workbenchWeb,
88
buildfile.entrypoint('vs/workbench/workbench.web.main.internal') // TODO@esm remove line when we stop supporting web-amd-esm-bridge
89
].flat();
90
91
/**
92
* @param extensionsRoot {string} The location where extension will be read from
93
* @param {object} product The parsed product.json file contents
94
*/
95
const createVSCodeWebFileContentMapper = (extensionsRoot, product) => {
96
/**
97
* @param {string} path
98
* @returns {((content: string) => string) | undefined}
99
*/
100
return path => {
101
if (path.endsWith('vs/platform/product/common/product.js')) {
102
return content => {
103
const productConfiguration = JSON.stringify({
104
...product,
105
version,
106
commit,
107
date: readISODate('out-build')
108
});
109
return content.replace('/*BUILD->INSERT_PRODUCT_CONFIGURATION*/', () => productConfiguration.substr(1, productConfiguration.length - 2) /* without { and }*/);
110
};
111
} else if (path.endsWith('vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js')) {
112
return content => {
113
const builtinExtensions = JSON.stringify(extensions.scanBuiltinExtensions(extensionsRoot));
114
return content.replace('/*BUILD->INSERT_BUILTIN_EXTENSIONS*/', () => builtinExtensions.substr(1, builtinExtensions.length - 2) /* without [ and ]*/);
115
};
116
}
117
118
return undefined;
119
};
120
};
121
exports.createVSCodeWebFileContentMapper = createVSCodeWebFileContentMapper;
122
123
const bundleVSCodeWebTask = task.define('bundle-vscode-web', task.series(
124
util.rimraf('out-vscode-web'),
125
optimize.bundleTask(
126
{
127
out: 'out-vscode-web',
128
esm: {
129
src: 'out-build',
130
entryPoints: vscodeWebEntryPoints,
131
resources: vscodeWebResources,
132
fileContentMapper: createVSCodeWebFileContentMapper('.build/web/extensions', product)
133
}
134
}
135
)
136
));
137
138
const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series(
139
bundleVSCodeWebTask,
140
util.rimraf('out-vscode-web-min'),
141
optimize.minifyTask('out-vscode-web', `https://main.vscode-cdn.net/sourcemaps/${commit}/core`)
142
));
143
gulp.task(minifyVSCodeWebTask);
144
145
/**
146
* @param {string} sourceFolderName
147
* @param {string} destinationFolderName
148
*/
149
function packageTask(sourceFolderName, destinationFolderName) {
150
const destination = path.join(BUILD_ROOT, destinationFolderName);
151
152
return () => {
153
const json = require('gulp-json-editor');
154
155
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
156
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }));
157
158
const extensions = gulp.src('.build/web/extensions/**', { base: '.build/web', dot: true });
159
160
const loader = gulp.src('build/loader.min', { base: 'build', dot: true }).pipe(rename('out/vs/loader.js')); // TODO@esm remove line when we stop supporting web-amd-esm-bridge
161
162
const sources = es.merge(src, extensions, loader)
163
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }))
164
// TODO@esm remove me once we stop supporting our web-esm-bridge
165
.pipe(es.through(function (file) {
166
if (file.relative === 'out/vs/workbench/workbench.web.main.internal.css') {
167
this.emit('data', new VinylFile({
168
contents: file.contents,
169
path: file.path.replace('workbench.web.main.internal.css', 'workbench.web.main.css'),
170
base: file.base
171
}));
172
}
173
this.emit('data', file);
174
}));
175
176
const name = product.nameShort;
177
const packageJsonStream = gulp.src(['remote/web/package.json'], { base: 'remote/web' })
178
.pipe(json({ name, version, type: 'module' }));
179
180
const license = gulp.src(['remote/LICENSE'], { base: 'remote', allowEmpty: true });
181
182
const productionDependencies = getProductionDependencies(WEB_FOLDER);
183
const dependenciesSrc = productionDependencies.map(d => path.relative(REPO_ROOT, d)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`, `!${d}/.bin/**`]).flat();
184
185
const deps = gulp.src(dependenciesSrc, { base: 'remote/web', dot: true })
186
.pipe(filter(['**', '!**/package-lock.json']))
187
.pipe(util.cleanNodeModules(path.join(__dirname, '.webignore')));
188
189
const favicon = gulp.src('resources/server/favicon.ico', { base: 'resources/server' });
190
const manifest = gulp.src('resources/server/manifest.json', { base: 'resources/server' });
191
const pwaicons = es.merge(
192
gulp.src('resources/server/code-192.png', { base: 'resources/server' }),
193
gulp.src('resources/server/code-512.png', { base: 'resources/server' })
194
);
195
196
const all = es.merge(
197
packageJsonStream,
198
license,
199
sources,
200
deps,
201
favicon,
202
manifest,
203
pwaicons
204
);
205
206
const result = all
207
.pipe(util.skipDirectories())
208
.pipe(util.fixWin32DirectoryPermissions());
209
210
return result.pipe(vfs.dest(destination));
211
};
212
}
213
214
const compileWebExtensionsBuildTask = task.define('compile-web-extensions-build', task.series(
215
task.define('clean-web-extensions-build', util.rimraf('.build/web/extensions')),
216
task.define('bundle-web-extensions-build', () => extensions.packageAllLocalExtensionsStream(true, false).pipe(gulp.dest('.build/web'))),
217
task.define('bundle-marketplace-web-extensions-build', () => extensions.packageMarketplaceExtensionsStream(true).pipe(gulp.dest('.build/web'))),
218
task.define('bundle-web-extension-media-build', () => extensions.buildExtensionMedia(false, '.build/web/extensions')),
219
));
220
gulp.task(compileWebExtensionsBuildTask);
221
222
const dashed = (/** @type {string} */ str) => (str ? `-${str}` : ``);
223
224
['', 'min'].forEach(minified => {
225
const sourceFolderName = `out-vscode-web${dashed(minified)}`;
226
const destinationFolderName = `vscode-web`;
227
228
const vscodeWebTaskCI = task.define(`vscode-web${dashed(minified)}-ci`, task.series(
229
compileWebExtensionsBuildTask,
230
minified ? minifyVSCodeWebTask : bundleVSCodeWebTask,
231
util.rimraf(path.join(BUILD_ROOT, destinationFolderName)),
232
packageTask(sourceFolderName, destinationFolderName)
233
));
234
gulp.task(vscodeWebTaskCI);
235
236
const vscodeWebTask = task.define(`vscode-web${dashed(minified)}`, task.series(
237
compileBuildWithManglingTask,
238
vscodeWebTaskCI
239
));
240
gulp.task(vscodeWebTask);
241
});
242
243