vscode/build/gulpfile.editor.js

482 lines
14 KiB
JavaScript
Raw Permalink Normal View History

2015-11-23 20:28:42 +01:00
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
2018-03-07 09:38:59 +01:00
const gulp = require('gulp');
const path = require('path');
const util = require('./lib/util');
2019-02-12 15:13:43 +01:00
const task = require('./lib/task');
2018-03-07 09:38:59 +01:00
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');
2018-07-19 21:05:38 +02:00
const compilation = require('./lib/compilation');
const monacoapi = require('./lib/monaco-api');
2018-07-20 11:25:46 +02:00
const fs = require('fs');
2015-11-23 20:28:42 +01:00
2020-01-02 20:35:07 +01:00
let root = path.dirname(__dirname);
let sha1 = util.getVersion(root);
let semver = require('./monaco/package.json').version;
let headerVersion = semver + '(' + sha1 + ')';
2015-11-23 20:28:42 +01:00
// Build
2020-01-02 20:35:07 +01:00
let editorEntryPoints = [
{
name: 'vs/editor/editor.main',
include: [],
2018-02-12 12:40:53 +01:00
exclude: ['vs/css', 'vs/nls'],
prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'],
},
{
name: 'vs/base/common/worker/simpleWorker',
2018-02-12 12:40:53 +01:00
include: ['vs/editor/common/services/editorSimpleWorker'],
prepend: ['vs/loader.js'],
append: ['vs/base/worker/workerMain'],
2016-09-18 22:05:42 +02:00
dest: 'vs/base/worker/workerMain.js'
}
2016-09-21 10:14:37 +02:00
];
2015-11-23 20:28:42 +01:00
2020-01-02 20:35:07 +01:00
let editorResources = [
'out-editor-build/vs/base/browser/ui/codicons/**/*.ttf'
2015-11-23 20:28:42 +01:00
];
2020-01-02 20:35:07 +01:00
let BUNDLED_FILE_HEADER = [
2015-11-23 20:28:42 +01:00
'/*!-----------------------------------------------------------',
2016-02-24 14:27:53 +01:00
' * Copyright (c) Microsoft Corporation. All rights reserved.',
2016-03-06 12:37:24 +01:00
' * Version: ' + headerVersion,
2015-11-23 20:28:42 +01:00
' * Released under the MIT license',
2021-02-14 20:10:24 +01:00
' * https://github.com/microsoft/vscode/blob/main/LICENSE.txt',
2015-11-23 20:28:42 +01:00
' *-----------------------------------------------------------*/',
''
].join('\n');
2018-03-07 09:38:59 +01:00
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
2019-02-12 20:43:28 +01:00
const extractEditorSrcTask = task.define('extract-editor-src', () => {
2018-07-20 11:25:46 +02:00
const apiusages = monacoapi.execute().usageContent;
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
standalone.extractEditor({
sourcesRoot: path.join(root, 'src'),
entryPoints: [
'vs/editor/editor.main',
'vs/editor/editor.worker',
'vs/base/worker/workerMain',
2018-07-20 11:25:46 +02:00
],
inlineEntryPoints: [
apiusages,
extrausages
],
2018-07-20 11:25:46 +02:00
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
2020-03-02 15:30:43 +01:00
importIgnorePattern: /(^vs\/css!)/,
2019-11-05 00:00:55 +01:00
destRoot: path.join(root, 'out-editor-src'),
redirects: []
});
2019-02-12 20:43:28 +01:00
});
2019-02-12 20:43:28 +01:00
const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true));
2018-07-19 21:05:38 +02:00
2019-02-12 20:43:28 +01:00
const optimizeEditorAMDTask = task.define('optimize-editor-amd', common.optimizeTask({
src: 'out-editor-build',
entryPoints: editorEntryPoints,
resources: editorResources,
loaderConfig: {
paths: {
'vs': 'out-editor-build/vs',
'vs/css': 'out-editor-build/vs/css.build',
'vs/nls': 'out-editor-build/vs/nls.build',
'vscode': 'empty:'
}
},
bundleLoader: false,
header: BUNDLED_FILE_HEADER,
bundleInfo: true,
out: 'out-editor',
languages: languages
2019-02-12 20:43:28 +01:00
}));
2019-02-12 20:43:28 +01:00
const minifyEditorAMDTask = task.define('minify-editor-amd', common.minifyTask('out-editor'));
2016-05-31 16:29:52 +02:00
2019-02-12 20:43:28 +01:00
const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => {
standalone.createESMSourcesAndResources2({
srcFolder: './out-editor-src',
outFolder: './out-editor-esm',
2018-03-07 09:38:59 +01:00
outResourcesFolder: './out-monaco-editor-core/esm',
ignores: [
'inlineEntryPoint:0.ts',
'inlineEntryPoint:1.ts',
2018-08-10 13:57:35 +02:00
'vs/loader.js',
'vs/nls.ts',
2018-08-10 13:57:35 +02:00
'vs/nls.build.js',
'vs/nls.d.ts',
2018-08-10 13:57:35 +02:00
'vs/css.js',
'vs/css.build.js',
'vs/css.d.ts',
'vs/base/worker/workerMain.ts',
],
renames: {
'vs/nls.mock.ts': 'vs/nls.ts'
2018-03-07 09:38:59 +01:00
}
});
2019-02-12 20:43:28 +01:00
});
2019-02-12 20:43:28 +01:00
const compileEditorESMTask = task.define('compile-editor-esm', () => {
const KEEP_PREV_ANALYSIS = false;
const FAIL_ON_PURPOSE = false;
console.log(`Launching the TS compiler at ${path.join(__dirname, '../out-editor-esm')}...`);
let result;
if (process.platform === 'win32') {
result = cp.spawnSync(`..\\node_modules\\.bin\\tsc.cmd`, {
cwd: path.join(__dirname, '../out-editor-esm')
});
} else {
result = cp.spawnSync(`node`, [`../node_modules/.bin/tsc`], {
cwd: path.join(__dirname, '../out-editor-esm')
});
}
console.log(result.stdout.toString());
console.log(result.stderr.toString());
if (FAIL_ON_PURPOSE || result.status !== 0) {
console.log(`The TS Compilation failed, preparing analysis folder...`);
const destPath = path.join(__dirname, '../../vscode-monaco-editor-esm-analysis');
const keepPrevAnalysis = (KEEP_PREV_ANALYSIS && fs.existsSync(destPath));
const cleanDestPath = (keepPrevAnalysis ? Promise.resolve() : util.rimraf(destPath)());
return cleanDestPath.then(() => {
// build a list of files to copy
const files = util.rreddir(path.join(__dirname, '../out-editor-esm'));
if (!keepPrevAnalysis) {
fs.mkdirSync(destPath);
// initialize a new repository
cp.spawnSync(`git`, [`init`], {
cwd: destPath
});
// 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 tree shaken src
for (const file of files) {
const srcFilePath = path.join(__dirname, '../out-editor-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);
}
}
2021-09-28 14:13:56 +02:00
console.log(`Open in VS Code the folder at '${destPath}' and you can analyze 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.');
});
}
2019-02-12 20:43:28 +01:00
});
2018-03-07 09:38:59 +01:00
function toExternalDTS(contents) {
let lines = contents.split(/\r\n|\r|\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 ');
}
if (line.indexOf('declare let MonacoEnvironment') === 0) {
lines[i] = `declare global {\n let MonacoEnvironment: Environment | undefined;\n}`;
}
if (line.indexOf('\tMonacoEnvironment?') === 0) {
lines[i] = ` MonacoEnvironment?: Environment | undefined;`;
}
}
return lines.join('\n').replace(/\n\n\n+/g, '\n\n');
}
function filterStream(testFunc) {
return es.through(function (data) {
if (!testFunc(data.relative)) {
return;
}
this.emit('data', data);
});
}
2019-02-12 20:43:28 +01:00
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
2016-05-31 16:29:52 +02:00
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')),
2018-04-25 11:46:17 +02:00
// 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,
contents: Buffer.from(toExternalDTS(data.contents.toString()))
2018-04-25 11:46:17 +02:00
}));
}))
.pipe(gulp.dest('out-monaco-editor-core/esm/vs/editor')),
// package.json
gulp.src('build/monaco/package.json')
2018-02-12 12:40:53 +01:00
.pipe(es.through(function (data) {
2020-01-02 20:35:07 +01:00
let json = JSON.parse(data.contents.toString());
json.private = false;
2018-02-26 13:09:47 +01:00
data.contents = Buffer.from(JSON.stringify(json, null, ' '));
this.emit('data', data);
}))
.pipe(gulp.dest('out-monaco-editor-core')),
2019-03-02 02:25:49 +01:00
// version.txt
gulp.src('build/monaco/version.txt')
.pipe(es.through(function (data) {
2020-09-16 01:13:49 +02:00
data.contents = Buffer.from(`monaco-editor-core: https://github.com/microsoft/vscode/tree/${sha1}`);
2019-03-02 02:25:49 +01:00
this.emit('data', data);
}))
.pipe(gulp.dest('out-monaco-editor-core')),
2016-06-09 11:20:03 +02:00
// README.md
gulp.src('build/monaco/README-npm.md')
2018-02-12 12:40:53 +01:00
.pipe(es.through(function (data) {
2016-06-09 11:20:03 +02:00
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')),
2016-05-31 16:29:52 +02:00
// 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/**/*')
2018-02-12 12:40:53 +01:00
).pipe(filterStream(function (path) {
2016-05-31 16:29:52 +02:00
// no map files
return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
2018-02-12 12:40:53 +01:00
})).pipe(es.through(function (data) {
2016-05-31 16:29:52 +02:00
// tweak the sourceMappingURL
if (!/\.js$/.test(data.path)) {
this.emit('data', data);
return;
}
2020-01-02 20:35:07 +01:00
let relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map'));
2016-05-31 16:29:52 +02:00
2020-01-02 20:35:07 +01:00
let strContents = data.contents.toString();
let newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
2019-02-05 23:39:23 +01:00
strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr);
2016-05-31 16:29:52 +02:00
2018-02-26 13:09:47 +01:00
data.contents = Buffer.from(strContents);
2016-05-31 16:29:52 +02:00
this.emit('data', data);
})).pipe(gulp.dest('out-monaco-editor-core/min')),
// min-maps folder
es.merge(
gulp.src('out-editor-min/**/*')
2018-02-12 12:40:53 +01:00
).pipe(filterStream(function (path) {
2016-05-31 16:29:52 +02:00
// no map files
2016-05-31 16:37:47 +02:00
return /\.js\.map$/.test(path);
2016-05-31 16:29:52 +02:00
})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
);
2019-02-12 20:43:28 +01:00
});
gulp.task('extract-editor-src',
task.series(
util.rimraf('out-editor-src'),
extractEditorSrcTask
)
);
gulp.task('editor-distro',
2019-02-12 15:13:43 +01:00
task.series(
task.parallel(
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,
2019-02-12 15:13:43 +01:00
task.parallel(
task.series(
compileEditorAMDTask,
optimizeEditorAMDTask,
minifyEditorAMDTask
),
2019-02-12 15:13:43 +01:00
task.series(
createESMSourcesAndResourcesTask,
compileEditorESMTask
)
),
finalEditorResourcesTask
)
);
const bundleEditorESMTask = task.define('editor-esm-bundle-webpack', () => {
2020-12-22 19:55:56 +01:00
const webpack = require('webpack');
const webpackGulp = require('webpack-stream');
const result = es.through();
const webpackConfigPath = path.join(root, 'build/monaco/monaco.webpack.config.js');
const webpackConfig = {
...require(webpackConfigPath),
...{ mode: 'production' }
};
const webpackDone = (err, stats) => {
if (err) {
result.emit('error', err);
return;
}
const { compilation } = stats;
if (compilation.errors.length > 0) {
result.emit('error', compilation.errors.join('\n'));
}
if (compilation.warnings.length > 0) {
result.emit('data', compilation.warnings.join('\n'));
}
};
return webpackGulp(webpackConfig, webpack, webpackDone)
.pipe(gulp.dest('out-editor-esm-bundle'));
});
gulp.task('editor-esm-bundle',
task.series(
task.parallel(
util.rimraf('out-editor-src'),
util.rimraf('out-editor-esm'),
util.rimraf('out-monaco-editor-core'),
2020-02-22 16:02:23 +01:00
util.rimraf('out-editor-esm-bundle'),
),
extractEditorSrcTask,
createESMSourcesAndResourcesTask,
compileEditorESMTask,
bundleEditorESMTask,
)
);
gulp.task('monacodts', task.define('monacodts', () => {
const result = monacoapi.execute();
fs.writeFileSync(result.filePath, result.content);
fs.writeFileSync(path.join(root, 'src/vs/editor/common/standalone/standaloneEnums.ts'), result.enums);
return Promise.resolve(true);
}));
//#region monaco type checking
function createTscCompileTask(watch) {
return () => {
const createReporter = require('./lib/reporter').createReporter;
return new Promise((resolve, reject) => {
const args = ['./node_modules/.bin/tsc', '-p', './src/tsconfig.monaco.json', '--noEmit'];
if (watch) {
args.push('-w');
}
const child = cp.spawn(`node`, args, {
cwd: path.join(__dirname, '..'),
// stdio: [null, 'pipe', 'inherit']
});
let errors = [];
let reporter = createReporter('monaco');
let report;
2019-02-05 23:39:23 +01:00
// eslint-disable-next-line no-control-regex
2018-04-05 11:33:28 +02:00
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
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];
reporter(fullpath + message);
} else {
reporter(str);
}
}
});
child.on('exit', resolve);
child.on('error', reject);
});
};
}
2019-02-12 20:43:28 +01:00
const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true));
2019-02-05 21:23:25 +01:00
exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask;
2019-02-12 20:43:28 +01:00
const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false));
2019-02-05 21:23:25 +01:00
exports.monacoTypecheckTask = monacoTypecheckTask;
//#endregion