Skip to content

Commit 5399233

Browse files
authored
Merge pull request microsoft#56261 from Microsoft/joh/extpack
Use webpack for emmet and git extension
2 parents 22edd3e + c98ed76 commit 5399233

15 files changed

Lines changed: 2252 additions & 94 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ npm-debug.log
33
Thumbs.db
44
node_modules/
55
.build/
6+
extensions/**/dist/
67
out/
78
out-build/
89
out-editor/
@@ -17,4 +18,4 @@ build/node_modules
1718
coverage/
1819
test_data/
1920
test-results/
20-
yarn-error.log
21+
yarn-error.log

build/gulpfile.extensions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const tasks = compilations.map(function (tsconfigFile) {
8989
.pipe(tsFilter)
9090
.pipe(util.loadSourcemaps())
9191
.pipe(compilation())
92-
.pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through())
92+
.pipe(build ? nlsDev.rewriteLocalizeCalls({ keepFilenames: true }) : es.through())
9393
.pipe(build ? util.stripSourceMappingURL() : es.through())
9494
.pipe(sourcemaps.write('.', {
9595
sourceMappingURL: !build ? null : f => `${baseUrl}/${f.relative}.map`,
@@ -167,4 +167,4 @@ gulp.task('watch-extensions', tasks.map(t => t.watch));
167167

168168
gulp.task('clean-extensions-build', tasks.map(t => t.cleanBuild));
169169
gulp.task('compile-extensions-build', tasks.map(t => t.compileBuild));
170-
gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild));
170+
gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild));

build/gulpfile.vscode.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ gulp.task('optimize-index-js', ['optimize-vscode'], () => {
113113
fs.writeFileSync(fullpath, newContents);
114114
});
115115

