Extract usage of require to separate function which can be tree-shaken by the monaco editor build and thus ignored by webpack

This commit is contained in:
Alex Dima
2022-11-09 09:39:20 +01:00
parent 5ad2852cc0
commit f46738bc47
17 changed files with 71 additions and 47 deletions
+2 -2
View File
@@ -49,8 +49,8 @@ interface NodeRequire {
config(data: any): any;
onError: Function;
__$__nodeRequire<T>(moduleName: string): T;
getStats(): ReadonlyArray<LoaderEvent>;
hasDependencyCycle(): boolean;
getStats?(): ReadonlyArray<LoaderEvent>;
hasDependencyCycle?(): boolean;
define(amdModuleId: string, dependencies: string[], callback: (...args: any[]) => any): any;
}
+1 -1
View File
@@ -1199,7 +1199,7 @@ export function asCSSUrl(uri: URI | null | undefined): string {
if (!uri) {
return `url('')`;
}
return `url('${FileAccess.asBrowserUri(uri).toString(true).replace(/'/g, '%27')}')`;
return `url('${FileAccess.uriToBrowserUri(uri).toString(true).replace(/'/g, '%27')}')`;
}
export function asCSSPropertyValue(value: string) {
+1 -1
View File
@@ -126,7 +126,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
// and because of that special rewriting needs to be done
// so that the URI uses a protocol that's understood by
// browsers (like http or https)
return FileAccess.asBrowserUri(uri).toString(true);
return FileAccess.uriToBrowserUri(uri).toString(true);
}
if (!uri) {
return href;
+4 -1
View File
@@ -40,7 +40,10 @@ export abstract class LoaderStats {
map.set(stat.detail, duration + stat.timestamp);
}
const stats = require.getStats().slice(0).sort((a, b) => a.timestamp - b.timestamp);
let stats: readonly LoaderEvent[] = [];
if (typeof require.getStats === 'function') {
stats = require.getStats().slice(0).sort((a, b) => a.timestamp - b.timestamp);
}
for (const stat of stats) {
switch (stat.type) {
+20 -8
View File
@@ -196,11 +196,18 @@ class FileAccessImpl {
*
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
*/
asBrowserUri(uri: URI): URI;
asBrowserUri(moduleId: AppResourcePath | ''): URI;
asBrowserUri(uriOrModule: URI | AppResourcePath | ''): URI {
const uri = this.toUri(uriOrModule, require);
asBrowserUri(resourcePath: AppResourcePath | ''): URI {
const uri = this.toUri(resourcePath, require);
return this.uriToBrowserUri(uri);
}
/**
* Returns a URI to use in contexts where the browser is responsible
* for loading (e.g. fetch()) or when used within the DOM.
*
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
*/
uriToBrowserUri(uri: URI): URI {
// Handle remote URIs via `RemoteAuthorities`
if (uri.scheme === Schemas.vscodeRemote) {
return RemoteAuthorities.rewrite(uri);
@@ -236,11 +243,16 @@ class FileAccessImpl {
* Returns the `file` URI to use in contexts where node.js
* is responsible for loading.
*/
asFileUri(uri: URI): URI;
asFileUri(moduleId: AppResourcePath | ''): URI;
asFileUri(uriOrModule: URI | AppResourcePath | ''): URI {
const uri = this.toUri(uriOrModule, require);
asFileUri(resourcePath: AppResourcePath | ''): URI {
const uri = this.toUri(resourcePath, require);
return this.uriToFileUri(uri);
}
/**
* Returns the `file` URI to use in contexts where node.js
* is responsible for loading.
*/
uriToFileUri(uri: URI): URI {
// Only convert the URI if it is `vscode-file:` scheme
if (uri.scheme === Schemas.vscodeFileResource) {
return uri.with({
+9 -9
View File
@@ -15,17 +15,17 @@ suite('network', () => {
// asCodeUri() & asFileUri(): simple, without authority
let originalFileUri = URI.file('network.test.ts');
let browserUri = FileAccess.asBrowserUri(originalFileUri);
let browserUri = FileAccess.uriToBrowserUri(originalFileUri);
assert.ok(browserUri.authority.length > 0);
let fileUri = FileAccess.asFileUri(browserUri);
let fileUri = FileAccess.uriToFileUri(browserUri);
assert.strictEqual(fileUri.authority.length, 0);
assert(isEqual(originalFileUri, fileUri));
// asCodeUri() & asFileUri(): with authority
originalFileUri = URI.file('network.test.ts').with({ authority: 'test-authority' });
browserUri = FileAccess.asBrowserUri(originalFileUri);
browserUri = FileAccess.uriToBrowserUri(originalFileUri);
assert.strictEqual(browserUri.authority, originalFileUri.authority);
fileUri = FileAccess.asFileUri(browserUri);
fileUri = FileAccess.uriToFileUri(browserUri);
assert(isEqual(originalFileUri, fileUri));
});
@@ -39,31 +39,31 @@ suite('network', () => {
(isWeb ? test.skip : test)('FileAccess: query and fragment is dropped (native)', () => {
const originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' });
const browserUri = FileAccess.asBrowserUri(originalFileUri);
const browserUri = FileAccess.uriToBrowserUri(originalFileUri);
assert.strictEqual(browserUri.query, '');
assert.strictEqual(browserUri.fragment, '');
});
(isWeb ? test.skip : test)('FileAccess: query and fragment is kept if URI is already of same scheme (native)', () => {
const originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' });
const browserUri = FileAccess.asBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource }));
const browserUri = FileAccess.uriToBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource }));
assert.strictEqual(browserUri.query, 'foo=bar');
assert.strictEqual(browserUri.fragment, 'something');
const fileUri = FileAccess.asFileUri(originalFileUri);
const fileUri = FileAccess.uriToFileUri(originalFileUri);
assert.strictEqual(fileUri.query, 'foo=bar');
assert.strictEqual(fileUri.fragment, 'something');
});
(isWeb ? test.skip : test)('FileAccess: web', () => {
const originalHttpsUri = URI.file('network.test.ts').with({ scheme: 'https' });
const browserUri = FileAccess.asBrowserUri(originalHttpsUri);
const browserUri = FileAccess.uriToBrowserUri(originalHttpsUri);
assert.strictEqual(originalHttpsUri.toString(), browserUri.toString());
});
test('FileAccess: remote URIs', () => {
const originalRemoteUri = URI.file('network.test.ts').with({ scheme: Schemas.vscodeRemote });
const browserUri = FileAccess.asBrowserUri(originalRemoteUri);
const browserUri = FileAccess.uriToBrowserUri(originalRemoteUri);
assert.notStrictEqual(originalRemoteUri.scheme, browserUri.scheme);
});
});
@@ -30,7 +30,7 @@ class ExtensionResourceLoaderService extends AbstractExtensionResourceLoaderServ
}
async readExtensionResource(uri: URI): Promise<string> {
uri = FileAccess.asBrowserUri(uri);
uri = FileAccess.uriToBrowserUri(uri);
if (uri.scheme !== Schemas.http && uri.scheme !== Schemas.https) {
const result = await this._fileService.readFile(uri);
@@ -127,7 +127,7 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ
// 2.) Use `FileAccess.asFileUri` to convert back from a
// `vscode-file:` URI to a `file:` URI.
const unnormalizedFileUri = FileAccess.asFileUri(requestUri);
const unnormalizedFileUri = FileAccess.uriToFileUri(requestUri);
// 3.) Strip anything from the URI that could result in
// relative paths (such as "..") by using `normalize`
@@ -189,7 +189,7 @@ export class MainThreadExtensionService implements MainThreadExtensionServiceSha
}
async $asBrowserUri(uri: UriComponents): Promise<UriComponents> {
return FileAccess.asBrowserUri(URI.revive(uri));
return FileAccess.uriToBrowserUri(URI.revive(uri));
}
}
@@ -95,7 +95,7 @@ if ((<any>self).Worker) {
const _Worker = (<any>self).Worker;
Worker = <any>function (stringUrl: string | URL, options?: WorkerOptions) {
if (/^file:/i.test(stringUrl.toString())) {
stringUrl = FileAccess.asBrowserUri(URI.parse(stringUrl.toString())).toString(true);
stringUrl = FileAccess.uriToBrowserUri(URI.parse(stringUrl.toString())).toString(true);
} else if (/^vscode-remote:/i.test(stringUrl.toString())) {
// Supporting transformation of vscode-remote URIs requires an async call to the main thread,
// but we cannot do this call from within the embedded Worker, and the only way out would be
+1 -1
View File
@@ -237,7 +237,7 @@ export function fillEditorsDragData(accessor: ServicesAccessor, resourcesOrEdito
// - only file:/ resources are supported
const firstFile = fileSystemResources.find(({ isDirectory }) => !isDirectory);
if (firstFile) {
const firstFileUri = FileAccess.asFileUri(firstFile.resource); // enforce `file:` URIs
const firstFileUri = FileAccess.uriToFileUri(firstFile.resource); // enforce `file:` URIs
if (firstFileUri.scheme === Schemas.file) {
event.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [Mimes.binary, basename(firstFile.resource), firstFileUri.toString()].join(':'));
}
@@ -174,7 +174,7 @@ export class Extension implements IExtension {
private get localIconUrl(): string | null {
if (this.local && this.local.manifest.icon) {
return FileAccess.asBrowserUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString(true);
return FileAccess.uriToBrowserUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString(true);
}
return null;
}
@@ -672,7 +672,7 @@ export class FileDownload {
try {
bufferOrUri = (await this.fileService.readFile(stat.resource, { limits: { size: maxBlobDownloadSize } }, cts.token)).value.buffer;
} catch (error) {
bufferOrUri = FileAccess.asBrowserUri(stat.resource);
bufferOrUri = FileAccess.uriToBrowserUri(stat.resource);
}
if (!cts.token.isCancellationRequested) {
@@ -256,9 +256,11 @@ class PerfModelContentProvider implements ITextModelContentProvider {
map.set(LoaderEventType.CachedDataFound, []);
map.set(LoaderEventType.CachedDataMissed, []);
map.set(LoaderEventType.CachedDataRejected, []);
for (const stat of require.getStats()) {
if (map.has(stat.type)) {
map.get(stat.type)!.push(stat.detail);
if (typeof require.getStats === 'function') {
for (const stat of require.getStats()) {
if (map.has(stat.type)) {
map.get(stat.type)!.push(stat.detail);
}
}
}
@@ -281,12 +281,12 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ
private async registerExtensionWalkthroughContributions(extension: IExtensionDescription) {
const convertExtensionPathToFileURI = (path: string) => path.startsWith('https://')
? URI.parse(path, true)
: FileAccess.asFileUri(joinPath(extension.extensionLocation, path));
: FileAccess.uriToFileUri(joinPath(extension.extensionLocation, path));
const convertExtensionRelativePathsToBrowserURIs = (path: string | { hc: string; hcLight?: string; dark: string; light: string }): { hcDark: URI; hcLight: URI; dark: URI; light: URI } => {
const convertPath = (path: string) => path.startsWith('https://')
? URI.parse(path, true)
: FileAccess.asBrowserUri(joinPath(extension.extensionLocation, path));
: FileAccess.uriToBrowserUri(joinPath(extension.extensionLocation, path));
if (typeof path === 'string') {
const converted = convertPath(path);
@@ -353,7 +353,7 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ
type: 'markdown',
path: convertExtensionPathToFileURI(step.media.markdown),
base: convertExtensionPathToFileURI(dirname(step.media.markdown)),
root: FileAccess.asFileUri(extension.extensionLocation),
root: FileAccess.uriToFileUri(extension.extensionLocation),
};
}
else if (step.media.svg) {
@@ -401,7 +401,7 @@ export class WalkthroughsService extends Disposable implements IWalkthroughsServ
icon: {
type: 'image',
path: iconStr
? FileAccess.asBrowserUri(joinPath(extension.extensionLocation, iconStr)).toString(true)
? FileAccess.uriToBrowserUri(joinPath(extension.extensionLocation, iconStr)).toString(true)
: DefaultIconPath
},
when: ContextKeyExpr.deserialize(override ?? walkthrough.when) ?? ContextKeyExpr.true(),
+1 -1
View File
@@ -640,7 +640,7 @@ export class NativeWindow extends Disposable {
private async handleWarnings(): Promise<void> {
// Check for cyclic dependencies
if (require.hasDependencyCycle()) {
if (typeof require.hasDependencyCycle === 'function' && require.hasDependencyCycle()) {
if (isCI) {
this.logService.error('Error: There is a dependency cycle in the AMD modules that needs to be resolved!');
this.nativeHostService.exit(37); // running on a build machine, just exit without showing a dialog
@@ -15,9 +15,14 @@ import type { IRawTheme, IOnigLib } from 'vscode-textmate';
import { ContiguousMultilineTokensBuilder } from 'vs/editor/common/tokens/contiguousMultilineTokensBuilder';
import { countEOL } from 'vs/editor/common/core/eolCounter';
import { LineTokens } from 'vs/editor/common/tokens/lineTokens';
import { FileAccess } from 'vs/base/common/network';
import { AppResourcePath, FileAccess, nodeModulesAsarPath, nodeModulesPath } from 'vs/base/common/network';
import { TMTokenization } from 'vs/workbench/services/textMate/common/TMTokenization';
const textmateModuleLocation: AppResourcePath = `${nodeModulesPath}/vscode-textmate`;
const textmateModuleLocationAsar: AppResourcePath = `${nodeModulesAsarPath}/vscode-textmate`;
const onigurumaModuleLocation: AppResourcePath = `${nodeModulesPath}/vscode-oniguruma`;
const onigurumaModuleLocationAsar: AppResourcePath = `${nodeModulesAsarPath}/vscode-oniguruma`;
export interface IValidGrammarDefinitionDTO {
location: UriComponents;
language?: string;
@@ -153,15 +158,17 @@ export class TextMateWorker {
}
private async _loadTMGrammarFactory(grammarDefinitions: IValidGrammarDefinition[]): Promise<TMGrammarFactory> {
require.config({
paths: {
'vscode-textmate': '../node_modules/vscode-textmate/release/main',
'vscode-oniguruma': '../node_modules/vscode-oniguruma/release/main',
}
});
const vscodeTextmate = await import('vscode-textmate');
const vscodeOniguruma = await import('vscode-oniguruma');
const response = await fetch(FileAccess.asBrowserUri('vscode-oniguruma/../onig.wasm').toString(true));
// TODO: asar support
const useAsar = false; // this._environmentService.isBuilt && !isWeb
const textmateLocation: AppResourcePath = useAsar ? textmateModuleLocation : textmateModuleLocationAsar;
const onigurumaLocation: AppResourcePath = useAsar ? onigurumaModuleLocation : onigurumaModuleLocationAsar;
const textmateMain: AppResourcePath = `${textmateLocation}/release/main.js`;
const onigurumaMain: AppResourcePath = `${onigurumaLocation}/release/main.js`;
const onigurumaWASM: AppResourcePath = `${onigurumaLocation}/release/onig.wasm`;
const vscodeTextmate = await import(FileAccess.asBrowserUri(textmateMain).toString(true));
const vscodeOniguruma = await import(FileAccess.asBrowserUri(onigurumaMain).toString(true));
const response = await fetch(FileAccess.asBrowserUri(onigurumaWASM).toString(true));
// Using the response directly only works if the server sets the MIME type 'application/wasm'.
// Otherwise, a TypeError is thrown when using the streaming compiler.
// We therefore use the non-streaming compiler :(.