build/lib/standalone.ts/copyFile
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
	const ts = require('typescript') as typeof import('typescript');

	const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
	let compilerOptions: { [key: string]: any };
	if (tsConfig.extends) {
		compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
		delete tsConfig.extends;
	} else {
		compilerOptions = tsConfig.compilerOptions;
	}
	tsConfig.compilerOptions = compilerOptions;

	compilerOptions.noEmit = false;
	compilerOptions.noUnusedLocals = false;
	compilerOptions.preserveConstEnums = false;
	compilerOptions.declaration = false;
	compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;


	options.compilerOptions = compilerOptions;

	console.log(`Running tree shaker with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);

	// Take the extra included .d.ts files from `tsconfig.monaco.json`
	options.typings = (<string[]>tsConfig.include).filter(includedFile => /\.d\.ts$/.test(includedFile));

	// Add extra .d.ts files from `node_modules/@types/`
	if (Array.isArray(options.compilerOptions?.types)) {
		options.compilerOptions.types.forEach((type: string) => {
			options.typings.push(`../node_modules/@types/${type}/index.d.ts`);
		});
	}

	const result = tss.shake(options);
	for (const fileName in result) {
		if (result.hasOwnProperty(fileName)) {
			writeFile(path.join(options.destRoot, fileName), result[fileName]);
		}
	}
	const copied: { [fileName: string]: boolean } = {};
	const copyFile = (fileName: string) => {
		if (copied[fileName]) {
			return;
		}
		copied[fileName] = true;
		const srcPath = path.join(options.sourcesRoot, fileName);
		const dstPath = path.join(options.destRoot, fileName);
		writeFile(dstPath, fs.readFileSync(srcPath));
	};
	const writeOutputFile = (fileName: string, contents: string | Buffer) => {
		writeFile(path.join(options.destRoot, fileName), contents);
	};
	for (const fileName in result) {
		if (result.hasOwnProperty(fileName)) {
			const fileContents = result[fileName];
			const info = ts.preProcessFile(fileContents);

			for (let i = info.importedFiles.length - 1; i >= 0; i--) {
				const importedFileName = info.importedFiles[i].fileName;

				let importedFilePath: string;
				if (/^vs\/css!/.test(importedFileName)) {
					importedFilePath = importedFileName.substr('vs/css!'.length) + '.css';
				} else {
					importedFilePath = importedFileName;
				}
				if (/(^\.\/)|(^\.\.\/)/.test(importedFilePath)) {
					importedFilePath = path.join(path.dirname(fileName), importedFilePath);
				}

				if (/\.css$/.test(importedFilePath)) {
					transportCSS(importedFilePath, copyFile, writeOutputFile);
				} else {
					if (fs.existsSync(path.join(options.sourcesRoot, importedFilePath + '.js'))) {
						copyFile(importedFilePath + '.js');
					}
				}
			}
		}
	}

	delete tsConfig.compilerOptions.moduleResolution;
	writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));

	[
		'vs/css.build.ts',
		'vs/css.ts',
		'vs/loader.js',
		'vs/loader.d.ts',
		'vs/nls.build.ts',
		'vs/nls.ts',
		'vs/nls.mock.ts',
	].forEach(copyFile);
}