116-
const baseUrl = `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`;
116+
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
117117
gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min'));
118-
gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], common.minifyTask('out-vscode', baseUrl));
118+
gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`));
119119

120120
// Package
121121

@@ -240,7 +240,7 @@ function packageTask(platform, arch, opts) {
240240
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
241241

242242
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
243-
return ext.fromLocal(extension.path)
243+
return ext.fromLocal(extension.path, sourceMappingURLBase)
244244
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
245245
}));
246246

@@ -451,16 +451,22 @@ gulp.task('vscode-translations-import', function () {
451451

452452
// Sourcemaps
453453

454-
gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
454+
gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min', 'minify-vscode'], () => {
455455
const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' })
456456
.pipe(es.mapSync(f => {
457457
f.path = `${f.base}/core/${f.relative}`;
458458
return f;
459459
}));
460460

461-
const extensions = gulp.src('extensions/**/out/**/*.map', { base: '.' });
461+
const extensionsOut = gulp.src('extensions/**/out/**/*.map', { base: '.' });
462+
const extensionsDist = gulp.src('extensions/**/dist/**/*.map', { base: '.' });
462463

463-
return es.merge(vs, extensions)
464+
return es.merge(vs, extensionsOut, extensionsDist)
465+
.pipe(es.through(function (data) {
466+
// debug
467+
console.log('Uploading Sourcemap', data.relative);
468+
this.emit('data', data);
469+
}))
464470
.pipe(azure.upload({
465471
account: process.env.AZURE_STORAGE_ACCOUNT,
466472
key: process.env.AZURE_STORAGE_ACCESS_KEY,
@@ -505,7 +511,7 @@ function getSettingsSearchBuildId(packageJson) {
505511
const branch = process.env.BUILD_SOURCEBRANCH;
506512
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
507513
/\/master$/.test(branch) ? 1 :
508-
2; // Some unexpected branch
514+
2; // Some unexpected branch
509515

510516
const out = cp.execSync(`git rev-list HEAD --count`);
511517
const count = parseInt(out.toString());

build/lib/extensions.js

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
* Copyright (c) Microsoft Corporation. All rights reserved.
44
* Licensed under the MIT License. See License.txt in the project root for license information.
55
*--------------------------------------------------------------------------------------------*/
6+
var __assign = (this && this.__assign) || Object.assign || function(t) {
7+
for (var s, i = 1, n = arguments.length; i < n; i++) {
8+
s = arguments[i];
9+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
10+
t[p] = s[p];
11+
}
12+
return t;
13+
};
614
Object.defineProperty(exports, "__esModule", { value: true });
715
var es = require("event-stream");
816
var assign = require("object-assign");
@@ -14,14 +22,15 @@ var rename = require('gulp-rename');
1422
var util = require('gulp-util');
1523
var buffer = require('gulp-buffer');
1624
var json = require('gulp-json-editor');
25+
var webpack = require('webpack');
26+
var webpackGulp = require('webpack-stream');
1727
var fs = require("fs");
1828
var path = require("path");
1929
var vsce = require("vsce");
2030
var File = require("vinyl");
21-
function fromLocal(extensionPath) {
31+
function fromLocal(extensionPath, sourceMappingURLBase) {
2232
var result = es.through();
23-
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
24-
.then(function (fileNames) {
33+
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(function (fileNames) {
2534
var files = fileNames
2635
.map(function (fileName) { return path.join(extensionPath, fileName); })
2736
.map(function (filePath) { return new File({
@@ -30,9 +39,58 @@ function fromLocal(extensionPath) {
3039
base: extensionPath,
3140
contents: fs.createReadStream(filePath)
3241
}); });
33-
es.readArray(files).pipe(result);
34-
})
35-
.catch(function (err) { return result.emit('error', err); });
42+
var filesStream = es.readArray(files);
43+
// check for a webpack configuration file, then invoke webpack
44+
// and merge its output with the files stream. also rewrite the package.json
45+
// file to a new entry point
46+
if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) {
47+
var packageJsonFilter = filter('package.json', { restore: true });
48+
var patchFilesStream = filesStream
49+
.pipe(packageJsonFilter)
50+
.pipe(buffer())
51+
.pipe(json(function (data) {
52+
// hardcoded entry point directory!
53+
data.main = data.main.replace('/out/', /dist/);
54+
return data;
55+
}))
56+
.pipe(packageJsonFilter.restore);
57+
var webpackConfig = __assign({}, require(path.join(extensionPath, 'extension.webpack.config.js')), { mode: 'production', stats: 'errors-only' });
58+
var webpackStream = webpackGulp(webpackConfig, webpack)
59+
.pipe(es.through(function (data) {
60+
data.stat = data.stat || {};
61+
data.base = extensionPath;
62+
this.emit('data', data);
63+
}))
64+
.pipe(es.through(function (data) {
65+
// source map handling:
66+
// * rewrite sourceMappingURL
67+
// * save to disk so that upload-task picks this up
68+
if (sourceMappingURLBase) {
69+
var contents = data.contents.toString('utf8');
70+
data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) {
71+
return "\n//# sourceMappingURL=" + sourceMappingURLBase + "/extensions/" + path.basename(extensionPath) + "/dist/" + g1;
72+
}), 'utf8');
73+
if (/\.js\.map$/.test(data.path)) {
74+
if (!fs.existsSync(path.dirname(data.path))) {
75+
fs.mkdirSync(path.dirname(data.path));
76+
}
77+
fs.writeFileSync(data.path, data.contents);
78+
}
79+
}
80+
this.emit('data', data);
81+
}));
82+
es.merge(webpackStream, patchFilesStream)
83+
// .pipe(es.through(function (data) {
84+
// // debug
85+
// console.log('out', data.path, data.contents.length);
86+
// this.emit('data', data);
87+
// }))
88+
.pipe(result);
89+
}
90+
else {
91+
filesStream.pipe(result);
92+
}
93+
}).catch(function (err) { return result.emit('error', err); });
3694
return result;
3795
}
3896
exports.fromLocal = fromLocal;

build/lib/extensions.ts

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,88 @@ const rename = require('gulp-rename');
1414
const util = require('gulp-util');
1515
const buffer = require('gulp-buffer');
1616
const json = require('gulp-json-editor');
17+
const webpack = require('webpack');
18+
const webpackGulp = require('webpack-stream');
1719
import * as fs from 'fs';
1820
import * as path from 'path';
1921
import * as vsce from 'vsce';
2022
import * as File from 'vinyl';
2123

22-
export function fromLocal(extensionPath: string): Stream {
23-
const result = es.through();
24-
25-
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
26-
.then(fileNames => {
27-
const files = fileNames
28-
.map(fileName => path.join(extensionPath, fileName))
29-
.map(filePath => new File({
30-
path: filePath,
31-
stat: fs.statSync(filePath),
32-
base: extensionPath,
33-
contents: fs.createReadStream(filePath) as any
34-
}));
24+
export function fromLocal(extensionPath: string, sourceMappingURLBase?: string): Stream {
25+
let result = es.through();
26+
27+
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }).then(fileNames => {
28+
const files = fileNames
29+
.map(fileName => path.join(extensionPath, fileName))
30+
.map(filePath => new File({
31+
path: filePath,
32+
stat: fs.statSync(filePath),
33+
base: extensionPath,
34+
contents: fs.createReadStream(filePath) as any
35+
}));
36+
37+
const filesStream = es.readArray(files);
38+
39+
// check for a webpack configuration file, then invoke webpack
40+
// and merge its output with the files stream. also rewrite the package.json
41+
// file to a new entry point
42+
if (fs.existsSync(path.join(extensionPath, 'extension.webpack.config.js'))) {
43+
const packageJsonFilter = filter('package.json', { restore: true });
44+
45+
const patchFilesStream = filesStream
46+
.pipe(packageJsonFilter)
47+
.pipe(buffer())
48+
.pipe(json(data => {
49+
// hardcoded entry point directory!
50+
data.main = data.main.replace('/out/', /dist/);
51+
return data;
52+
}))
53+
.pipe(packageJsonFilter.restore);
54+
55+
const webpackConfig = {
56+
...require(path.join(extensionPath, 'extension.webpack.config.js')),
57+
...{ mode: 'production', stats: 'errors-only' }
58+
};
59+
const webpackStream = webpackGulp(webpackConfig, webpack)
60+
.pipe(es.through(function (data) {
61+
data.stat = data.stat || {};
62+
data.base = extensionPath;
63+
this.emit('data', data);
64+
}))
65+
.pipe(es.through(function (data: File) {
66+
// source map handling:
67+
// * rewrite sourceMappingURL
68+
// * save to disk so that upload-task picks this up
69+
if (sourceMappingURLBase) {
70+
const contents = (<Buffer>data.contents).toString('utf8');
71+
data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) {
72+
return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/dist/${g1}`;
73+
}), 'utf8');
74+
75+
if (/\.js\.map$/.test(data.path)) {
76+
if (!fs.existsSync(path.dirname(data.path))) {
77+
fs.mkdirSync(path.dirname(data.path));
78+
}
79+
fs.writeFileSync(data.path, data.contents);
80+
}
81+
}
82+
this.emit('data', data);
83+
}))
84+
;
85+
86+
es.merge(webpackStream, patchFilesStream)
87+
// .pipe(es.through(function (data) {
88+
// // debug
89+
// console.log('out', data.path, data.contents.length);
90+
// this.emit('data', data);
91+
// }))
92+
.pipe(result);
93+
94+
} else {
95+
filesStream.pipe(result);
96+
}
3597

