Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack #996

Merged
merged 7 commits into from
Jan 17, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,11 @@ test-results.xml

# Artifacts from ANTLR4 extension
grammar/.antlr

node_modules
out
*.vsix
.vscode-test
test-results.xml
dist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: all but these last two are already in the gitignore

stats.json
19 changes: 11 additions & 8 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
],
"stopOnEntry": false,
"sourceMaps": true,
// outFiles is used for locating generated JavaScript files, see https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_source-maps
"outFiles": [
"${workspaceRoot}/out/src/**/*.js"
"${workspaceFolder}/**/*.js"
],
"preLaunchTask": "npm: compile",
"preLaunchTask": "npm: webpack",
"env": {
"DEBUGTELEMETRY": "1"
"DEBUGTELEMETRY": "1",
"NODE_DEBUG": ""
}
},
{
Expand All @@ -27,14 +29,15 @@
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceRoot}",
"--extensionTestsPath=${workspaceRoot}/out/test"
"--extensionTestsPath=${workspaceRoot}/dist/test"
],
"stopOnEntry": false,
"sourceMaps": true,
// outFiles is used for locating generated JavaScript files, see https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_source-maps
"outFiles": [
"${workspaceRoot}/out/test"
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "npm: compile",
"preLaunchTask": "npm: webpack",
"env": {
"MOCHA_grep": "", // RegExp of tests to run (empty for all)
"MOCHA_enableTimeouts": "0", // Disable time-outs
Expand All @@ -50,7 +53,7 @@
"port": 6005,
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/out/**/*.js"
"${workspaceRoot}/dist/**/*.js"
]
},
{
Expand All @@ -76,7 +79,7 @@
"name": "Debug Mongo grammar",
"type": "antlr-debug",
"request": "launch",
// This doesn't seem to work: "input": "${workspaceFolder}/${command:AskForTestInput}",
// This doesn't seem to work: "input": "${workspaceRoot}/${command:AskForTestInput}",
"input": "c:/temp/debugger-input.mongo",
"grammar": "grammar/mongo.g4",
"startRule": "mongoCommands",
Expand Down
14 changes: 14 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,17 @@ tslint.json
.github/**
test-results.xml
.azure-pipelines/**
node_modules/**
out/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah a lot of these are duplicates. Here's the alphabetized, de-duped list for the entire file:

.azure-pipelines/**
.github/**
.gitignore
.travis.yml
.vscode-test/**
.vscode/**
*.tgz
**/*.map
build
dist/test/**
grammar
gulp*
node_modules/**
out/**
package-lock.json
src/**
stats.json
test-results.xml
test/**
testOutput/**
tsconfig.json
tslint.json
webpack.config*

(I tried out this extension to help: https://marketplace.visualstudio.com/items?itemName=Tyriar.sort-lines)

src/**
test/**
dist/test/**
testOutput/**
test-results.xml
gulp*
webpack.config*
package-lock.json
stats.json
*.tgz
grammar
build
72 changes: 72 additions & 0 deletions build/vscode-languageserver-files-stub.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// This stub is a subset of the code from files.ts in vscode-languageserver
// (https://github.com/Microsoft/vscode-languageserver-node/blob/master/server/src/files.ts), which is used
// by https://www.npmjs.com/package/dockerfile-language-server-nodejs. It contains some dynamic imports that
// can't be webpack'ed. Since dockerfile-language-server-node only uses the uriToFilePath utility from this
// file and that function doesn't have issues, the easiest solution is to copy just that function here.
//
// The original files.js file gets replaced by this file during webpack

/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const url = require("url");
const path = require("path");
const fs = require("fs");
const child_process_1 = require("child_process");
/**
* @deprecated Use the `vscode-uri` npm module which provides a more
* complete implementation of handling VS Code URIs.
*/
function uriToFilePath(uri) {
let parsed = url.parse(uri);
if (parsed.protocol !== 'file:' || !parsed.path) {
return undefined;
}
let segments = parsed.path.split('/');
for (var i = 0, len = segments.length; i < len; i++) {
segments[i] = decodeURIComponent(segments[i]);
}
if (process.platform === 'win32' && segments.length > 1) {
let first = segments[0];
let second = segments[1];
// Do we have a drive letter and we started with a / which is the
// case if the first segement is empty (see split above)
if (first.length === 0 && second.length > 1 && second[1] === ':') {
// Remove first slash
segments.shift();
}
}
return path.normalize(segments.join('/'));
}
exports.uriToFilePath = uriToFilePath;

// END OF ORIGINAL CODE

// Throw NYI if any of the other functions are ever called (they shouldn't be currently)
function resolveModule(workspaceRoot, moduleName) {
throw new Error('Not implemented');
}
exports.resolveModule = resolveModule;
function resolve(moduleName, nodePath, cwd, tracer) {
throw new Error('Not implemented');
}
exports.resolve = resolve;
function resolveGlobalNodePath(tracer) {
throw new Error('Not implemented');
}
exports.resolveGlobalNodePath = resolveGlobalNodePath;
function resolveGlobalYarnPath(tracer) {
throw new Error('Not implemented');
}
exports.resolveGlobalYarnPath = resolveGlobalYarnPath;
function resolveModulePath(workspaceRoot, moduleName, nodePath, tracer) {
throw new Error('Not implemented');
}
exports.resolveModulePath = resolveModulePath;
function resolveModule2(workspaceRoot, moduleName, nodePath, tracer) {
throw new Error('Not implemented');
}
exports.resolveModule2 = resolveModule2;
33 changes: 33 additions & 0 deletions entrypoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

"use strict";

// This is the extension entrypoint module, which imports extension.js, the actual extension code.
//
// This is in a separate file so we can properly measure extension.js load time.

let perfStats = {
loadStartTime: Date.now(),
loadEndTime: undefined
};

Object.defineProperty(exports, "__esModule", { value: true });

const extension = require("./dist/extension");

async function activate(ctx) {
return await extension.activateInternal(ctx, perfStats);
}

async function deactivate(ctx) {
return await extension.deactivateInternal(ctx, perfStats);
}

// Export as entrypoints for vscode
exports.activate = activate;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this being imported anywhere. Are these used by AzureTools?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Added comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, used by vscode

// Export for use by vscode
exports.activate = activate;
exports.deactivate = deactivate;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sounds good.

exports.deactivate = deactivate;

perfStats.loadEndTime = Date.now();
34 changes: 34 additions & 0 deletions extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

/**
* This is the external face of extension.js, the main webpack bundle for the extension.
* Anything needing to be exposed outside of the extension sources must be exported from here, because
* everything else will be in private modules in extension.js.
*/

// Export activate/deactivate for entrypoint.js
export { activateInternal, deactivateInternal } from './src/cosmosExtension';

// Exports for tests
// The tests are not packaged with the webpack bundle and therefore only have access to code exported from this file.
//
// The tests should import '../extension.ts'. At design-time they live in tests/ and so will pick up this file (extension.ts).
// At runtime the tests live in dist/tests and will therefore pick up the main webpack bundle at dist/extension.js.
export { ext } from './src/extensionVariables';
export * from './src/utils/array';
export { AttachedAccountsTreeItem, MONGO_CONNECTION_EXPECTED } from './src/tree/AttachedAccountsTreeItem';
export { parseDocDBConnectionString } from './src/docdb/docDBConnectionStrings';
export { emulatorPassword } from './src/constants';
export { getDocumentTreeItemLabel } from './src/utils/vscodeUtils';
export { validOnTimeoutOrException } from './src/utils/inputValidation';
export { addDatabaseToAccountConnectionString, getDatabaseNameFromConnectionString } from './src/mongo/mongoConnectionStrings';
export { MongoCommand } from './src/mongo/MongoCommand';
export { getAllCommandsFromText, getCommandFromTextAtLocation } from './src/mongo/MongoScrapbook';
export { rejectOnTimeout, valueOnTimeout } from './src/utils/timeout';

// These use instanceof and therefore we need to make sure we're using the same version of the bson module in the tests as in the bundle,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this only apply to test code? If not, it makes me kinda nervous. What exactly is the problem with instanceof? I guess I'd rather find a fix for instanceof than single out every single use of it we run in to.

Is this at all related to the thing you did here? microsoft/vscode-docker#745 Either way don't forget to do that here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, tests only (updated comment). The issue is that the test code is completely separate from the extension bundle, so if we do a blind import from the tests, you get two different instances of the module and hence two difference classes with different identity. That's also why we're importing everything from extension.ts instead of importing individual files directly from the tests like we used to, because you'd end up with two different instances of the code (and hence extensionVariables isn't a singleton, etc.).

extension.js is separate from the test code and uses an internal webpack version of import, so it doesn't know about anything imported by code outside of it (something I wish we could change - I tried).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this at all related to the thing you did here? microsoft/vscode-docker#745 Either way don't forget to do that here :)

