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

Better split service overrides #206

Merged
merged 15 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"compile": "tsc",
"start": "NODE_OPTIONS=--experimental-import-meta-resolve vite --config vite.config.ts",
"start:debug": "vite --config vite.config.ts --debug --force",
"build": "vite --config vite.config.ts build",
"build:github": "vite --config vite.github-page.config.ts build && touch dist/.nojekyll",
"build": "tsc --noEmit && vite --config vite.config.ts build",
"build:github": "tsc --noEmit && vite --config vite.github-page.config.ts build && touch dist/.nojekyll",
"start:debugServer": "node --loader ts-node/esm src/debugServer.ts",
"start:extHostServer": "vscode-ext-host-server --without-connection-token"
},
Expand Down
1 change: 1 addition & 0 deletions demo/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"noImplicitReturns": true,
"baseUrl": ".",
"paths": {
"vscode/vscode/*": ["../dist/main/vscode/src/*"],
"vscode/*": ["../dist/main/*"]
}
},
Expand Down
3 changes: 1 addition & 2 deletions demo/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ export default defineConfig({
'@codingame/monaco-vscode-typescript-language-features-default-extension', '@codingame/monaco-vscode-markdown-language-features-default-extension',
'@codingame/monaco-vscode-json-language-features-default-extension', '@codingame/monaco-vscode-css-language-features-default-extension',
'@codingame/monaco-vscode-npm-default-extension', '@codingame/monaco-vscode-css-default-extension', '@codingame/monaco-vscode-markdown-basics-default-extension', '@codingame/monaco-vscode-html-default-extension',
'@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension',
'vscode/workers/textmate.worker'
'@codingame/monaco-vscode-html-language-features-default-extension', '@codingame/monaco-vscode-configuration-editing-default-extension', '@codingame/monaco-vscode-media-preview-default-extension', '@codingame/monaco-vscode-markdown-math-default-extension'
],
esbuildOptions: {
plugins: [{
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"type": "module",
"scripts": {
"build": "npm run clean && npm run generate-types && npm run lint && npm run compile-rollup-plugins && npm run compile-treemending-script && npm run compile && npm run compile-server && npm run compile-default-extensions && npm run copy-monaco-editor",
"build": "npm run clean && npm run lint && npm run compile && npm run compile-rollup-plugins && npm run generate-types && npm run compile-treemending-script && npm run compile-server && npm run compile-default-extensions && npm run copy-monaco-editor",
"compile": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.config.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config.json`}' --vscode-version ${npm_package_config_vscode_version} --vscode-ref ${npm_package_config_vscode_ref}",
"compile-default-extensions": "NODE_OPTIONS=--max_old_space_size=8192 rollup --config rollup/rollup.default-extensions.ts --configPlugin 'typescript={tsconfig: `tsconfig.rollup-config-default-extensions.json`}'",
"clean": "rm -rf dist/",
Expand Down Expand Up @@ -59,6 +59,7 @@
"@types/yauzl": "^2.10.0",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript/vfs": "^1.5.0",
"@vscode/iconv-lite-umd": "^0.7.0",
"@web/rollup-plugin-import-meta-assets": "^2.1.0",
"change-package-name": "^1.0.5",
Expand Down
64 changes: 50 additions & 14 deletions rollup/rollup-metadata-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,59 @@
import type { OutputBundle, OutputOptions, Plugin, PluginContext } from 'rollup'
import type { OutputBundle, OutputChunk, OutputOptions, Plugin, PluginContext } from 'rollup'
import { builtinModules } from 'module'
import path from 'path'

interface Group {
name: string
dependencies: Set<string>
modules: Set<string>
entrypoints: Set<string>
}

interface Options {
stage?: 'generateBundle' | 'writeBundle'
getGroup?: (entryPoint: string, options: OutputOptions) => string
handle (this: PluginContext, groupName: string, dependencies: Set<string>, entrypoints: Set<string>, options: OutputOptions, bundle: OutputBundle): void | Promise<void>
handle (this: PluginContext, groupName: string, dependencies: Set<string>, entrypoints: Set<string>, exclusiveModules: Set<string>, options: OutputOptions, bundle: OutputBundle): void | Promise<void>
}

export default ({ handle, getGroup = () => 'main' }: Options): Plugin => ({
export default ({ handle, getGroup = () => 'main', stage = 'generateBundle' }: Options): Plugin => ({
name: 'generate-metadata',
async generateBundle (options: OutputOptions, bundle: OutputBundle) {
const externalDependencyCache = new Map<string, Set<string>>()
const getModuleExternalDependencies = (id: string, path: string[]): Set<string> => {
if (!externalDependencyCache.has(id)) {
[stage]: async function (this: PluginContext, options: OutputOptions, bundle: OutputBundle) {
const dependencyCache = new Map<string, { externals: Set<string>, internals: Set<string> }>()

const inputToOutput = Object.fromEntries(Object.values(bundle)
.filter((chunk): chunk is OutputChunk => 'code' in chunk)
.map(chunk => [
chunk.facadeModuleId,
path.resolve(options.dir!, chunk.preliminaryFileName)
]))
const getModuleDependencies = (id: string, path: string[]): { externals: Set<string>, internals: Set<string> } => {
if (path.includes(id)) {
// Break recursive imports
return {
externals: new Set(),
internals: new Set()
}
}
if (!dependencyCache.has(id)) {
const moduleInfo = this.getModuleInfo(id)!
if (moduleInfo.isExternal) {
const match = /^(?:@[^/]*\/)?[^/]*/.exec(id)
externalDependencyCache.set(id, new Set(match != null && !builtinModules.includes(match[0]) ? [match[0]] : []))
dependencyCache.set(id, {
externals: new Set(match != null && !builtinModules.includes(match[0]) ? [match[0]] : []),
internals: new Set([])
})
} else {
externalDependencyCache.set(id, new Set([...moduleInfo.importedIds, ...moduleInfo.dynamicallyImportedIds].flatMap(depId => Array.from(getModuleExternalDependencies(depId, [...path, id])))))
const dependencies = [...moduleInfo.importedIds, ...moduleInfo.dynamicallyImportedIds].map(depId => {
return getModuleDependencies(depId, [...path, id])
})
dependencyCache.set(id, {
externals: new Set(dependencies.map(t => t.externals).flatMap(map => Array.from(map))),
internals: new Set([inputToOutput[id] ?? id, ...dependencies.map(t => t.internals).flatMap(map => Array.from(map))])
})
}
}

return externalDependencyCache.get(id)!
return dependencyCache.get(id)!
}

const groups = new Map<string, Group>()
Expand All @@ -37,22 +63,32 @@ export default ({ handle, getGroup = () => 'main' }: Options): Plugin => ({
continue
}
const groupName = getGroup(id, options)
const externalDependencies = getModuleExternalDependencies(moduleInfo.id, [])
const dependencies = getModuleDependencies(moduleInfo.id, [])

if (!groups.has(groupName)) {
groups.set(groupName, {
dependencies: new Set<string>(),
entrypoints: new Set<string>(),
name: groupName
name: groupName,
modules: new Set<string>()
})
}
const group = groups.get(groupName)!
externalDependencies.forEach(d => group.dependencies.add(d))
dependencies.externals.forEach(d => group.dependencies.add(d))
dependencies.internals.forEach(d => group.modules.add(d))
group.entrypoints.add(id)
}

const moduleUseCount = new Map<string, number>()
for (const [_, group] of groups.entries()) {
for (const module of group.modules) {
moduleUseCount.set(module, (moduleUseCount.get(module) ?? 0) + 1)
}
}

await Promise.all(Array.from(groups.entries()).map(async ([name, group]) => {
await handle.call(this, name, group.dependencies, group.entrypoints, options, bundle)
const exclusiveModules = new Set(Array.from(group.modules).filter(module => moduleUseCount.get(module)! <= 1))
await handle.call(this, name, group.dependencies, exclusiveModules, group.entrypoints, options, bundle)
}))
}
})
Loading