Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/gulpfile.editor.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
//@ts-check
7
8
const gulp = require('gulp');
9
const path = require('path');
10
const util = require('./lib/util');
11
const { getVersion } = require('./lib/getVersion');
12
const task = require('./lib/task');
13
const es = require('event-stream');
14
const File = require('vinyl');
15
const i18n = require('./lib/i18n');
16
const standalone = require('./lib/standalone');
17
const cp = require('child_process');
18
const compilation = require('./lib/compilation');
19
const monacoapi = require('./lib/monaco-api');
20
const fs = require('fs');
21
const filter = require('gulp-filter');
22
23
const root = path.dirname(__dirname);
24
const sha1 = getVersion(root);
25
const semver = require('./monaco/package.json').version;
26
const headerVersion = semver + '(' + sha1 + ')';
27
28
const BUNDLED_FILE_HEADER = [
29
'/*!-----------------------------------------------------------',
30
' * Copyright (c) Microsoft Corporation. All rights reserved.',
31
' * Version: ' + headerVersion,
32
' * Released under the MIT license',
33
' * https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
34
' *-----------------------------------------------------------*/',
35
''
36
].join('\n');
37
38
const extractEditorSrcTask = task.define('extract-editor-src', () => {
39
const apiusages = monacoapi.execute().usageContent;
40
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
41
standalone.extractEditor({
42
sourcesRoot: path.join(root, 'src'),
43
entryPoints: [
44
'vs/editor/editor.main',
45
'vs/editor/editor.worker.start',
46
'vs/editor/common/services/editorWebWorkerMain',
47
],
48
inlineEntryPoints: [
49
apiusages,
50
extrausages
51
],
52
typings: [],
53
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
54
importIgnorePattern: /\.css$/,
55
destRoot: path.join(root, 'out-editor-src'),
56
tsOutDir: '../out-monaco-editor-core/esm/vs',
57
redirects: {
58
'@vscode/tree-sitter-wasm': '../node_modules/@vscode/tree-sitter-wasm/wasm/web-tree-sitter',
59
}
60
});
61
});
62
63
const compileEditorESMTask = task.define('compile-editor-esm', () => {
64
65
const src = 'out-editor-src';
66
const out = 'out-monaco-editor-core/esm';
67
68
const compile = compilation.createCompile(src, { build: true, emitError: true, transpileOnly: false, preserveEnglish: true });
69
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
70
71
return (
72
srcPipe
73
.pipe(compile())
74
.pipe(i18n.processNlsFiles({
75
out,
76
fileHeader: BUNDLED_FILE_HEADER,
77
languages: i18n.defaultLanguages,
78
}))
79
.pipe(filter(['**', '!**/inlineEntryPoint*', '!**/tsconfig.json', '!**/loader.js']))
80
.pipe(gulp.dest(out))
81
);
82
});
83
84
/**
85
* @param {string} contents
86
*/
87
function toExternalDTS(contents) {
88
const lines = contents.split(/\r\n|\r|\n/);
89
let killNextCloseCurlyBrace = false;
90
for (let i = 0; i < lines.length; i++) {
91
const line = lines[i];
92
93
if (killNextCloseCurlyBrace) {
94
if ('}' === line) {
95
lines[i] = '';
96
killNextCloseCurlyBrace = false;
97
continue;
98
}
99
100
if (line.indexOf(' ') === 0) {
101
lines[i] = line.substr(4);
102
} else if (line.charAt(0) === '\t') {
103
lines[i] = line.substr(1);
104
}
105
106
continue;
107
}
108
109
if ('declare namespace monaco {' === line) {
110
lines[i] = '';
111
killNextCloseCurlyBrace = true;
112
continue;
113
}
114
115
if (line.indexOf('declare namespace monaco.') === 0) {
116
lines[i] = line.replace('declare namespace monaco.', 'export namespace ');
117
}
118
119
if (line.indexOf('declare var MonacoEnvironment') === 0) {
120
lines[i] = `declare global {\n var MonacoEnvironment: Environment | undefined;\n}`;
121
}
122
}
123
return lines.join('\n').replace(/\n\n\n+/g, '\n\n');
124
}
125
126
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
127
return es.merge(
128
// other assets
129
es.merge(
130
gulp.src('build/monaco/LICENSE'),
131
gulp.src('build/monaco/ThirdPartyNotices.txt'),
132
gulp.src('src/vs/monaco.d.ts')
133
).pipe(gulp.dest('out-monaco-editor-core')),
134
135
// place the .d.ts in the esm folder
136
gulp.src('src/vs/monaco.d.ts')
137
.pipe(es.through(function (data) {
138
this.emit('data', new File({
139
path: data.path.replace(/monaco\.d\.ts/, 'editor.api.d.ts'),
140
base: data.base,
141
contents: Buffer.from(toExternalDTS(data.contents.toString()))
142
}));
143
}))
144
.pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')),
145
146
// package.json
147
gulp.src('build/monaco/package.json')
148
.pipe(es.through(function (data) {
149
const json = JSON.parse(data.contents.toString());
150
json.private = false;
151
152
let markedVersion;
153
let dompurifyVersion;
154
try {
155
const markedManifestPath = path.join(root, 'src/vs/base/common/marked/cgmanifest.json');
156
const dompurifyManifestPath = path.join(root, 'src/vs/base/browser/dompurify/cgmanifest.json');
157
158
const markedManifest = JSON.parse(fs.readFileSync(markedManifestPath, 'utf8'));
159
const dompurifyManifest = JSON.parse(fs.readFileSync(dompurifyManifestPath, 'utf8'));
160
161
markedVersion = markedManifest.registrations[0].version;
162
dompurifyVersion = dompurifyManifest.registrations[0].version;
163
164
if (!markedVersion || !dompurifyVersion) {
165
throw new Error('Unable to read versions from cgmanifest.json files');
166
}
167
} catch (error) {
168
throw new Error(`Failed to read cgmanifest.json files for monaco-editor-core dependencies: ${error.message}`);
169
}
170
171
setUnsetField(json, 'dependencies', {
172
'marked': markedVersion,
173
'dompurify': dompurifyVersion
174
});
175
176
data.contents = Buffer.from(JSON.stringify(json, null, ' '));
177
this.emit('data', data);
178
}))
179
.pipe(gulp.dest('out-monaco-editor-core')),
180
181
// version.txt
182
gulp.src('build/monaco/version.txt')
183
.pipe(es.through(function (data) {
184
data.contents = Buffer.from(`monaco-editor-core: https://github.com/microsoft/vscode/tree/${sha1}`);
185
this.emit('data', data);
186
}))
187
.pipe(gulp.dest('out-monaco-editor-core')),
188
189
// README.md
190
gulp.src('build/monaco/README-npm.md')
191
.pipe(es.through(function (data) {
192
this.emit('data', new File({
193
path: data.path.replace(/README-npm\.md/, 'README.md'),
194
base: data.base,
195
contents: data.contents
196
}));
197
}))
198
.pipe(gulp.dest('out-monaco-editor-core')),
199
);
200
});
201
202
gulp.task('extract-editor-src',
203
task.series(
204
util.rimraf('out-editor-src'),
205
extractEditorSrcTask
206
)
207
);
208
209
gulp.task('editor-distro',
210
task.series(
211
task.parallel(
212
util.rimraf('out-editor-src'),
213
util.rimraf('out-monaco-editor-core'),
214
),
215
extractEditorSrcTask,
216
compileEditorESMTask,
217
finalEditorResourcesTask
218
)
219
);
220
221
gulp.task('monacodts', task.define('monacodts', () => {
222
const result = monacoapi.execute();
223
fs.writeFileSync(result.filePath, result.content);
224
fs.writeFileSync(path.join(root, 'src/vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
225
return Promise.resolve(true);
226
}));
227
228
//#region monaco type checking
229
230
/**
231
* @param {boolean} watch
232
*/
233
function createTscCompileTask(watch) {
234
return () => {
235
const createReporter = require('./lib/reporter').createReporter;
236
237
return new Promise((resolve, reject) => {
238
const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit'];
239
if (watch) {
240
args.push('-w');
241
}
242
const child = cp.spawn(`node`, args, {
243
cwd: path.join(__dirname, '..'),
244
// stdio: [null, 'pipe', 'inherit']
245
});
246
const errors = [];
247
const reporter = createReporter('monaco');
248
249
/** @type {NodeJS.ReadWriteStream | undefined} */
250
let report;
251
const magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings
252
253
child.stdout.on('data', data => {
254
let str = String(data);
255
str = str.replace(magic, '').trim();
256
if (str.indexOf('Starting compilation') >= 0 || str.indexOf('File change detected') >= 0) {
257
errors.length = 0;
258
report = reporter.end(false);
259
260
} else if (str.indexOf('Compilation complete') >= 0) {
261
// @ts-ignore
262
report.end();
263
264
} else if (str) {
265
const match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str);
266
if (match) {
267
// trying to massage the message so that it matches the gulp-tsb error messages
268
// e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'.
269
const fullpath = path.join(root, match[1]);
270
const message = match[3];
271
reporter(fullpath + message);
272
} else {
273
reporter(str);
274
}
275
}
276
});
277
child.on('exit', resolve);
278
child.on('error', reject);
279
});
280
};
281
}
282
283
const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true));
284
exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask;
285
286
const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false));
287
exports.monacoTypecheckTask = monacoTypecheckTask;
288
289
//#endregion
290
291
/**
292
* Sets a field on an object only if it's not already set, otherwise throws an error
293
* @param {any} obj - The object to modify
294
* @param {string} field - The field name to set
295
* @param {any} value - The value to set
296
*/
297
function setUnsetField(obj, field, value) {
298
if (obj[field] !== undefined) {
299
throw new Error(`Field "${field}" is already set (but was expected to not be).`);
300
}
301
obj[field] = value;
302
}
303
304