From 4f2cf6e6e586868873b83cf6af5dc26805a8c677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mangeonjean?= Date: Mon, 25 Sep 2023 19:10:57 +0200 Subject: [PATCH] feat: generate meta-package pulling default extension sets --- release.ts | 5 + releaseNext.ts | 5 + rollup/rollup.default-extensions.ts | 221 ++++++++++++++++++---------- 3 files changed, 156 insertions(+), 75 deletions(-) diff --git a/release.ts b/release.ts index 63eace9e..f22b0f90 100644 --- a/release.ts +++ b/release.ts @@ -145,6 +145,11 @@ async function publishNpm (version: string) { if (packageJson.dependencies?.vscode != null) { packageJson.dependencies.vscode = `npm:@codingame/monaco-vscode-api@${version}` } + for (const dependency in packageJson.dependencies) { + if (dependency.startsWith('@codingame/monaco-vscode-')) { + packageJson.dependencies[dependency] = version + } + } await fs.writeFile(packageJsonFile, JSON.stringify(packageJson, null, 2)) $.cwd = libDir diff --git a/releaseNext.ts b/releaseNext.ts index 2d165377..885e8eeb 100644 --- a/releaseNext.ts +++ b/releaseNext.ts @@ -67,6 +67,11 @@ async function publishNpm (version: string) { if (packageJson.dependencies?.vscode != null) { packageJson.dependencies.vscode = `npm:@codingame/monaco-vscode-api@${version}` } + for (const dependency in packageJson.dependencies) { + if (dependency.startsWith('@codingame/monaco-vscode-')) { + packageJson.dependencies[dependency] = version + } + } await fs.writeFile(packageJsonFile, JSON.stringify(packageJson, null, 2)) $.cwd = libDir diff --git a/rollup/rollup.default-extensions.ts b/rollup/rollup.default-extensions.ts index 94cdc7cc..1da2a869 100644 --- a/rollup/rollup.default-extensions.ts +++ b/rollup/rollup.default-extensions.ts @@ -21,96 +21,168 @@ const defaultExtensions = fs.readdirSync(DEFAULT_EXTENSIONS_PATH, { withFileType .filter(f => f.isDirectory() && fs.existsSync(path.resolve(DEFAULT_EXTENSIONS_PATH, f.name, 'package.json'))) .map(f => f.name) -export default rollup.defineConfig(defaultExtensions.map(name => ({ - input: path.resolve(DEFAULT_EXTENSIONS_PATH, name), - output: [{ - minifyInternalExports: false, - assetFileNames: chunkInfo => { - if (chunkInfo.name != null && chunkInfo.name.endsWith('d.ts')) { +const languageGrammarExtensions: string[] = [] +const languageFeatureExtensions: string[] = [] +for (const extension of defaultExtensions) { + const extensionPath = path.resolve(DEFAULT_EXTENSIONS_PATH, extension, 'package.json') + const packageJson = JSON.parse(fs.readFileSync(extensionPath).toString()) + if ((packageJson.contributes?.languages ?? []).length > 0) { + languageGrammarExtensions.push(extension) + } + if (extension.endsWith('language-features')) { + languageFeatureExtensions.push(extension) + } +} + +export default rollup.defineConfig([ + ...defaultExtensions.map(name => ({ + input: path.resolve(DEFAULT_EXTENSIONS_PATH, name), + output: [{ + minifyInternalExports: false, + assetFileNames: chunkInfo => { + if (chunkInfo.name != null && chunkInfo.name.endsWith('d.ts')) { // append .txt at the end of d.ts files: those file are required by the typescript extension and are just expected to be loaded as simple text - return '[name][extname].txt' - } - return '[name][extname]' - }, - format: 'esm', - dir: `dist/default-extension-${name}`, - entryFileNames: 'index.js', - chunkFileNames: '[name].js', - hoistTransitiveImports: false - }], - external (source) { - return source === 'vscode/extensions' - }, - plugins: [ - { - name: 'resolve-asset-url', - resolveFileUrl (options) { - let relativePath = options.relativePath - if (!relativePath.startsWith('.')) { - relativePath = `./${options.relativePath}` + return '[name][extname].txt' } - return `'${relativePath}'` - } + return '[name][extname]' + }, + format: 'esm', + dir: `dist/default-extension-${name}`, + entryFileNames: 'index.js', + chunkFileNames: '[name].js', + hoistTransitiveImports: false + }], + external (source) { + return source === 'vscode/extensions' }, - nodeResolve({ - extensions: EXTENSIONS - }), - importMetaAssets(), - { - name: 'dynamic-import-polyfill', - renderDynamicImport (): { left: string, right: string } { - return { - left: 'import(', - right: ').then(module => module.default ?? module)' + plugins: [ + { + name: 'resolve-asset-url', + resolveFileUrl (options) { + let relativePath = options.relativePath + if (!relativePath.startsWith('.')) { + relativePath = `./${options.relativePath}` + } + return `'${relativePath}'` } - } - }, - extensionDirectoryPlugin({ - include: `${DEFAULT_EXTENSIONS_PATH}/**/*`, - transformManifest (manifest) { - if (manifest.name === 'configuration-editing') { - manifest = { - ...manifest, - contributes: { - ...manifest.contributes, - jsonValidation: manifest.contributes!.jsonValidation!.map(validation => { - return { - fileMatch: (validation.fileMatch as string).replaceAll('%APP_SETTINGS_HOME%', 'user:'), - url: validation.url - } - }) + }, + nodeResolve({ + extensions: EXTENSIONS + }), + importMetaAssets(), + { + name: 'dynamic-import-polyfill', + renderDynamicImport (): { left: string, right: string } { + return { + left: 'import(', + right: ').then(module => module.default ?? module)' + } + } + }, + extensionDirectoryPlugin({ + include: `${DEFAULT_EXTENSIONS_PATH}/**/*`, + transformManifest (manifest) { + if (manifest.name === 'configuration-editing') { + manifest = { + ...manifest, + contributes: { + ...manifest.contributes, + jsonValidation: manifest.contributes!.jsonValidation!.map(validation => { + return { + fileMatch: (validation.fileMatch as string).replaceAll('%APP_SETTINGS_HOME%', 'user:'), + url: validation.url + } + }) + } } } + return { + ...manifest, + main: undefined + } + }, + async getAdditionalResources (manifest, directory) { + if (manifest.name === 'typescript-language-features') { + const files = (await fsPromise.readdir(path.resolve(directory, 'dist/browser/typescript'), { + withFileTypes: true + })).filter(f => f.isFile()).map(f => f.name) + return files.map(file => ({ path: path.join('./dist/browser/typescript', file), mimeType: 'text/plain' })) + } + return [] } - return { - ...manifest, - main: undefined + }), + metadataPlugin({ + handle (_, dependencies, entrypoints, options, bundle) { + const entrypoint = Object.values(bundle).filter(v => (v as rollup.OutputChunk).isEntry)[0]!.fileName + const packageJson: PackageJson = { + name: `@codingame/monaco-vscode-${name}-default-extension`, + ...Object.fromEntries(Object.entries(pkg).filter(([key]) => ['version', 'keywords', 'author', 'license', 'repository', 'type'].includes(key))), + private: false, + description: `Default VSCode extension designed to be used with ${pkg.name}`, + main: entrypoint, + module: entrypoint, + dependencies: { + vscode: `npm:${pkg.name}@^${pkg.version}`, + ...Object.fromEntries(Object.entries(pkg.dependencies).filter(([key]) => dependencies.has(key))) + } + } + + this.emitFile({ + fileName: 'package.json', + needsCodeReference: false, + source: JSON.stringify(packageJson, null, 2), + type: 'asset' + }) } + }) + ] + })), ...[{ + name: '@codingame/monaco-vscode-all-default-extensions', + directory: 'default-extension-all', + extensions: defaultExtensions + }, { + name: '@codingame/monaco-vscode-all-language-default-extensions', + directory: 'default-extension-all-languages', + extensions: languageGrammarExtensions + }, { + name: '@codingame/monaco-vscode-all-language-feature-default-extensions', + directory: 'default-extension-all-language-features', + extensions: languageFeatureExtensions + }].map(({ name, directory, extensions }) => ({ + input: 'index.js', + output: [{ + format: 'esm', + dir: 'dist/' + directory, + entryFileNames: 'index.js' + }], + external () { + return true + }, + plugins: [{ + name: 'code-loader', + resolveId () { + return 'index.js' }, - async getAdditionalResources (manifest, directory) { - if (manifest.name === 'typescript-language-features') { - const files = (await fsPromise.readdir(path.resolve(directory, 'dist/browser/typescript'), { - withFileTypes: true - })).filter(f => f.isFile()).map(f => f.name) - return files.map(file => ({ path: path.join('./dist/browser/typescript', file), mimeType: 'text/plain' })) - } - return [] + load () { + return ` +${extensions.map(name => `import '@codingame/monaco-vscode-${name}-default-extension'`).join('\n')} + ` } - }), + }, metadataPlugin({ handle (_, dependencies, entrypoints, options, bundle) { const entrypoint = Object.values(bundle).filter(v => (v as rollup.OutputChunk).isEntry)[0]!.fileName const packageJson: PackageJson = { - name: `@codingame/monaco-vscode-${name}-default-extension`, + name, ...Object.fromEntries(Object.entries(pkg).filter(([key]) => ['version', 'keywords', 'author', 'license', 'repository', 'type'].includes(key))), private: false, - description: `Default VSCode extension designed to be used with ${pkg.name}`, + description: `Meta package including default VSCode extensions designed to be used with ${pkg.name}`, main: entrypoint, module: entrypoint, - dependencies: { - vscode: `npm:${pkg.name}@^${pkg.version}`, - ...Object.fromEntries(Object.entries(pkg.dependencies).filter(([key]) => dependencies.has(key))) - } + dependencies: Object.fromEntries(Array.from(dependencies).map(name => [ + name, + pkg.version + ])) } this.emitFile({ @@ -120,6 +192,5 @@ export default rollup.defineConfig(defaultExtensions.map(name => (