gulpfile.editor.js 12.4 KB
Newer Older
I
isidor 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

A
Alex Dima 已提交
6 7 8
const gulp = require('gulp');
const path = require('path');
const util = require('./lib/util');
A
Alex Dima 已提交
9
const task = require('./lib/task');
A
Alex Dima 已提交
10 11 12 13 14 15
const common = require('./lib/optimize');
const es = require('event-stream');
const File = require('vinyl');
const i18n = require('./lib/i18n');
const standalone = require('./lib/standalone');
const cp = require('child_process');
A
Alex Dima 已提交
16
const compilation = require('./lib/compilation');
A
Alex Dima 已提交
17 18
const monacoapi = require('./monaco/api');
const fs = require('fs');
I
isidor 已提交
19 20

var root = path.dirname(__dirname);
A
Alex Dima 已提交
21 22 23
var sha1 = util.getVersion(root);
var semver = require('./monaco/package.json').version;
var headerVersion = semver + '(' + sha1 + ')';
I
isidor 已提交
24 25 26

// Build

27 28 29 30
var editorEntryPoints = [
	{
		name: 'vs/editor/editor.main',
		include: [],
J
Joao Moreno 已提交
31
		exclude: ['vs/css', 'vs/nls'],
A
Alex Dima 已提交
32
		prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'],
33 34 35
	},
	{
		name: 'vs/base/common/worker/simpleWorker',
J
Joao Moreno 已提交
36 37 38
		include: ['vs/editor/common/services/editorSimpleWorker'],
		prepend: ['vs/loader.js'],
		append: ['vs/base/worker/workerMain'],
A
Alex Dima 已提交
39
		dest: 'vs/base/worker/workerMain.js'
40
	}
A
Alex Dima 已提交
41
];
I
isidor 已提交
42 43

var editorResources = [
44
	'out-editor-build/vs/base/browser/ui/codiconLabel/**/*.ttf'
I
isidor 已提交
45 46 47 48
];

var BUNDLED_FILE_HEADER = [
	'/*!-----------------------------------------------------------',
A
Alex Dima 已提交
49
	' * Copyright (c) Microsoft Corporation. All rights reserved.',
A
Alex Dima 已提交
50
	' * Version: ' + headerVersion,
I
isidor 已提交
51 52 53 54 55 56
	' * Released under the MIT license',
	' * https://github.com/Microsoft/vscode/blob/master/LICENSE.txt',
	' *-----------------------------------------------------------*/',
	''
].join('\n');

A
Alex Dima 已提交
57 58
const languages = i18n.defaultLanguages.concat([]);  // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);

59
const extractEditorSrcTask = task.define('extract-editor-src', () => {
A
Alex Dima 已提交
60 61
	const apiusages = monacoapi.execute().usageContent;
	const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
62 63 64 65 66
	standalone.extractEditor({
		sourcesRoot: path.join(root, 'src'),
		entryPoints: [
			'vs/editor/editor.main',
			'vs/editor/editor.worker',
67
			'vs/base/worker/workerMain',
A
Alex Dima 已提交
68 69 70 71
		],
		inlineEntryPoints: [
			apiusages,
			extrausages
72 73
		],
		libs: [
A
Alex Dima 已提交
74 75 76
			`lib.es5.d.ts`,
			`lib.dom.d.ts`,
			`lib.webworker.importscripts.d.ts`
77
		],
A
Alex Dima 已提交
78
		shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
A
Alex Dima 已提交
79
		importIgnorePattern: /(^vs\/css!)|(promise-polyfill\/polyfill)/,
P
Peng Lyu 已提交
80 81
		destRoot: path.join(root, 'out-editor-src'),
		redirects: []
82
	});
83
});
84

85
const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true));
A
Alex Dima 已提交
86