36-
es.readArray(files).pipe(result);
37-
})
38-
.catch(err => result.emit('error', err));
98+
}).catch(err => result.emit('error', err));
3999

40100
return result;
41101
}

extensions/emmet/.vscodeignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
test/**
22
src/**
3-
tsconfig.json
3+
out/**
4+
tsconfig.json
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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 sharedConfig = require('../shared.webpack.config');
9+
10+
const myConfig = {
11+
entry: {
12+
extension: './src/extension.ts',
13+
},
14+
externals: {
15+
'vscode': 'commonjs vscode', // ignored because it doesn't exist
16+
'@emmetio/css-parser': 'commonjs @emmetio/css-parser',
17+
'@emmetio/html-matcher': 'commonjs @emmetio/html-matcher',
18+
'@emmetio/math-expression': 'commonjs @emmetio/math-expression',
19+
'image-size': 'commonjs image-size',
20+
'vscode-emmet-helper': 'commonjs vscode-emmet-helper',
21+
},
22+
};
23+
24+
module.exports = { ...sharedConfig(__dirname), ...myConfig };

extensions/emmet/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
"include": [
1717
"src/**/*"
1818
]
19-
}
19+
}

extensions/git/.vscodeignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
src/**
22
test/**
3-
out/test/**
3+
out/**
44
tsconfig.json
5-
build/**
5+
build/**
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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 sharedConfig = require('../shared.webpack.config');
9+
const CopyWebpackPlugin = require('copy-webpack-plugin');
10+
11+
const myConfig = {
12+
node: {
13+
__dirname: false // leave the __dirname-behaviour intact
14+
},
15+
entry: {
16+
main: './out/main.js',
17+
['askpass-main']: './out/askpass-main.js'
18+
},
19+
plugins: [
20+
new CopyWebpackPlugin([
21+
{ from: './out/*.sh', to: '[name].sh' },
22+
{ from: './out/nls.*.json', to: '[name].json' }
23+
])
24+
],
25+
externals: {
26+
'vscode': 'commonjs vscode', // ignored because it doesn't exist
27+
"byline": 'commonjs byline',
28+
"file-type": 'commonjs file-type',
29+
"iconv-lite": 'commonjs iconv-lite',
30+
"jschardet": 'commonjs jschardet',
31+
"vscode-extension-telemetry": 'commonjs vscode-extension-telemetry',
32+
"vscode-nls": 'commonjs vscode-nls',
33+
"which": 'commonjs which',
34+
},
35+
};
36+
37+
module.exports = { ...sharedConfig(__dirname, false), ...myConfig };

0 commit comments

Comments
 (0)