diff --git a/packages/monaco-graphql/__fixtures__/bundle-test/index.html b/packages/monaco-graphql/__fixtures__/bundle-test/index.html new file mode 100644 index 00000000000..b78bb95423a --- /dev/null +++ b/packages/monaco-graphql/__fixtures__/bundle-test/index.html @@ -0,0 +1,9 @@ + + +
+ + + + + + diff --git a/packages/monaco-graphql/__fixtures__/bundle-test/index.ts b/packages/monaco-graphql/__fixtures__/bundle-test/index.ts new file mode 100644 index 00000000000..b06daa901c3 --- /dev/null +++ b/packages/monaco-graphql/__fixtures__/bundle-test/index.ts @@ -0,0 +1,16 @@ +import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker.js?worker'; +import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js?worker'; +import GraphQLWorker from 'monaco-graphql/esm/graphql.worker.js?worker'; +import 'monaco-graphql'; + +globalThis.MonacoEnvironment = { + getWorker(_workerId: string, label: string) { + switch (label) { + case 'json': + return new JsonWorker(); + case 'graphql': + return new GraphQLWorker(); + } + return new EditorWorker(); + }, +}; diff --git a/packages/monaco-graphql/__tests__/monaco-editor.test.ts b/packages/monaco-graphql/__tests__/monaco-editor.test.ts index 4f0aac0abd5..abde426af94 100644 --- a/packages/monaco-graphql/__tests__/monaco-editor.test.ts +++ b/packages/monaco-graphql/__tests__/monaco-editor.test.ts @@ -1,41 +1,69 @@ import { describe, it, expect } from 'vitest'; -import { $ } from 'execa'; +import { build, type UserConfig } from 'vite'; +import path from 'node:path'; -// eslint-disable-next-line no-control-regex -const ANSI_COLOR_REGEX = /\u001b\[\d+m/g; - -const VOLATILE_LINE = - /modules transformed|rendering chunks|computing gzip size|transforming|built in|building for production/; +const FIXTURE_ROOT = path.resolve( + import.meta.dirname, + '../__fixtures__/bundle-test', +); describe('monaco-editor', () => { - it('should include in bundle only graphql/json languages', async () => { - const { stdout } = - await $`yarn workspace example-monaco-graphql-react-vite build`; - // When process.env.CI is set, stdout contains ANSI color codes, and vite doesn't have - // `--no-colors` flag - const files = stdout - .replaceAll(ANSI_COLOR_REGEX, '') - .split('\n') - .map(line => line.replaceAll(/\s{2,}.*/gm, '').trim()) - .filter(line => line && !VOLATILE_LINE.test(line)); + it('should not bundle Monaco language modules beyond graphql and json', async () => { + const result = await build({ + root: FIXTURE_ROOT, + logLevel: 'warn', + build: { + write: false, + minify: false, + target: 'esnext', + reportCompressedSize: false, + rollupOptions: { + treeshake: false, + output: { + entryFileNames: '[name].js', + chunkFileNames: 'assets/[name].js', + assetFileNames: 'assets/[name].[ext]', + }, + }, + }, + worker: { + format: 'es', + rollupOptions: { + treeshake: false, + output: { + entryFileNames: 'workers/[name].js', + chunkFileNames: 'workers/[name].js', + }, + }, + }, + } satisfies UserConfig); + + const mainOutput = Array.isArray(result) ? result[0] : result; + const files = mainOutput.output.map(chunk => chunk.fileName).sort(); + + // Explicit negative assertion: importing monaco-graphql must not pull in + // TypeScript, CSS, or HTML language services. A consumer who only wants + // GraphQL + JSON should not be forced to ship them. + for (const file of files) { + expect(file).not.toMatch( + /typescript|tsMode|tsWorker|ts\.worker|cssMode|css\.worker|htmlMode|html\.worker/i, + ); + } + expect(files).toMatchInlineSnapshot(` [ - "dist/index.html", - "dist/workers/graphql.js", - "dist/assets/codicon.ttf", - "dist/workers/standalone.js", - "dist/workers/editor.worker.js", - "dist/workers/json.worker.js", - "dist/workers/graphql.worker.js", - "dist/workers/ts.worker.js", - "dist/assets/index.css", - "dist/assets/graphql.js", - "dist/assets/typescript.js", - "dist/assets/index.js", - "dist/assets/tsMode.js", - "dist/assets/jsonMode.js", - "dist/assets/graphqlMode.js", - "dist/index.js", + "assets/codicon.ttf", + "assets/graphql.js", + "assets/graphqlMode.js", + "assets/index.css", + "assets/jsonMode.js", + "index.html", + "index.js", + "workers/editor.worker.js", + "workers/graphql.js", + "workers/graphql.worker.js", + "workers/json.worker.js", + "workers/standalone.js", ] `); }, 60_000); diff --git a/packages/monaco-graphql/package.json b/packages/monaco-graphql/package.json index c165d2cbdd5..cd35db65a16 100644 --- a/packages/monaco-graphql/package.json +++ b/packages/monaco-graphql/package.json @@ -76,7 +76,6 @@ "picomatch-browser": "^2.2.6" }, "devDependencies": { - "execa": "^7.1.1", "graphql": "^16.9.0", "monaco-editor": "0.52.2", "prettier": "3.3.2", diff --git a/resources/custom-words.txt b/resources/custom-words.txt index eb1cc28a269..c8cde7e6594 100644 --- a/resources/custom-words.txt +++ b/resources/custom-words.txt @@ -228,6 +228,7 @@ therox thomasheyenbrock timsuchanek tokenizes +treeshake tsup turbopack typeahead diff --git a/yarn.lock b/yarn.lock index 455b489f60d..cf164b5cf50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17112,7 +17112,6 @@ __metadata: version: 0.0.0-use.local resolution: "monaco-graphql@workspace:packages/monaco-graphql" dependencies: - execa: "npm:^7.1.1" graphql: "npm:^16.9.0" graphql-language-service: "npm:^5.5.1" monaco-editor: "npm:0.52.2"