87
const optimizeEditorAMDTask = task.define('optimize-editor-amd', common.optimizeTask({
88 89 90 91 92 93
	src: 'out-editor-build',
	entryPoints: editorEntryPoints,
	resources: editorResources,
	loaderConfig: {
		paths: {
			'vs': 'out-editor-build/vs',
A
Alex Dima 已提交
94 95
			'vs/css': 'out-editor-build/vs/css.build',
			'vs/nls': 'out-editor-build/vs/nls.build',
96 97 98 99 100 101 102 103
			'vscode': 'empty:'
		}
	},
	bundleLoader: false,
	header: BUNDLED_FILE_HEADER,
	bundleInfo: true,
	out: 'out-editor',
	languages: languages
104
}));
105

106
const minifyEditorAMDTask = task.define('minify-editor-amd', common.minifyTask('out-editor'));
A
Alex Dima 已提交
107

108
const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => {
109 110
	standalone.createESMSourcesAndResources2({
		srcFolder: './out-editor-src',
A
Alex Dima 已提交
111
		outFolder: './out-editor-esm',
A
Alex Dima 已提交
112
		outResourcesFolder: './out-monaco-editor-core/esm',
113 114 115
		ignores: [
			'inlineEntryPoint:0.ts',
			'inlineEntryPoint:1.ts',
116
			'vs/loader.js',
117
			'vs/nls.ts',
118
			'vs/nls.build.js',
119
			'vs/nls.d.ts',
120 121
			'vs/css.js',
			'vs/css.build.js',
122 123 124 125 126
			'vs/css.d.ts',
			'vs/base/worker/workerMain.ts',
		],
		renames: {
			'vs/nls.mock.ts': 'vs/nls.ts'
A
Alex Dima 已提交
127 128
		}
	});
129
});
130

131
const compileEditorESMTask = task.define('compile-editor-esm', () => {
132 133
	console.log(`Launching the TS compiler at ${path.join(__dirname, '../out-editor-esm')}...`);
	let result;
134
	if (process.platform === 'win32') {
135
		result = cp.spawnSync(`..\\node_modules\\.bin\\tsc.cmd`, {
136 137 138
			cwd: path.join(__dirname, '../out-editor-esm')
		});
	} else {
139
		result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], {
140 141
			cwd: path.join(__dirname, '../out-editor-esm')
		});
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
	}

	console.log(result.stdout.toString());
	console.log(result.stderr.toString());

	if (result.status !== 0) {
		console.log(`The TS Compilation failed, preparing analysis folder...`);
		const destPath = path.join(__dirname, '../../vscode-monaco-editor-esm-analysis');
		return util.rimraf(destPath)().then(() => {
			fs.mkdirSync(destPath);

			// initialize a new repository
			cp.spawnSync(`git`, [`init`], {
				cwd: destPath
			});

			// build a list of files to copy
			const files = util.rreddir(path.join(__dirname, '../out-editor-esm'));

			// copy files from src
			for (const file of files) {
				const srcFilePath = path.join(__dirname, '../src', file);
				const dstFilePath = path.join(destPath, file);
				if (fs.existsSync(srcFilePath)) {
					util.ensureDir(path.dirname(dstFilePath));
					const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
					fs.writeFileSync(dstFilePath, contents);
				}
			}

			// create an initial commit to diff against
			cp.spawnSync(`git`, [`add`, `.`], {
				cwd: destPath
			});

			// create the commit
			cp.spawnSync(`git`, [`commit`, `-m`, `"original sources"`, `--no-gpg-sign`], {
				cwd: destPath
			});

			// copy files from esm
			for (const file of files) {
				const srcFilePath = path.join(__dirname, '../out-editor-esm', file);
				const dstFilePath = path.join(destPath, file);
				if (fs.existsSync(srcFilePath)) {
					util.ensureDir(path.dirname(dstFilePath));
					const contents = fs.readFileSync(srcFilePath).toString().replace(/\r\n|\r|\n/g, '\n');
					fs.writeFileSync(dstFilePath, contents);
				}
			}

			console.log(`Open in VS Code the folder at '${destPath}' and you can alayze the compilation error`);
			throw new Error('Standalone Editor compilation failed. If this is the build machine, simply launch `yarn run gulp editor-distro` on your machine to further analyze the compilation problem.');
		});
196
	}