No. The other fix will be in the shared version.

// so export it from the bundle itself.
export { ObjectID, ObjectId } from 'bson';
33 changes: 27 additions & 6 deletions gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@
*--------------------------------------------------------------------------------------------*/

import * as cp from 'child_process';
import * as fse from 'fs-extra';
import * as glob from 'glob';
import * as gulp from 'gulp';
import * as decompress from 'gulp-decompress';
import * as download from 'gulp-download';
import * as os from 'os';
import * as path from 'path';

const env = process.env;

function webpack(mode: string): cp.ChildProcess {
// without this, webpack can run out of memory in some environments
env.NODE_OPTIONS = '--max-old-space-size=8192';
return spawn(path.join(__dirname, './node_modules/.bin/webpack'), ['--mode', mode, '--display', 'minimal'], { stdio: 'inherit', env });
}

/**
* Installs the azure account extension before running tests (otherwise our extension would fail to activate)
* NOTE: The version isn't super important since we don't actually use the account extension in tests
*/
function installAzureAccount() {
function installAzureAccount(): Promise<void> {
const version = '0.4.3';
const extensionPath = path.join(os.homedir(), `.vscode/extensions/ms-vscode.azure-account-${version}`);
const existingExtensions = glob.sync(extensionPath.replace(version, '*'));
Expand All @@ -37,12 +46,24 @@ function installAzureAccount() {
}
}

function test() {
const env = process.env;
function test(): cp.ChildProcess {
env.DEBUGTELEMETRY = '1';
env.MOCHA_reporter = 'mocha-junit-reporter';
env.MOCHA_FILE = path.join(__dirname, 'test-results.xml');
return cp.spawn('node', ['./node_modules/vscode/bin/test'], { stdio: 'inherit', env });
env.CODE_TESTS_PATH = path.join(__dirname, 'dist/test');
return spawn('node', ['./node_modules/vscode/bin/test'], { stdio: 'inherit', env });
}

function spawn(command: string, args: string[], options: {}): cp.ChildProcess {
if (process.platform === 'win32') {
if (fse.pathExistsSync(command + '.exe')) {
command = command + '.exe';
} else if (fse.pathExistsSync(command + '.cmd')) {
command = command + '.cmd';
}
}

return cp.spawn(command, args, options);
}

exports['webpack-dev'] = () => webpack('development');
exports['webpack-prod'] = () => webpack('production');
exports.test = gulp.series(installAzureAccount, test);
Loading