197
});
A
Alex Dima 已提交
198

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
function toExternalDTS(contents) {
	let lines = contents.split('\n');
	let killNextCloseCurlyBrace = false;
	for (let i = 0; i < lines.length; i++) {
		let line = lines[i];

		if (killNextCloseCurlyBrace) {
			if ('}' === line) {
				lines[i] = '';
				killNextCloseCurlyBrace = false;
				continue;
			}

			if (line.indexOf('    ') === 0) {
				lines[i] = line.substr(4);
			} else if (line.charAt(0) === '\t') {
				lines[i] = line.substr(1);
			}

			continue;
		}

		if ('declare namespace monaco {' === line) {
			lines[i] = '';
			killNextCloseCurlyBrace = true;
			continue;
		}

		if (line.indexOf('declare namespace monaco.') === 0) {
			lines[i] = line.replace('declare namespace monaco.', 'export namespace ');
		}
	}
	return lines.join('\n');
}

234 235 236 237 238 239 240 241 242
function filterStream(testFunc) {
	return es.through(function (data) {
		if (!testFunc(data.relative)) {
			return;
		}
		this.emit('data', data);
	});
}

243
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
A
Alex Dima 已提交
244 245 246 247 248 249 250 251
	return es.merge(
		// other assets
		es.merge(
			gulp.src('build/monaco/LICENSE'),
			gulp.src('build/monaco/ThirdPartyNotices.txt'),
			gulp.src('src/vs/monaco.d.ts')
		).pipe(gulp.dest('out-monaco-editor-core')),

A
Alex Dima 已提交
252 253 254 255 256 257
		// place the .d.ts in the esm folder
		gulp.src('src/vs/monaco.d.ts')
			.pipe(es.through(function (data) {
				this.emit('data', new File({
					path: data.path.replace(/monaco\.d\.ts/, 'editor.api.d.ts'),
					base: data.base,
258
					contents: Buffer.from(toExternalDTS(data.contents.toString()))
A
Alex Dima 已提交
259 260 261 262
				}));
			}))
			.pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')),

263 264
		// package.json
		gulp.src('build/monaco/package.json')
J
Joao Moreno 已提交
265
			.pipe(es.through(function (data) {
266 267
				var json = JSON.parse(data.contents.toString());
				json.private = false;
268
				data.contents = Buffer.from(JSON.stringify(json, null, '  '));
269 270 271 272
				this.emit('data', data);
			}))
			.pipe(gulp.dest('out-monaco-editor-core')),

A
Alex Dima 已提交
273 274 275 276 277 278 279 280
		// version.txt
		gulp.src('build/monaco/version.txt')
			.pipe(es.through(function (data) {
				data.contents = Buffer.from(`monaco-editor-core: https://github.com/Microsoft/vscode/tree/${sha1}`);
				this.emit('data', data);
			}))
			.pipe(gulp.dest('out-monaco-editor-core')),

281 282
		// README.md
		gulp.src('build/monaco/README-npm.md')
J
Joao Moreno 已提交
283
			.pipe(es.through(function (data) {
284 285 286 287 288 289 290 291
				this.emit('data', new File({
					path: data.path.replace(/README-npm\.md/, 'README.md'),
					base: data.base,
					contents: data.contents
				}));
			}))
			.pipe(gulp.dest('out-monaco-editor-core')),

A
Alex Dima 已提交
292 293 294 295 296 297 298 299
		// dev folder
		es.merge(
			gulp.src('out-editor/**/*')
		).pipe(gulp.dest('out-monaco-editor-core/dev')),

		// min folder
		es.merge(
			gulp.src('out-editor-min/**/*')
J
Joao Moreno 已提交
300
		).pipe(filterStream(function (path) {
A
Alex Dima 已提交
301
			// no map files
302
			return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
J
Joao Moreno 已提交
303
		})).pipe(es.through(function (data) {
A
Alex Dima 已提交
304 305 306 307 308 309 310 311 312 313
			// tweak the sourceMappingURL
			if (!/\.js$/.test(data.path)) {
				this.emit('data', data);
				return;
			}

			var relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map'));

			var strContents = data.contents.toString();
			var newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
A
Alex Dima 已提交
314
			strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr);
A
Alex Dima 已提交
315

316
			data.contents = Buffer.from(strContents);
A
Alex Dima 已提交
317 318 319 320 321 322
			this.emit('data', data);
		})).pipe(gulp.dest('out-monaco-editor-core/min')),

		// min-maps folder
		es.merge(
			gulp.src('out-editor-min/**/*')
J
Joao Moreno 已提交
323
		).pipe(filterStream(function (path) {
A
Alex Dima 已提交
324
			// no map files
A
Alex Dima 已提交
325
			return /\.js\.map$/.test(path);
A
Alex Dima 已提交
326 327
		})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
	);
328
});
329 330

gulp.task('editor-distro',
A
Alex Dima 已提交
331 332
	task.series(
		task.parallel(
333 334 335 336 337 338 339 340
			util.rimraf('out-editor-src'),
			util.rimraf('out-editor-build'),
			util.rimraf('out-editor-esm'),
			util.rimraf('out-monaco-editor-core'),
			util.rimraf('out-editor'),
			util.rimraf('out-editor-min')
		),
		extractEditorSrcTask,
A
Alex Dima 已提交
341 342
		task.parallel(
			task.series(
343 344 345 346
				compileEditorAMDTask,
				optimizeEditorAMDTask,
				minifyEditorAMDTask
			),
A
Alex Dima 已提交
347
			task.series(
348 349 350 351 352 353 354
				createESMSourcesAndResourcesTask,
				compileEditorESMTask
			)
		),
		finalEditorResourcesTask
	)
);
355 356 357 358 359 360 361 362

//#region monaco type checking

function createTscCompileTask(watch) {
	return () => {
		const createReporter = require('./lib/reporter').createReporter;

		return new Promise((resolve, reject) => {
J
Johannes Rieken 已提交
363
			const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit'];
364 365 366
			if (watch) {
				args.push('-w');
			}
J
Johannes Rieken 已提交
367
			const child = cp.spawn(`node`, args, {
368
				cwd: path.join(__dirname, '..'),
J
Johannes Rieken 已提交
369
				// stdio: [null, 'pipe', 'inherit']
370 371 372 373
			});
			let errors = [];
			let reporter = createReporter();
			let report;
A
Alex Dima 已提交
374
			// eslint-disable-next-line no-control-regex
J
Johannes Rieken 已提交
375
			let 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
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393

			child.stdout.on('data', data => {
				let str = String(data);
				str = str.replace(magic, '').trim();
				if (str.indexOf('Starting compilation') >= 0 || str.indexOf('File change detected') >= 0) {
					errors.length = 0;
					report = reporter.end(false);

				} else if (str.indexOf('Compilation complete') >= 0) {
					report.end();

				} else if (str) {
					let match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str);
					if (match) {
						// trying to massage the message so that it matches the gulp-tsb error messages
						// e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'.
						let fullpath = path.join(root, match[1]);
						let message = match[3];
J
Johannes Rieken 已提交
394
						// @ts-ignore
395 396
						reporter(fullpath + message);
					} else {
J
Johannes Rieken 已提交
397
						// @ts-ignore
398 399 400 401 402 403 404 405 406 407
						reporter(str);
					}
				}
			});
			child.on('exit', resolve);
			child.on('error', reject);
		});
	};
}

408
const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true));
A
Alex Dima 已提交
409 410
exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask;

411
const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false));
A
Alex Dima 已提交
412
exports.monacoTypecheckTask = monacoTypecheckTask;
413 414

//#endregion