From 5a7e91758731415795599cbc4f217a67e3606997 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 13 Oct 2025 18:05:43 +0200 Subject: [PATCH] Uses rollup for ESM build and d.ts bundling. (#5048) * Uses rollup for ESM build and d.ts bundling. Moves monaco.languages.{typescript, json, html, css} to monaco.*. Moves monaco.editor.createWebWorker to monaco.createWebWorker. * Adds excluded files from dist, as they needed to be patched. --- build/amd/src/editor.main.ts | 28 +- build/build-languages.ts | 127 ----- build/build-monaco-editor.ts | 302 +---------- build/esm/build.script.ts | 7 + .../rollup-plugin-keep-css-imports/.gitignore | 1 + .../rollup-plugin-keep-css-imports/LICENSE | 21 + .../rollup-plugin-keep-css-imports/README.md | 2 + .../dist/ImportUpdater.d.ts | 25 + .../dist/compileSass.d.ts | 31 ++ .../dist/constants.d.ts | 3 + .../dist/helpers.d.ts | 52 ++ .../dist/index.d.ts | 4 + .../dist/index.mjs | 487 +++++++++++++++++ .../dist/index.original.mjs | 489 ++++++++++++++++++ .../dist/types.d.ts | 110 ++++ .../package.json | 74 +++ build/esm/rollup-types.config.mjs | 67 +++ .../esm/rollup-url-to-module-plugin/index.mjs | 63 +++ build/esm/rollup.config.mjs | 109 ++++ build/fillers/vscode-nls.ts | 46 -- build/releaseMetadata.ts | 2 +- build/utils.ts | 170 ------ package-lock.json | 150 ++++++ package.json | 9 +- src/common/workers.ts | 22 +- src/editor/edcore.main.ts | 2 + src/editor/editor.all.ts | 3 + src/editor/editor.api.ts | 3 + src/editor/editor.main.ts | 28 +- src/editor/internal/editorWithLanguages.ts | 10 + src/editor/internal/initialize.ts | 12 + src/language/css/monaco.contribution.ts | 3 - src/language/css/workerManager.ts | 2 +- src/language/html/monaco.contribution.ts | 11 - src/language/html/workerManager.ts | 1 + src/language/json/monaco.contribution.ts | 11 +- src/language/json/workerManager.ts | 1 + .../typescript/monaco.contribution.ts | 18 +- src/language/typescript/workerManager.ts | 1 + 39 files changed, 1795 insertions(+), 712 deletions(-) delete mode 100644 build/build-languages.ts create mode 100644 build/esm/build.script.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/.gitignore create mode 100644 build/esm/rollup-plugin-keep-css-imports/LICENSE create mode 100644 build/esm/rollup-plugin-keep-css-imports/README.md create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/ImportUpdater.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/compileSass.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/constants.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/helpers.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/index.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/index.mjs create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/index.original.mjs create mode 100644 build/esm/rollup-plugin-keep-css-imports/dist/types.d.ts create mode 100644 build/esm/rollup-plugin-keep-css-imports/package.json create mode 100644 build/esm/rollup-types.config.mjs create mode 100644 build/esm/rollup-url-to-module-plugin/index.mjs create mode 100644 build/esm/rollup.config.mjs delete mode 100644 build/fillers/vscode-nls.ts create mode 100644 src/editor/edcore.main.ts create mode 100644 src/editor/editor.all.ts create mode 100644 src/editor/editor.api.ts create mode 100644 src/editor/internal/editorWithLanguages.ts create mode 100644 src/editor/internal/initialize.ts diff --git a/build/amd/src/editor.main.ts b/build/amd/src/editor.main.ts index 527d4ddf..32783bfa 100644 --- a/build/amd/src/editor.main.ts +++ b/build/amd/src/editor.main.ts @@ -1,6 +1,24 @@ /// @ts-ignore import * as require from 'require'; +if (typeof (globalThis as any).require !== 'undefined' && typeof (globalThis as any).require.config === 'function') { + (globalThis as any).require.config({ + ignoreDuplicateModules: [ + 'vscode-languageserver-types', + 'vscode-languageserver-types/main', + 'vscode-languageserver-textdocument', + 'vscode-languageserver-textdocument/main', + 'vscode-nls', + 'vscode-nls/vscode-nls', + 'jsonc-parser', + 'jsonc-parser/main', + 'vscode-uri', + 'vscode-uri/index', + 'vs/basic-languages/typescript/typescript' + ] + }); +} + self.MonacoEnvironment = { getWorker: function (_moduleId, label) { if (label === 'json') { @@ -63,16 +81,10 @@ function getWorkerBootstrapUrl(workerScriptUrl: string | URL) { } import 'vs/nls.messages-loader!'; +import * as monaco from '../../../src/editor/editor.main'; export * from '../../../src/editor/editor.main'; -// for now, lsp is only available to amd build -import * as lsp from '@vscode/monaco-lsp-client'; -export { lsp }; - -// TODO@hediet get rid of the monaco global -if ((globalThis as any).monaco) { - (globalThis as any).monaco.lsp = lsp; -} +globalThis.monaco = monaco; const styleSheetUrl = require.toUrl('vs/editor/editor.main.css'); diff --git a/build/build-languages.ts b/build/build-languages.ts deleted file mode 100644 index f2f0d285..00000000 --- a/build/build-languages.ts +++ /dev/null @@ -1,127 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import glob from 'glob'; -import { runTsc, massageAndCopyDts, buildESM } from './utils'; -import { removeDir } from './fs'; - -removeDir(`out/languages`); - -runTsc(`src/tsconfig.json`); - -//#region Type Defintion - -massageAndCopyDts( - `out/languages/tsc/language/css/monaco.contribution.d.ts`, - `out/languages/bundled/css.d.ts`, - 'monaco.languages.css' -); -massageAndCopyDts( - `out/languages/tsc/language/html/monaco.contribution.d.ts`, - `out/languages/bundled/html.d.ts`, - 'monaco.languages.html' -); -massageAndCopyDts( - `out/languages/tsc/language/json/monaco.contribution.d.ts`, - `out/languages/bundled/json.d.ts`, - 'monaco.languages.json' -); -massageAndCopyDts( - `out/languages/tsc/language/typescript/monaco.contribution.d.ts`, - `out/languages/bundled/typescript.d.ts`, - 'monaco.languages.typescript' -); - -//#endregion - -//#region css - -buildESM({ - base: 'language/css', - entryPoints: [ - 'src/language/css/monaco.contribution.ts', - 'src/language/css/cssMode.ts', - 'src/language/css/css.worker.ts' - ], - external: ['monaco-editor-core', '*/cssMode', '*/monaco.contribution'] -}); - -//#endregion - -//#region html - -buildESM({ - base: 'language/html', - entryPoints: [ - 'src/language/html/monaco.contribution.ts', - 'src/language/html/htmlMode.ts', - 'src/language/html/html.worker.ts' - ], - external: ['monaco-editor-core', '*/htmlMode', '*/monaco.contribution'] -}); - -//#endregion - -//#region json - -buildESM({ - base: 'language/json', - entryPoints: [ - 'src/language/json/monaco.contribution.ts', - 'src/language/json/jsonMode.ts', - 'src/language/json/json.worker.ts' - ], - external: ['monaco-editor-core', '*/jsonMode', '*/monaco.contribution'] -}); - -//#endregion - -//#region typescript - -buildESM({ - base: 'language/typescript', - entryPoints: [ - 'src/language/typescript/monaco.contribution.ts', - 'src/language/typescript/tsMode.ts', - 'src/language/typescript/ts.worker.ts' - ], - external: ['monaco-editor-core', '*/tsMode', '*/monaco.contribution'] -}); - -//#endregion - -//#region basic-languages - -glob('../src/basic-languages/*/*.contribution.ts', { cwd: __dirname }, function (err, files) { - if (err) { - console.error(err); - return; - } - - const languages = files.map((file) => file.split('/')[3]); - - // ESM - { - /** @type {string[]} */ - const entryPoints = [ - 'src/basic-languages/monaco.contribution.ts', - 'src/basic-languages/_.contribution.ts' - ]; - const external = ['monaco-editor-core', '*/_.contribution']; - for (const language of languages) { - entryPoints.push(`src/basic-languages/${language}/${language}.contribution.ts`); - entryPoints.push(`src/basic-languages/${language}/${language}.ts`); - external.push(`*/${language}.contribution`); - external.push(`*/${language}`); - } - buildESM({ - base: 'basic-languages', - entryPoints, - external - }); - } -}); - -//#endregion diff --git a/build/build-monaco-editor.ts b/build/build-monaco-editor.ts index 4471478d..2d718f28 100644 --- a/build/build-monaco-editor.ts +++ b/build/build-monaco-editor.ts @@ -5,31 +5,18 @@ import path = require('path'); import fs = require('fs'); -import { - REPO_ROOT, - readFiles, - writeFiles, - IFile, - readFile, - build, - bundledFileHeader -} from '../build/utils'; -import { removeDir } from '../build/fs'; -import { generateMetadata } from './releaseMetadata'; +import { REPO_ROOT, readFiles, writeFiles } from '../build/utils'; +import { generateEsmMetadataJsAndDTs } from './releaseMetadata'; +import { buildESM } from './esm/build.script'; +import { removeDir } from './fs'; import { buildAmdMinDev } from './amd/build.script'; -import ts = require('typescript'); async function run() { removeDir(`out/monaco-editor`); + await buildESM(); await buildAmdMinDev(); - // esm folder - ESM_release(); - - // monaco.d.ts, editor.api.d.ts - releaseDTS(); - // copy types.d.ts from build/amd/out/ to out/monaco-editor/monaco.d.ts (and append `declare global { export import monaco = editor_main; }`) (() => { let contents = fs.readFileSync('build/amd/out/types.d.ts', { encoding: 'utf8' }); @@ -37,11 +24,8 @@ async function run() { fs.writeFileSync('out/monaco-editor/monaco.d.ts', contents); })(); - // ThirdPartyNotices.txt - releaseThirdPartyNotices(); - - // esm/metadata.d.ts, esm/metadata.js - generateMetadata(); + createThirdPartyNoticesDotTxt(); + generateEsmMetadataJsAndDTs(); // package.json (() => { @@ -71,281 +55,11 @@ async function run() { })(); } -function ESM_release() { - const coreFiles = readFiles(`node_modules/monaco-editor-core/esm/**/*`, { - base: 'node_modules/monaco-editor-core/esm', - // we will create our own editor.api.d.ts which also contains the plugins API - ignore: ['node_modules/monaco-editor-core/esm/vs/editor/editor.api.d.ts'] - }); - ESM_addImportSuffix(coreFiles); - ESM_addPluginContribs(coreFiles); - writeFiles(coreFiles, `out/monaco-editor/esm`); - - ESM_releasePlugins(); - - build({ - entryPoints: ['src/editor/editor.main.ts', 'src/editor/editor.worker.ts'], - bundle: true, - target: 'esnext', - format: 'esm', - drop: ['debugger'], - banner: { - js: bundledFileHeader - }, - external: ['./src/basic-languages/*', './edcore.main.js', './editor.worker.start'], - alias: { - 'monaco-editor-core/esm/vs/editor/editor.worker.start': './editor.worker.start', - 'monaco-editor-core': './edcore.main.js' - }, - outbase: `src/`, - outdir: `out/monaco-editor/esm/vs/`, - plugins: [ - { - name: 'example', - setup(build) { - build.onResolve({ filter: /\/language\/|\/basic-languages\// }, (args) => { - if (args.path.includes('monaco-editor-core')) { - return undefined; - } - return { external: true }; - }); - } - } - ] - }); -} - -/** - * Release a plugin to `esm`. - * Adds a dependency to 'vs/editor/editor.api' in contrib files in order for `monaco` to be defined. - * Rewrites imports for 'monaco-editor-core/**' - */ -function ESM_releasePlugins() { - const files = readFiles(`out/languages/bundled/esm/**/*`, { base: 'out/languages/bundled/esm/' }); - - for (const file of files) { - if (!/(\.js$)|(\.ts$)/.test(file.path)) { - continue; - } - - let contents = file.contents.toString(); - - // replace all `from "monaco-editor-core"` with from relativePath - let relativePath = path - .relative(path.dirname(file.path), 'vs/editor/editor.api') - .replace(/\\/g, '/'); - - contents = contents.replace( - /from "monaco-editor-core"/g, - `from ${JSON.stringify(relativePath)}` - ); - - file.contents = Buffer.from(contents); - } - - for (const file of files) { - if (!/monaco\.contribution\.js$/.test(file.path)) { - continue; - } - - const apiFilePath = 'vs/editor/editor.api'; - let relativePath = path.relative(path.dirname(file.path), apiFilePath).replace(/\\/g, '/'); - if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { - relativePath = './' + relativePath; - } - - let contents = file.contents.toString(); - contents = `import '${relativePath}';\n` + contents; - file.contents = Buffer.from(contents); - } - - ESM_addImportSuffix(files); - writeFiles(files, `out/monaco-editor/esm`); -} - -/** - * Adds `.js` to all import statements. - */ -function ESM_addImportSuffix(files: IFile[]) { - for (const file of files) { - if (!/\.js$/.test(file.path)) { - continue; - } - - let contents = file.contents.toString(); - - const info = ts.preProcessFile(contents); - for (let i = info.importedFiles.length - 1; i >= 0; i--) { - const importText = info.importedFiles[i].fileName; - const pos = info.importedFiles[i].pos; - const end = info.importedFiles[i].end; - - if (/(\.css)|(\.js)$/.test(importText)) { - // A CSS import or an import already using .js - continue; - } - - contents = contents.substring(0, pos + 1) + importText + '.js' + contents.substring(end + 1); - } - - file.contents = Buffer.from(contents); - } -} - -/** - * - Rename esm/vs/editor/editor.main.js to esm/vs/editor/edcore.main.js - * - Create esm/vs/editor/editor.main.js that that stiches things together - */ -function ESM_addPluginContribs(files: IFile[]) { - for (const file of files) { - if (!/editor\.main\.js$/.test(file.path)) { - continue; - } - file.path = file.path.replace(/editor\.main/, 'edcore.main'); - } -} - -/** - * Edit monaco.d.ts: - * - append monaco.d.ts from plugins - */ -function releaseDTS() { - const monacodts = readFiles('node_modules/monaco-editor-core/monaco.d.ts', { - base: 'node_modules/monaco-editor-core' - })[0]; - - let contents = monacodts.contents.toString(); - - const additionalDtsFiles: Record = { - 'out/languages/tsc/common/workers.d.ts': 'monaco.editor' - }; - Object.entries(additionalDtsFiles).forEach(([filePath, namespace]) => { - try { - const dtsFile = readFile(filePath); - let dtsContent = dtsFile.contents.toString(); - - // Remove imports - dtsContent = dtsContent.replace(/import .*\n/gm, ''); - dtsContent = dtsContent.replace(/export declare function/gm, 'export function'); - - // Wrap in namespace if specified - if (namespace) { - dtsContent = `declare namespace ${namespace} {\n${dtsContent - .split('\n') - .map((line) => (line ? ` ${line}` : line)) - .join('\n')}\n}`; - } - - contents += '\n' + dtsContent; - } catch (error) { - console.warn(`Could not read d.ts file: ${filePath}`); - } - }); - - const extraContent = readFiles('out/languages/bundled/*.d.ts', { - base: 'out/languages/bundled/' - }).map((file) => { - return file.contents.toString().replace(/\/\/\/ ; +export type PostCssCompatible = { + process: (css: string, opt: { + from: string; + to: string; + map: { + prev: string; + inline: boolean; + } | null; + }) => string | { + css: string; + map?: string; + }; +}; +export interface CompilationOptions { + outputExt: string; + sass?: SassAsyncCompiler; + postProcessor?: (css: string, map: string) => Promise; + loadPaths?: string[]; + sourceMap?: boolean; + sassOptions: Options<"async">; +} +export declare const compileSass: (sassPath: string, outWatchList: string[] | undefined, { outputExt, sass, postProcessor, loadPaths, sourceMap, sassOptions }: CompilationOptions) => Promise<{ + css: string; + map: string; +}>; +export {}; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/constants.d.ts b/build/esm/rollup-plugin-keep-css-imports/dist/constants.d.ts new file mode 100644 index 00000000..b9f48378 --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/constants.d.ts @@ -0,0 +1,3 @@ +export declare const PLUGIN_NAME = "keep-css-imports"; +export declare const FILE_URL_PREFIX: string; +export declare const KEY_EXT_STRING = ".[keep-css-imports-plugin-ext]"; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/helpers.d.ts b/build/esm/rollup-plugin-keep-css-imports/dist/helpers.d.ts new file mode 100644 index 00000000..0ab4c3ec --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/helpers.d.ts @@ -0,0 +1,52 @@ +import { EmitFile } from "rollup"; +import { StylesMap } from "./types"; +export declare const escapeRegex: (val: any) => any; +export declare const assertDuplicates: (stylesToEmit: StylesMap) => void; +export declare const assertLocation: (outDir: any, assetPath: any) => void; +export declare const ensureSourceMap: ({ css, map }: { + css?: string | Uint8Array; + map?: string | Uint8Array; +}, includeSourceMap: boolean | "inline" | undefined, fileName: string, onEmit: EmitFile) => string | Uint8Array; +export declare const formatProcessedToCSS: (input: string | { + css: string; + map?: string | object; +}, sourceMap: boolean) => { + css: string; + map: string; +}; +export declare const requireSass: () => Promise<{ + default: typeof import("sass"); + AsyncCompiler: typeof import("sass").AsyncCompiler; + Compiler: typeof import("sass").Compiler; + compile: typeof import("sass").compile; + compileAsync: typeof import("sass").compileAsync; + compileString: typeof import("sass").compileString; + compileStringAsync: typeof import("sass").compileStringAsync; + initCompiler: typeof import("sass").initCompiler; + initAsyncCompiler: typeof import("sass").initAsyncCompiler; + Exception: typeof import("sass").Exception; + Logger: typeof import("sass").Logger; + CalculationInterpolation: typeof import("sass").CalculationInterpolation; + CalculationOperation: typeof import("sass").CalculationOperation; + SassArgumentList: typeof import("sass").SassArgumentList; + SassBoolean: typeof import("sass").SassBoolean; + SassCalculation: typeof import("sass").SassCalculation; + SassColor: typeof import("sass").SassColor; + SassFunction: typeof import("sass").SassFunction; + SassList: typeof import("sass").SassList; + SassMap: typeof import("sass").SassMap; + SassMixin: typeof import("sass").SassMixin; + SassNumber: typeof import("sass").SassNumber; + SassString: typeof import("sass").SassString; + Value: typeof import("sass").Value; + sassFalse: import("sass").SassBoolean; + sassNull: import("sass").Value; + sassTrue: import("sass").SassBoolean; + FALSE: import("sass").types.Boolean; + NULL: import("sass").types.Null; + TRUE: import("sass").types.Boolean; + types: typeof import("sass").types; + render: typeof import("sass").render; + renderSync: typeof import("sass").renderSync; + info: string; +}>; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/index.d.ts b/build/esm/rollup-plugin-keep-css-imports/dist/index.d.ts new file mode 100644 index 00000000..0b911594 --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/index.d.ts @@ -0,0 +1,4 @@ +import type { Plugin } from "rollup"; +import { KeepCssImportsOptions } from "./types"; +declare function keepCssImports({ outputExt, outputPath, skipCurrentFolderPart, includeRegexp, sass, postProcessor, sassOptions, ...options }?: KeepCssImportsOptions): Plugin; +export default keepCssImports; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/index.mjs b/build/esm/rollup-plugin-keep-css-imports/dist/index.mjs new file mode 100644 index 00000000..fc3714c7 --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/index.mjs @@ -0,0 +1,487 @@ +import { readFile } from 'fs/promises'; +import * as path from 'path'; +import MagicString from 'magic-string'; + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol */ + + +var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +var escapeRegex = function (val) { return val.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&"); }; +var assertDuplicates = function (stylesToEmit) { + Object.values(stylesToEmit).forEach(function (v, i, all) { + if (all.some(function (av, ai) { return !!v.output && v.output === av.output && ai != i; })) { + throw new Error("Two or more assets have conflicting output path ".concat(v.output)); + } + }); +}; +var assertLocation = function (outDir, assetPath) { + if (!path.normalize(assetPath).startsWith(path.normalize(outDir))) { + throw new Error("Output path ".concat(assetPath, " must be in output directory ").concat(outDir)); + } +}; +var ensureSourceMap = function (_a, includeSourceMap, fileName, onEmit) { + var css = _a.css, map = _a.map; + if (map) { + if (includeSourceMap === "inline") { + css += "\n/*# sourceMappingURL=data:application/json;base64,".concat((map instanceof Uint8Array ? Buffer.from(map) : Buffer.from(map, "utf8")).toString("base64"), "*/"); + } + else if (includeSourceMap === true) { + css += "\n/*# sourceMappingURL=".concat(path.basename(fileName), ".map */"); + } + if (includeSourceMap === true) { + onEmit({ + type: "asset", + fileName: fileName + ".map", + source: map, + }); + } + } + return css; +}; +var formatProcessedToCSS = function (input, sourceMap) { + return typeof input === "string" + ? { css: input, map: "" } + : typeof input === "object" + ? { + css: input.css, + map: !sourceMap ? "" : typeof input.map === "object" ? JSON.stringify(input.map) : input.map, + } + : input; +}; +var requireSass = function () { + try { + return import('sass'); + } + catch (e) { + throw new Error("You have to install `sass` package! Try running\n\t" + + "npm install --save-dev sass\nor\nyarn add sass --dev\n" + + "or use `sass` option to pass processor"); + } +}; + +function ensureCompiler(sass) { + return __awaiter(this, void 0, void 0, function () { + var sassProcessor, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _a = sass; + if (_a) return [3 /*break*/, 2]; + return [4 /*yield*/, requireSass()]; + case 1: + _a = (_b.sent()); + _b.label = 2; + case 2: + sassProcessor = _a; + if (!("compileAsync" in sassProcessor)) { + throw new Error("You have to install `sass` package! Or provide an object which implements `compileAsync` as `sass` option"); + } + return [2 /*return*/, sassProcessor]; + } + }); + }); +} +var isPostCssCompatible = function (result) { + return result && typeof result === "object" && "process" in result && typeof result.process === "function"; +}; +var compileSass = function (sassPath, outWatchList, _a) { + var outputExt = _a.outputExt, sass = _a.sass, postProcessor = _a.postProcessor, loadPaths = _a.loadPaths, sourceMap = _a.sourceMap, sassOptions = _a.sassOptions; + return __awaiter(void 0, void 0, void 0, function () { + var sassProcessor, watchListNeeded, compiled, css, mapObject, sources, map, result, _b, _c; + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + if (!sassPath) { + return [2 /*return*/, { css: "", map: "" }]; + } + return [4 /*yield*/, ensureCompiler(sass)]; + case 1: + sassProcessor = _d.sent(); + watchListNeeded = Array.isArray(outWatchList); + return [4 /*yield*/, sassProcessor.compileAsync(sassPath, __assign({ loadPaths: loadPaths, style: "expanded", sourceMap: !!sourceMap || watchListNeeded, sourceMapIncludeSources: !!sourceMap || watchListNeeded }, (sassOptions || [])))]; + case 2: + compiled = _d.sent(); + css = compiled.css.toString(); + if (watchListNeeded && compiled.sourceMap && typeof compiled.sourceMap === "object") { + mapObject = "toJSON" in compiled.sourceMap && typeof compiled.sourceMap.toJSON === "function" + ? compiled.sourceMap.toJSON() + : compiled.sourceMap; + sources = mapObject.sources || mapObject._sources; + outWatchList.push.apply(outWatchList, sources.filter(function (s) { return s && typeof s === "string"; })); + } + map = compiled.sourceMap + ? typeof compiled.sourceMap === "object" + ? JSON.stringify(compiled.sourceMap) + : compiled.sourceMap + : ""; + if (!(typeof postProcessor === "function")) return [3 /*break*/, 7]; + return [4 /*yield*/, postProcessor(css, map)]; + case 3: + result = _d.sent(); + if ((typeof result !== "string" && typeof result !== "object") || result === null) { + throw new Error("`postProcessor` must return string, object with `css` and `map` or PostCSS like object which implements `process` function"); + } + _b = formatProcessedToCSS; + if (!isPostCssCompatible(result) // If PostCSS compatible result + ) return [3 /*break*/, 5]; // If PostCSS compatible result + return [4 /*yield*/, Promise.resolve(result.process(css, { + from: sassPath, + to: path.parse(sassPath).name + outputExt, + map: map ? { prev: map, inline: false } : null, + }))]; + case 4: + _c = _d.sent(); + return [3 /*break*/, 6]; + case 5: + _c = result; + _d.label = 6; + case 6: return [2 /*return*/, _b.apply(void 0, [_c, sourceMap])]; + case 7: return [2 /*return*/, { css: css, map: sourceMap ? map : undefined }]; + } + }); + }); +}; + +var PLUGIN_NAME = "keep-css-imports"; +var FILE_URL_PREFIX = new URL("file://").toString(); +var KEY_EXT_STRING = ".[keep-css-imports-plugin-ext]"; + +var createErrorMessage = function (message) { return "[".concat(PLUGIN_NAME, "] ").concat(message); }; +var ImportUpdater = /** @class */ (function () { + function ImportUpdater(pluginContext, outputOptions) { + var _this = this; + this.addImportAndGetNewId = function (resolvedId) { + var moduleIndex = _this._pluginContext.allStyleImports.indexOf(resolvedId); + return !~moduleIndex ? _this._pluginContext.allStyleImports.push(resolvedId) - 1 : moduleIndex; + }; + this._pluginContext = pluginContext; + this._outputOptions = outputOptions; + } + ImportUpdater.prototype.getMagicId = function (id) { + return "\0" + this.addImportAndGetNewId(id) + KEY_EXT_STRING; + }; + ImportUpdater.prototype.updateImports = function (code, chunk, bundleOutDir, moduleRoot) { + var _this = this; + var magicString = new MagicString(code); + var matchRegex = new RegExp("\0([^\"']+)".concat(escapeRegex(KEY_EXT_STRING)), "g"); + Array.from(code.matchAll(matchRegex)) + .reverse() + .forEach(function (m) { + return _this.updateMatchedImport(m, magicString, { + chunk: chunk, + bundleOutDir: bundleOutDir, + moduleRoot: moduleRoot, + }); + }); + return { + code: magicString.toString(), + map: magicString.generateMap({ hires: true }), + }; + }; + ImportUpdater.prototype.updateMatchedImport = function (m, magicString, chunkDetails) { + var importId = m[0]; + var assetId = this._pluginContext.allStyleImports[m[1]]; + if (!assetId || typeof assetId !== "string" || !this._pluginContext.stylesToEmit[assetId]) { + return; + } + var updatedImport = this.saveAndGetUpdatedImportPath(assetId, chunkDetails); + var start = m.index; + var end = start + importId.length; + magicString.overwrite(start, end, updatedImport); + this.updateChunk(importId, updatedImport, chunkDetails.chunk); + }; + ImportUpdater.prototype.updateChunk = function (importId, updatedImport, chunk) { + if (chunk.importedBindings[importId]) { + chunk.importedBindings[updatedImport] = chunk.importedBindings[importId]; + if (updatedImport !== importId) { + delete chunk.importedBindings[importId]; + } + } + var importIndex = chunk.imports.indexOf(importId); + if (~importIndex) { + chunk.imports[importIndex] = updatedImport; + } + }; + ImportUpdater.prototype.saveAndGetUpdatedImportPath = function (assetId, _a) { + var bundleOutDir = _a.bundleOutDir, moduleRoot = _a.moduleRoot, chunk = _a.chunk; + var assetOutput = this.resolveOutputPath(bundleOutDir, assetId, moduleRoot); + var updatedImport = path + .relative(path.dirname(path.resolve(bundleOutDir, chunk.fileName)), assetOutput) + .replace(/\\/g, "/"); + this._pluginContext.stylesToEmit[assetId].output = path.relative(path.resolve(bundleOutDir), assetOutput); + if (this.shouldAddPrefixCurrentDir(updatedImport) && + !updatedImport.startsWith("./") && + !updatedImport.startsWith("../") && + !updatedImport.match(/^[a-zA-Z]:/)) { + updatedImport = "./" + updatedImport; + } + return updatedImport; + }; + ImportUpdater.prototype.shouldAddPrefixCurrentDir = function (updatedImport) { + var skip = this._outputOptions.skipCurrentFolderPart; + return !skip || (skip instanceof RegExp && !skip.test(updatedImport)); + }; + ImportUpdater.prototype.resolveOutputPath = function (bundleOutDir, assetId, moduleRoot) { + var _a = this._outputOptions, outputPath = _a.outputPath, outputDir = _a.outputDir, outputExt = _a.outputExt; + var newPath = undefined; + if (typeof outputPath === "function") { + newPath = outputPath(assetId); + assertLocation(bundleOutDir, newPath); + } + else if (typeof outputPath === "string") { + newPath = path.resolve(bundleOutDir, outputDir, outputPath !== "keep" ? outputPath : path.relative(moduleRoot, assetId)); + assertLocation(bundleOutDir, newPath); + } + else { + throw new Error(createErrorMessage("Invalid outputPath option value!")); + } + return newPath.replace(/\.s[ca]ss$/, outputExt); + }; + return ImportUpdater; +}()); + +var ensureStylesInfo = function (stylesMap, importer, resolvedId) { + stylesMap[resolvedId] = stylesMap[resolvedId] || { importers: [], watchList: [] }; + stylesMap[resolvedId].importers.push(importer); + return stylesMap[resolvedId]; +}; +var ensureCodeAndWatchList = function (filePath, stylesInfo, isWatch, compilerOptions) { + return __awaiter(void 0, void 0, void 0, function () { + var outWatchList, _a, _b, css, map; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + outWatchList = []; + if (!filePath.endsWith(".css")) return [3 /*break*/, 2]; + _a = stylesInfo; + return [4 /*yield*/, readFile(filePath, "utf8")]; + case 1: + _a.css = _c.sent(); + return [3 /*break*/, 4]; + case 2: return [4 /*yield*/, compileSass(filePath, isWatch ? outWatchList : undefined, compilerOptions)]; + case 3: + _b = _c.sent(), css = _b.css, map = _b.map; + stylesInfo.css = css; + stylesInfo.map = map; + _c.label = 4; + case 4: + outWatchList.push(filePath); + stylesInfo.watchList = outWatchList.map(function (watchFile) { return path.resolve(watchFile.replace(FILE_URL_PREFIX, "")); }); + return [2 /*return*/]; + } + }); + }); +}; +function keepCssImports(_a) { + if (_a === void 0) { _a = {}; } + var _b = _a.outputExt, outputExt = _b === void 0 ? ".css" : _b, _c = _a.outputPath, outputPath = _c === void 0 ? "keep" : _c, _d = _a.skipCurrentFolderPart, skipCurrentFolderPart = _d === void 0 ? false : _d, _e = _a.includeRegexp, includeRegexp = _e === void 0 ? /\.(?:s[ca]|c)ss$/ : _e, sass = _a.sass, postProcessor = _a.postProcessor, sassOptions = _a.sassOptions, options = __rest(_a, ["outputExt", "outputPath", "skipCurrentFolderPart", "includeRegexp", "sass", "postProcessor", "sassOptions"]); + var stylesOutputOptions = { + outputPath: outputPath, + outputExt: outputExt, + outputDir: options.outputDir ? path.resolve(options.outputDir) : "./", + skipCurrentFolderPart: skipCurrentFolderPart, + }; + var context = { + allStyleImports: [], + modulesWithCss: new Set(), + stylesToEmit: {}, + }; + var importUpdater = new ImportUpdater(context, stylesOutputOptions); + var loadPaths = options.includePaths || ["node_modules/"]; + loadPaths.push(process.cwd()); + loadPaths = loadPaths.filter(function (v, i, a) { return a.indexOf(v) === i; }); + var compilerOptions = { + outputExt: outputExt, + sass: sass, + postProcessor: typeof postProcessor === "function" + ? function (css, map) { return postProcessor(css, map, context.stylesToEmit); } + : undefined, + loadPaths: loadPaths, + sourceMap: !!options.sourceMap, + sassOptions: sassOptions, + }; + return { + name: PLUGIN_NAME, + resolveId: function (source, importer, resolveOptions) { + return __awaiter(this, void 0, void 0, function () { + var _a, custom, _b, _c, _d, _e, _f, alreadyResolving, resolved, styleInfo; + var _g, _h; + var _this = this; + return __generator(this, function (_j) { + switch (_j.label) { + case 0: + if (!importer || !includeRegexp.test(source) || /\0/.test(source)) { + return [2 /*return*/, null]; + } + _a = resolveOptions.custom, custom = _a === void 0 ? {} : _a; + _b = custom, _c = PLUGIN_NAME, _d = _b[_c], _e = _d === void 0 ? {} : _d, _f = _e.resolving, alreadyResolving = _f === void 0 ? false : _f; + if (alreadyResolving) { + return [2 /*return*/, null]; + } + return [4 /*yield*/, this.resolve(source, importer, __assign(__assign({ skipSelf: true }, resolveOptions), { custom: __assign(__assign({}, custom), (_g = {}, _g[PLUGIN_NAME] = __assign(__assign({}, custom[PLUGIN_NAME]), { resolving: true }), _g)) }))]; + case 1: + resolved = _j.sent(); + if (!resolved || resolved.external) { + return [2 /*return*/, resolved]; + } + context.modulesWithCss.add(importer); + styleInfo = ensureStylesInfo(context.stylesToEmit, importer, resolved.id); + return [4 /*yield*/, ensureCodeAndWatchList(resolved.id, styleInfo, this.meta.watchMode, compilerOptions)]; + case 2: + _j.sent(); + styleInfo.watchList.forEach(function (watchFile) { + _this.addWatchFile(watchFile); + }); + return [2 /*return*/, { + id: importUpdater.getMagicId(resolved.id), + meta: (_h = {}, _h[PLUGIN_NAME] = { sourceId: resolved.id }, _h), + external: true, + }]; + } + }); + }); + }, + buildStart: function () { + var _this = this; + // Every rebuild will refresh watcher, so we need to reattach + if (this.meta.watchMode) { + var allWatched_1 = this.getWatchFiles(); + Object.values(context.stylesToEmit).forEach(function (styleInfo) { + return styleInfo.watchList.forEach(function (watchFile) { + if (!allWatched_1.find(function (watched) { return path.normalize(watched) === path.normalize(watchFile); })) { + _this.addWatchFile(watchFile); + } + }); + }); + } + }, + watchChange: function (id) { + return __awaiter(this, void 0, void 0, function () { + var resolvedId, filesToUpdate; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + resolvedId = path.resolve(id); + filesToUpdate = Object.entries(context.stylesToEmit).filter(function (_a) { + var styleInfo = _a[1]; + return styleInfo.watchList.includes(resolvedId); + }); + return [4 /*yield*/, Promise.all(filesToUpdate.map(function (_a) { + var fileName = _a[0], styleInfo = _a[1]; + return ensureCodeAndWatchList(fileName, styleInfo, _this.meta.watchMode, compilerOptions); + }))]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }, + renderChunk: function (code, chunk, outputOptions) { + var bundleOutDir = path.resolve(outputOptions.dir || path.dirname(outputOptions.file)); + // Always do it, otherwise some modules are missed + var moduleRoot = outputOptions.preserveModulesRoot || process.cwd(); + return importUpdater.updateImports(code, chunk, bundleOutDir, moduleRoot); + }, + generateBundle: function (_, __, isWrite) { + if (!isWrite) { + return; + } + assertDuplicates(context.stylesToEmit); + for (var file in context.stylesToEmit) { + var stylesInfo = context.stylesToEmit[file]; + var fileName = stylesInfo.output; + var source = file.endsWith(".css") + ? stylesInfo.css + : ensureSourceMap(stylesInfo, options.sourceMap || (sassOptions === null || sassOptions === void 0 ? void 0 : sassOptions.sourceMap), fileName, this.emitFile); + this.emitFile({ + type: "asset", + fileName: fileName, + source: source, + }); + } + }, + }; +} + +export { keepCssImports as default }; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/index.original.mjs b/build/esm/rollup-plugin-keep-css-imports/dist/index.original.mjs new file mode 100644 index 00000000..26a1ce76 --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/index.original.mjs @@ -0,0 +1,489 @@ +import { readFile } from 'fs/promises'; +import * as path from 'path'; +import MagicString from 'magic-string'; + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol */ + + +var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +} + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +var escapeRegex = function (val) { return val.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&"); }; +var assertDuplicates = function (stylesToEmit) { + Object.values(stylesToEmit).forEach(function (v, i, all) { + if (all.some(function (av, ai) { return !!v.output && v.output === av.output && ai != i; })) { + throw new Error("Two or more assets have conflicting output path ".concat(v.output)); + } + }); +}; +var assertLocation = function (outDir, assetPath) { + if (!path.normalize(assetPath).startsWith(path.normalize(outDir))) { + throw new Error("Output path ".concat(assetPath, " must be in output directory ").concat(outDir)); + } +}; +var ensureSourceMap = function (_a, includeSourceMap, fileName, onEmit) { + var css = _a.css, map = _a.map; + if (map) { + if (includeSourceMap === "inline") { + css += "\n/*# sourceMappingURL=data:application/json;base64,".concat((map instanceof Uint8Array ? Buffer.from(map) : Buffer.from(map, "utf8")).toString("base64"), "*/"); + } + else if (includeSourceMap === true) { + css += "\n/*# sourceMappingURL=".concat(path.basename(fileName), ".map */"); + } + if (includeSourceMap === true) { + onEmit({ + type: "asset", + fileName: fileName + ".map", + source: map, + }); + } + } + return css; +}; +var formatProcessedToCSS = function (input, sourceMap) { + return typeof input === "string" + ? { css: input, map: "" } + : typeof input === "object" + ? { + css: input.css, + map: !sourceMap ? "" : typeof input.map === "object" ? JSON.stringify(input.map) : input.map, + } + : input; +}; +var requireSass = function () { + try { + return import('sass'); + } + catch (e) { + throw new Error("You have to install `sass` package! Try running\n\t" + + "npm install --save-dev sass\nor\nyarn add sass --dev\n" + + "or use `sass` option to pass processor"); + } +}; + +function ensureCompiler(sass) { + return __awaiter(this, void 0, void 0, function () { + var sassProcessor, _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + _a = sass; + if (_a) return [3 /*break*/, 2]; + return [4 /*yield*/, requireSass()]; + case 1: + _a = (_b.sent()); + _b.label = 2; + case 2: + sassProcessor = _a; + if (!("compileAsync" in sassProcessor)) { + throw new Error("You have to install `sass` package! Or provide an object which implements `compileAsync` as `sass` option"); + } + return [2 /*return*/, sassProcessor]; + } + }); + }); +} +var isPostCssCompatible = function (result) { + return result && typeof result === "object" && "process" in result && typeof result.process === "function"; +}; +var compileSass = function (sassPath, outWatchList, _a) { + var outputExt = _a.outputExt, sass = _a.sass, postProcessor = _a.postProcessor, loadPaths = _a.loadPaths, sourceMap = _a.sourceMap, sassOptions = _a.sassOptions; + return __awaiter(void 0, void 0, void 0, function () { + var sassProcessor, watchListNeeded, compiled, css, mapObject, sources, map, result, _b, _c; + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + if (!sassPath) { + return [2 /*return*/, { css: "", map: "" }]; + } + return [4 /*yield*/, ensureCompiler(sass)]; + case 1: + sassProcessor = _d.sent(); + watchListNeeded = Array.isArray(outWatchList); + return [4 /*yield*/, sassProcessor.compileAsync(sassPath, __assign({ loadPaths: loadPaths, style: "expanded", sourceMap: !!sourceMap || watchListNeeded, sourceMapIncludeSources: !!sourceMap || watchListNeeded }, (sassOptions || [])))]; + case 2: + compiled = _d.sent(); + css = compiled.css.toString(); + if (watchListNeeded && compiled.sourceMap && typeof compiled.sourceMap === "object") { + mapObject = "toJSON" in compiled.sourceMap && typeof compiled.sourceMap.toJSON === "function" + ? compiled.sourceMap.toJSON() + : compiled.sourceMap; + sources = mapObject.sources || mapObject._sources; + outWatchList.push.apply(outWatchList, sources.filter(function (s) { return s && typeof s === "string"; })); + } + map = compiled.sourceMap + ? typeof compiled.sourceMap === "object" + ? JSON.stringify(compiled.sourceMap) + : compiled.sourceMap + : ""; + if (!(typeof postProcessor === "function")) return [3 /*break*/, 7]; + return [4 /*yield*/, postProcessor(css, map)]; + case 3: + result = _d.sent(); + if ((typeof result !== "string" && typeof result !== "object") || result === null) { + throw new Error("`postProcessor` must return string, object with `css` and `map` or PostCSS like object which implements `process` function"); + } + _b = formatProcessedToCSS; + if (!isPostCssCompatible(result) // If PostCSS compatible result + ) return [3 /*break*/, 5]; // If PostCSS compatible result + return [4 /*yield*/, Promise.resolve(result.process(css, { + from: sassPath, + to: path.parse(sassPath).name + outputExt, + map: map ? { prev: map, inline: false } : null, + }))]; + case 4: + _c = _d.sent(); + return [3 /*break*/, 6]; + case 5: + _c = result; + _d.label = 6; + case 6: return [2 /*return*/, _b.apply(void 0, [_c, sourceMap])]; + case 7: return [2 /*return*/, { css: css, map: sourceMap ? map : undefined }]; + } + }); + }); +}; + +var PLUGIN_NAME = "keep-css-imports"; +var FILE_URL_PREFIX = new URL("file://").toString(); +var KEY_EXT_STRING = ".[keep-css-imports-plugin-ext]"; + +var createErrorMessage = function (message) { return "[".concat(PLUGIN_NAME, "] ").concat(message); }; +var ImportUpdater = /** @class */ (function () { + function ImportUpdater(pluginContext, outputOptions) { + var _this = this; + this.addImportAndGetNewId = function (resolvedId) { + var moduleIndex = _this._pluginContext.allStyleImports.indexOf(resolvedId); + return !~moduleIndex ? _this._pluginContext.allStyleImports.push(resolvedId) - 1 : moduleIndex; + }; + this._pluginContext = pluginContext; + this._outputOptions = outputOptions; + } + ImportUpdater.prototype.getMagicId = function (id) { + return "\0" + this.addImportAndGetNewId(id) + KEY_EXT_STRING; + }; + ImportUpdater.prototype.updateImports = function (code, chunk, bundleOutDir, moduleRoot) { + var _this = this; + var magicString = new MagicString(code); + var matchRegex = new RegExp("\0([^\"']+)".concat(escapeRegex(KEY_EXT_STRING)), "g"); + Array.from(code.matchAll(matchRegex)) + .reverse() + .forEach(function (m) { + return _this.updateMatchedImport(m, magicString, { + chunk: chunk, + bundleOutDir: bundleOutDir, + moduleRoot: moduleRoot, + }); + }); + return { + code: magicString.toString(), + map: magicString.generateMap({ hires: true }), + }; + }; + ImportUpdater.prototype.updateMatchedImport = function (m, magicString, chunkDetails) { + var importId = m[0]; + var assetId = this._pluginContext.allStyleImports[m[1]]; + if (!assetId || typeof assetId !== "string" || !this._pluginContext.stylesToEmit[assetId]) { + return; + } + var updatedImport = this.saveAndGetUpdatedImportPath(assetId, chunkDetails); + var start = m.index; + var end = start + importId.length; + magicString.overwrite(start, end, updatedImport); + this.updateChunk(importId, updatedImport, chunkDetails.chunk); + }; + ImportUpdater.prototype.updateChunk = function (importId, updatedImport, chunk) { + if (chunk.importedBindings[importId]) { + chunk.importedBindings[updatedImport] = chunk.importedBindings[importId]; + if (updatedImport !== importId) { + delete chunk.importedBindings[importId]; + } + } + var importIndex = chunk.imports.indexOf(importId); + if (~importIndex) { + chunk.imports[importIndex] = updatedImport; + } + }; + ImportUpdater.prototype.saveAndGetUpdatedImportPath = function (assetId, _a) { + var bundleOutDir = _a.bundleOutDir, moduleRoot = _a.moduleRoot, chunk = _a.chunk; + var assetOutput = this.resolveOutputPath(bundleOutDir, assetId, moduleRoot); + var updatedImport = path + .relative(path.dirname(path.resolve(bundleOutDir, chunk.fileName)), assetOutput) + .replace(/\\/g, "/"); + this._pluginContext.stylesToEmit[assetId].output = path.relative(path.resolve(bundleOutDir), assetOutput); + if (this.shouldAddPrefixCurrentDir(updatedImport) && + !updatedImport.startsWith("./") && + !updatedImport.startsWith("../") && + !updatedImport.match(/^[a-zA-Z]:/)) { + updatedImport = "./" + updatedImport; + } + return updatedImport; + }; + ImportUpdater.prototype.shouldAddPrefixCurrentDir = function (updatedImport) { + var skip = this._outputOptions.skipCurrentFolderPart; + return !skip || (skip instanceof RegExp && !skip.test(updatedImport)); + }; + ImportUpdater.prototype.resolveOutputPath = function (bundleOutDir, assetId, moduleRoot) { + var _a = this._outputOptions, outputPath = _a.outputPath, outputDir = _a.outputDir, outputExt = _a.outputExt; + var newPath = undefined; + if (typeof outputPath === "function") { + newPath = outputPath(assetId); + assertLocation(bundleOutDir, newPath); + } + else if (typeof outputPath === "string") { + newPath = path.resolve(bundleOutDir, outputDir, outputPath !== "keep" ? outputPath : path.relative(moduleRoot, assetId)); + assertLocation(bundleOutDir, newPath); + } + else { + throw new Error(createErrorMessage("Invalid outputPath option value!")); + } + return newPath.replace(/\.s[ca]ss$/, outputExt); + }; + return ImportUpdater; +}()); + +var ensureStylesInfo = function (stylesMap, importer, resolvedId) { + stylesMap[resolvedId] = stylesMap[resolvedId] || { importers: [], watchList: [] }; + stylesMap[resolvedId].importers.push(importer); + return stylesMap[resolvedId]; +}; +var ensureCodeAndWatchList = function (filePath, stylesInfo, isWatch, compilerOptions) { + return __awaiter(void 0, void 0, void 0, function () { + var outWatchList, _a, _b, css, map; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + outWatchList = []; + if (!filePath.endsWith(".css")) return [3 /*break*/, 2]; + _a = stylesInfo; + return [4 /*yield*/, readFile(filePath, "utf8")]; + case 1: + _a.css = _c.sent(); + return [3 /*break*/, 4]; + case 2: return [4 /*yield*/, compileSass(filePath, isWatch ? outWatchList : undefined, compilerOptions)]; + case 3: + _b = _c.sent(), css = _b.css, map = _b.map; + stylesInfo.css = css; + stylesInfo.map = map; + _c.label = 4; + case 4: + outWatchList.push(filePath); + stylesInfo.watchList = outWatchList.map(function (watchFile) { return path.resolve(watchFile.replace(FILE_URL_PREFIX, "")); }); + return [2 /*return*/]; + } + }); + }); +}; +function keepCssImports(_a) { + if (_a === void 0) { _a = {}; } + var _b = _a.outputExt, outputExt = _b === void 0 ? ".css" : _b, _c = _a.outputPath, outputPath = _c === void 0 ? "keep" : _c, _d = _a.skipCurrentFolderPart, skipCurrentFolderPart = _d === void 0 ? false : _d, _e = _a.includeRegexp, includeRegexp = _e === void 0 ? /\.(?:s[ca]|c)ss$/ : _e, sass = _a.sass, postProcessor = _a.postProcessor, sassOptions = _a.sassOptions, options = __rest(_a, ["outputExt", "outputPath", "skipCurrentFolderPart", "includeRegexp", "sass", "postProcessor", "sassOptions"]); + var stylesOutputOptions = { + outputPath: outputPath, + outputExt: outputExt, + outputDir: options.outputDir ? path.resolve(options.outputDir) : "./", + skipCurrentFolderPart: skipCurrentFolderPart, + }; + var context = { + allStyleImports: [], + modulesWithCss: new Set(), + stylesToEmit: {}, + }; + var importUpdater = new ImportUpdater(context, stylesOutputOptions); + var loadPaths = options.includePaths || ["node_modules/"]; + loadPaths.push(process.cwd()); + loadPaths = loadPaths.filter(function (v, i, a) { return a.indexOf(v) === i; }); + var compilerOptions = { + outputExt: outputExt, + sass: sass, + postProcessor: typeof postProcessor === "function" + ? function (css, map) { return postProcessor(css, map, context.stylesToEmit); } + : undefined, + loadPaths: loadPaths, + sourceMap: !!options.sourceMap, + sassOptions: sassOptions, + }; + return { + name: PLUGIN_NAME, + resolveId: function (source, importer, resolveOptions) { + return __awaiter(this, void 0, void 0, function () { + var _a, custom, _b, _c, _d, _e, _f, alreadyResolving, resolved, styleInfo; + var _g, _h; + var _this = this; + return __generator(this, function (_j) { + switch (_j.label) { + case 0: + if (!importer || !includeRegexp.test(source) || /\0/.test(source)) { + return [2 /*return*/, null]; + } + _a = resolveOptions.custom, custom = _a === void 0 ? {} : _a; + _b = custom, _c = PLUGIN_NAME, _d = _b[_c], _e = _d === void 0 ? {} : _d, _f = _e.resolving, alreadyResolving = _f === void 0 ? false : _f; + if (alreadyResolving) { + return [2 /*return*/, null]; + } + return [4 /*yield*/, this.resolve(source, importer, __assign(__assign({ skipSelf: true }, resolveOptions), { custom: __assign(__assign({}, custom), (_g = {}, _g[PLUGIN_NAME] = __assign(__assign({}, custom[PLUGIN_NAME]), { resolving: true }), _g)) }))]; + case 1: + resolved = _j.sent(); + if (!resolved || resolved.external) { + return [2 /*return*/, resolved]; + } + context.modulesWithCss.add(importer); + styleInfo = ensureStylesInfo(context.stylesToEmit, importer, resolved.id); + return [4 /*yield*/, ensureCodeAndWatchList(resolved.id, styleInfo, this.meta.watchMode, compilerOptions)]; + case 2: + _j.sent(); + styleInfo.watchList.forEach(function (watchFile) { + _this.addWatchFile(watchFile); + }); + return [2 /*return*/, { + id: importUpdater.getMagicId(resolved.id), + meta: (_h = {}, _h[PLUGIN_NAME] = { sourceId: resolved.id }, _h), + external: true, + }]; + } + }); + }); + }, + buildStart: function () { + var _this = this; + // Every rebuild will refresh watcher, so we need to reattach + if (this.meta.watchMode) { + var allWatched_1 = this.getWatchFiles(); + Object.values(context.stylesToEmit).forEach(function (styleInfo) { + return styleInfo.watchList.forEach(function (watchFile) { + if (!allWatched_1.find(function (watched) { return path.normalize(watched) === path.normalize(watchFile); })) { + _this.addWatchFile(watchFile); + } + }); + }); + } + }, + watchChange: function (id) { + return __awaiter(this, void 0, void 0, function () { + var resolvedId, filesToUpdate; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + resolvedId = path.resolve(id); + filesToUpdate = Object.entries(context.stylesToEmit).filter(function (_a) { + var styleInfo = _a[1]; + return styleInfo.watchList.includes(resolvedId); + }); + return [4 /*yield*/, Promise.all(filesToUpdate.map(function (_a) { + var fileName = _a[0], styleInfo = _a[1]; + return ensureCodeAndWatchList(fileName, styleInfo, _this.meta.watchMode, compilerOptions); + }))]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }, + renderChunk: function (code, chunk, outputOptions) { + var bundleOutDir = path.resolve(outputOptions.dir || path.dirname(outputOptions.file)); + if (code && chunk.modules && Object.keys(chunk.modules).some(function (m) { return context.modulesWithCss.has(m); })) { + var moduleRoot = outputOptions.preserveModulesRoot || process.cwd(); + return importUpdater.updateImports(code, chunk, bundleOutDir, moduleRoot); + } + return null; + }, + generateBundle: function (_, __, isWrite) { + if (!isWrite) { + return; + } + assertDuplicates(context.stylesToEmit); + for (var file in context.stylesToEmit) { + var stylesInfo = context.stylesToEmit[file]; + var fileName = stylesInfo.output; + var source = file.endsWith(".css") + ? stylesInfo.css + : ensureSourceMap(stylesInfo, options.sourceMap || (sassOptions === null || sassOptions === void 0 ? void 0 : sassOptions.sourceMap), fileName, this.emitFile); + this.emitFile({ + type: "asset", + fileName: fileName, + source: source, + }); + } + }, + }; +} + +export { keepCssImports as default }; diff --git a/build/esm/rollup-plugin-keep-css-imports/dist/types.d.ts b/build/esm/rollup-plugin-keep-css-imports/dist/types.d.ts new file mode 100644 index 00000000..3680d628 --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/dist/types.d.ts @@ -0,0 +1,110 @@ +import { type CompilationOptions, PostCssCompatible } from "./compileSass"; +import type { Options as SassOptions } from "sass"; +export type KeepCssImportsOptions = OutputOptions & InputOptions & Extensions; +export type StyleRefInfo = { + /** + * Collection of files with reference to the current file + */ + importers: string[]; + /** + * List of files which are used to render the current file + */ + watchList: string[]; + /** + * Emit path + */ + output?: string; + /** + * Processed CSS content to emit + */ + css?: string | Uint8Array; + /** + * Processed CSS content map to emit + */ + map?: string | Uint8Array; +}; +export type StylesMap = Record; +interface Extensions { + /** + * Customised SASS (SCSS) processor. If not provided plugin will try to + * import locally installed `sass` if required + */ + sass?: CompilationOptions["sass"]; + /** + * An optional object that allows to provide additional options for the + * SASS compiler. + */ + sassOptions?: SassOptions<"async">; + /** + * Specifies the list of include paths for SASS to search when resolving imports. + * + * Default: `["node_modules/"]` + */ + includePaths?: string[]; + /** + * An optional function that allows you to perform additional processing on the + * generated CSS, such as applying PostCSS plugins. + */ + postProcessor?: (css: string, map: string, stylesMap: StylesMap) => Promise; +} +type OutputPath = string | "keep" | ((assetId: string) => string); +export interface OutputOptions { + /** + * Specifies the file extension for the output CSS files. + * + * Default: `".css"` + */ + outputExt?: string; + /** + * Specifies the output directory for the generated CSS files. + * Relative to Rollup output folder. + * + * Default: `"./"` + */ + outputDir?: string; + /** + * Specifies the output path relative to `outputDir` for the generated CSS + * files. + * The default value, "keep", preserves the original file paths. It is also + * possible to provide a custom function to generate output paths based on + * the input file. + * + * Default: `"keep"` + */ + outputPath?: OutputPath; + /** + * Specifies whether to generate source maps for the compiled CSS. + * Use `"inline"` to inline source maps into CSS files. + * + * Default: `false` + */ + sourceMap?: boolean | "inline"; + /** + * By default CSS paths will be prefixed with current folder mark `./`. + * To avoid this for CSS files use `true` or specify RegExp filter. + * + * If RegExp filter matches `./` won't be added to the path. + * This option may be helpful if you have some issues with external + * modules imports from `node_modules` + * + * Default: `false` + */ + skipCurrentFolderPart?: boolean | RegExp; +} +interface InputOptions { + /** + * Regular expression to test if an import should be processed by this plugin + * + * Default: `/\.(?:s[ca]|c)ss$/` + */ + includeRegexp?: RegExp; +} +export interface KeepCssImportsPluginContext { + allStyleImports: string[]; + modulesWithCss: Set; + stylesToEmit: StylesMap; +} +export {}; diff --git a/build/esm/rollup-plugin-keep-css-imports/package.json b/build/esm/rollup-plugin-keep-css-imports/package.json new file mode 100644 index 00000000..5cca1b9f --- /dev/null +++ b/build/esm/rollup-plugin-keep-css-imports/package.json @@ -0,0 +1,74 @@ +{ + "name": "rollup-plugin-keep-css-imports", + "version": "1.0.0", + "description": "Rollup plugin that allows to maintain the original structure of style imports without altering them during the bundling process", + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.ts", + "default": "./dist/index.cjs" + } + } + }, + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "keywords": [ + "rollup", + "rollup-plugin", + "css-modules", + "sass", + "scss", + "keep", + "preserve", + "imports" + ], + "homepage": "https://github.com/SLTKA/rollup-plugin-keep-css-imports", + "author": "Alexandr Yeskov", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/SLTKA/rollup-plugin-keep-css-imports" + }, + "bugs": { + "url": "https://github.com/SLTKA/rollup-plugin-keep-css-imports/issues" + }, + "scripts": { + "prebuild": "rimraf -rf dist/", + "build": "rollup -c", + "test": "mocha", + "pretest": "yarn build" + }, + "devDependencies": { + "@rollup/plugin-typescript": "^11.1.6", + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.24", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-mocha": "^10.2.0", + "eslint-plugin-prettier": "^5.1.3", + "mocha": "^10.2.0", + "prettier": "^3.2.4", + "rimraf": "^5.0.5", + "rollup": "^4.9.5", + "rollup-plugin-dts": "^6.1.0", + "sass": "^1.70.0", + "ts-node": "^10.9.2", + "typescript": "^5.3.3", + "typescript-eslint": "^7.1.1" + }, + "dependencies": { + "magic-string": "^0.30.5" + } +} diff --git a/build/esm/rollup-types.config.mjs b/build/esm/rollup-types.config.mjs new file mode 100644 index 00000000..a622c2ca --- /dev/null +++ b/build/esm/rollup-types.config.mjs @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// @ts-check + +import nodeResolve from '@rollup/plugin-node-resolve'; +import { join } from 'path'; +import { defineConfig } from 'rollup'; +import { dts } from "rollup-plugin-dts"; + +const root = join(import.meta.dirname, '../../'); +const outDir = join(root, './out/monaco-editor/esm'); + +/** + * @param {string} filePath + * @param {string} newExt + * @returns {string} + */ +function changeExt(filePath, newExt) { + const idx = filePath.lastIndexOf('.'); + if (idx === -1) { + return filePath + newExt; + } else { + return filePath.substring(0, idx) + newExt; + } +} + +const mappedPaths = { + [join(root, 'node_modules/monaco-editor-core/esm/')]: '.', + [join(root, 'node_modules/')]: 'external/', + [join(root, 'src/')]: 'vs/', +}; + +export default defineConfig({ + input: { + entry: join(root, './src/editor/editor.main.ts'), + }, + output: { + dir: outDir, + format: 'es', + preserveModules: false, + entryFileNames: function (chunkInfo) { + const moduleId = chunkInfo.facadeModuleId; + if (moduleId) { + for (const [key, val] of Object.entries(mappedPaths)) { + if (moduleId.startsWith(key)) { + const relativePath = moduleId.substring(key.length); + return changeExt(join(val, relativePath), '.d.ts'); + } + } + } + return '[name].d.ts'; + }, + }, + external: [/.*\.css/], + plugins: [ + nodeResolve(), + dts({ + compilerOptions: { + stripInternal: true, + }, + includeExternal: ['monaco-editor-core', '@vscode/monaco-lsp-client'] + }), + ], +}); diff --git a/build/esm/rollup-url-to-module-plugin/index.mjs b/build/esm/rollup-url-to-module-plugin/index.mjs new file mode 100644 index 00000000..8a0168bd --- /dev/null +++ b/build/esm/rollup-url-to-module-plugin/index.mjs @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * @type {() => import('rollup').Plugin} +*/ +export function urlToEsmPlugin() { + return { + name: 'import-meta-url', + async transform(code, id) { + if (this.environment?.mode === 'dev') { + return; + } + + // Look for `new URL(..., import.meta.url)` patterns. + const regex = /new\s+URL\s*\(\s*(['"`])(.*?)\1\s*,\s*import\.meta\.url\s*\)?/g; + + let match; + let modified = false; + let result = code; + let offset = 0; + + while ((match = regex.exec(code)) !== null) { + let path = match[2]; + + if (!path.startsWith('.') && !path.startsWith('/')) { + path = `./${path}`; + } + const resolved = await this.resolve(path, id); + + if (!resolved) { + continue; + } + + // Add the file as an entry point + const refId = this.emitFile({ + type: 'chunk', + id: resolved.id, + }); + + const start = match.index; + const end = start + match[0].length; + + const replacement = `import.meta.ROLLUP_FILE_URL_OBJ_${refId}`; + + result = result.slice(0, start + offset) + replacement + result.slice(end + offset); + offset += replacement.length - (end - start); + modified = true; + } + + if (!modified) { + return null; + } + + return { + code: result, + map: null + }; + } + }; +} diff --git a/build/esm/rollup.config.mjs b/build/esm/rollup.config.mjs new file mode 100644 index 00000000..715c4e21 --- /dev/null +++ b/build/esm/rollup.config.mjs @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// @ts-check + +import { join, relative } from 'path'; +import { defineConfig } from 'rollup'; +import esbuild from 'rollup-plugin-esbuild'; +//import { urlToEsmPlugin } from '../rollup-url-to-module-plugin/index.mjs'; +import del from 'rollup-plugin-delete'; +import keepCssImports from './rollup-plugin-keep-css-imports/dist/index.mjs'; +import nodeResolve from '@rollup/plugin-node-resolve'; +import { urlToEsmPlugin } from './rollup-url-to-module-plugin/index.mjs'; +import { copyFileSync, mkdirSync } from 'fs'; +import { dirname } from 'path'; + +const root = join(import.meta.dirname, '../../'); +const outDir = join(root, './out/monaco-editor/esm'); + +/** + * @param {string} filePath + * @param {string} newExt + * @returns {string} + */ +function changeExt(filePath, newExt) { + const idx = filePath.lastIndexOf('.'); + if (idx === -1) { + return filePath + newExt; + } else { + return filePath.substring(0, idx) + newExt; + } +} + +const mappedPaths = { + [join(root, 'node_modules/monaco-editor-core/esm/')]: '.', + [join(root, 'node_modules/')]: 'external/', + [join(root, 'monaco-lsp-client/')]: 'external/monaco-lsp-client/', + [join(root, 'src/')]: 'vs/', +}; + +export default defineConfig({ + input: { + entry: join(root, './src/editor/editor.main.ts'), + editorAll: join(root, './src/editor/editor.all.ts'), + edcoreMain: join(root, './src/editor/edcore.main.ts'), + editorApi: join(root, './src/editor/editor.api.ts'), + editorWorker: join(root, './src/editor/editor.worker.ts'), + }, + + output: { + dir: outDir, + format: 'es', + + entryFileNames: function (chunkInfo) { + const moduleId = chunkInfo.facadeModuleId; + if (moduleId) { + for (const [key, val] of Object.entries(mappedPaths)) { + if (moduleId.startsWith(key)) { + const relativePath = moduleId.substring(key.length); + return changeExt(join(val, relativePath), '.js'); + } + } + } + return '[name].js'; + }, + preserveModules: true, + }, + + + plugins: [ + del({ targets: outDir, force: true }), + + { + name: 'copy-codicon-font', + buildEnd() { + const codiconSource = join(root, 'node_modules/monaco-editor-core/esm/vs/base/browser/ui/codicons/codicon/codicon.ttf'); + const codiconDest = join(outDir, 'vs/base/browser/ui/codicons/codicon/codicon.ttf'); + mkdirSync(dirname(codiconDest), { recursive: true }); + copyFileSync(codiconSource, codiconDest); + } + }, + + urlToEsmPlugin(), + esbuild(), + + keepCssImports({ + /** + * @param {string} assetId + */ + outputPath: (assetId) => { + for (const [key, val] of Object.entries(mappedPaths)) { + if (assetId.startsWith(key)) { + const relativePath = assetId.substring(key.length); + return changeExt(join(outDir, val, relativePath), '.css'); + } + } + + const relativePath = join(outDir, relative(root, assetId)); + return relativePath.replace(/(\.s[ca]ss)$/, ".min$1") + }, + }), + nodeResolve({ + dedupe: ['monaco-editor-core', '@vscode/monaco-lsp-client'], + browser: true, + }), + ], +}); diff --git a/build/fillers/vscode-nls.ts b/build/fillers/vscode-nls.ts deleted file mode 100644 index 38f7b334..00000000 --- a/build/fillers/vscode-nls.ts +++ /dev/null @@ -1,46 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface Options { - locale?: string; - cacheLanguageResolution?: boolean; -} -export interface LocalizeInfo { - key: string; - comment: string[]; -} -export interface LocalizeFunc { - (info: LocalizeInfo, message: string, ...args: any[]): string; - (key: string, message: string, ...args: any[]): string; -} -export interface LoadFunc { - (file?: string): LocalizeFunc; -} - -function format(message: string, args: any[]): string { - let result: string; - - if (args.length === 0) { - result = message; - } else { - result = message.replace(/\{(\d+)\}/g, (match, rest) => { - let index = rest[0]; - return typeof args[index] !== 'undefined' ? args[index] : match; - }); - } - return result; -} - -function localize(key: string | LocalizeInfo, message: string, ...args: any[]): string { - return format(message, args); -} - -export function loadMessageBundle(file?: string): LocalizeFunc { - return localize; -} - -export function config(opt?: Options | string): LoadFunc { - return loadMessageBundle; -} diff --git a/build/releaseMetadata.ts b/build/releaseMetadata.ts index 17a530ff..d25ceb76 100644 --- a/build/releaseMetadata.ts +++ b/build/releaseMetadata.ts @@ -103,7 +103,7 @@ function getAdvancedLanguages(): Promise< } } -export function generateMetadata() { +export function generateEsmMetadataJsAndDTs() { return Promise.all([getBasicLanguages(), getAdvancedLanguages()]).then( ([basicLanguages, advancedLanguages]) => { basicLanguages.sort((a, b) => strcmp(a.entry, b.entry)); diff --git a/build/utils.ts b/build/utils.ts index b4a90bb3..8a11841c 100644 --- a/build/utils.ts +++ b/build/utils.ts @@ -5,181 +5,11 @@ import * as fs from 'fs'; import * as path from 'path'; -import * as cp from 'child_process'; -import * as esbuild from 'esbuild'; import * as glob from 'glob'; import { ensureDir } from './fs'; export const REPO_ROOT = path.join(__dirname, '../'); -/** - * Launch the typescript compiler synchronously over a project. - */ -export function runTsc(_projectPath: string) { - const projectPath = path.join(REPO_ROOT, _projectPath); - console.log(`Launching compiler at ${_projectPath}...`); - const res = cp.spawnSync( - process.execPath, - [path.join(__dirname, '../node_modules/typescript/lib/tsc.js'), '-p', projectPath], - { stdio: 'inherit' } - ); - console.log(`Compiled ${_projectPath}`); - if (res.status !== 0) { - process.exit(res.status); - } -} - -/** - * Launch prettier on a specific file. - */ -export function prettier(_filePath: string) { - const filePath = path.join(REPO_ROOT, _filePath); - cp.spawnSync( - process.execPath, - [path.join(__dirname, '../node_modules/prettier/bin-prettier.js'), '--write', filePath], - { stdio: 'inherit' } - ); - - console.log(`Ran prettier over ${_filePath}`); -} - -/** - * Transform an external .d.ts file to an internal .d.ts file - */ -export function massageAndCopyDts(source: string, destination: string, namespace: string) { - const absoluteSource = path.join(REPO_ROOT, source); - const absoluteDestination = path.join(REPO_ROOT, destination); - - const lines = fs - .readFileSync(absoluteSource) - .toString() - .split(/\r\n|\r|\n/); - - let result = [ - `/*---------------------------------------------------------------------------------------------`, - ` * Copyright (c) Microsoft Corporation. All rights reserved.`, - ` * Licensed under the MIT License. See License.txt in the project root for license information.`, - ` *--------------------------------------------------------------------------------------------*/`, - ``, - `declare namespace ${namespace} {` - ]; - for (let line of lines) { - if (/^import/.test(line)) { - continue; - } - if (line === 'export {};') { - continue; - } - line = line.replace(/ /g, '\t'); - line = line.replace(/declare /g, ''); - if (line.length > 0) { - line = `\t${line}`; - result.push(line); - } - } - result.push(`}`); - result.push(``); - - ensureDir(path.dirname(absoluteDestination)); - fs.writeFileSync(absoluteDestination, result.join('\n')); - - prettier(destination); -} - -export function build(options: import('esbuild').BuildOptions) { - esbuild.build(options).then((result) => { - if (result.errors.length > 0) { - console.error(result.errors); - } - if (result.warnings.length > 0) { - console.error(result.warnings); - } - }); -} - -export function buildESM(options: { base: string; entryPoints: string[]; external: string[] }) { - build({ - entryPoints: options.entryPoints, - bundle: true, - target: 'esnext', - format: 'esm', - drop: ['debugger'], - banner: { - js: bundledFileHeader - }, - external: options.external, - outbase: `src/${options.base}`, - outdir: `out/languages/bundled/esm/vs/${options.base}/` - }); -} - -function getGitVersion() { - const git = path.join(REPO_ROOT, '.git'); - const headPath = path.join(git, 'HEAD'); - let head; - - try { - head = fs.readFileSync(headPath, 'utf8').trim(); - } catch (e) { - return void 0; - } - - if (/^[0-9a-f]{40}$/i.test(head)) { - return head; - } - - const refMatch = /^ref: (.*)$/.exec(head); - - if (!refMatch) { - return void 0; - } - - const ref = refMatch[1]; - const refPath = path.join(git, ref); - - try { - return fs.readFileSync(refPath, 'utf8').trim(); - } catch (e) { - // noop - } - - const packedRefsPath = path.join(git, 'packed-refs'); - let refsRaw; - - try { - refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim(); - } catch (e) { - return void 0; - } - - const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; - let refsMatch; - const refs = {}; - - while ((refsMatch = refsRegex.exec(refsRaw))) { - refs[refsMatch[2]] = refsMatch[1]; - } - - return refs[ref]; -} - -export const bundledFileHeader = (() => { - const sha1 = getGitVersion(); - const semver = require('../package.json').version; - const headerVersion = semver + '(' + sha1 + ')'; - - const BUNDLED_FILE_HEADER = [ - '/*!-----------------------------------------------------------------------------', - ' * Copyright (c) Microsoft Corporation. All rights reserved.', - ' * Version: ' + headerVersion, - ' * Released under the MIT license', - ' * https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt', - ' *-----------------------------------------------------------------------------*/', - '' - ].join('\n'); - - return BUNDLED_FILE_HEADER; -})(); export interface IFile { path: string; diff --git a/package-lock.json b/package-lock.json index ed65ffae..1a8506c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "monaco-editor-core": "^0.55.0-dev-20251008", "parcel": "^2.7.0", "pin-github-action": "^1.8.0", + "postcss-url": "^10.1.3", "prettier": "^2.5.1", "pretty-quick": "^3.1.3", "requirejs": "^2.3.7", @@ -4272,6 +4273,13 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", + "dev": true, + "license": "MIT" + }, "node_modules/data-urls": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", @@ -6223,6 +6231,32 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -6308,6 +6342,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", @@ -7134,6 +7181,38 @@ "node": ">=4" } }, + "node_modules/postcss-url": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", + "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "make-dir": "~3.1.0", + "mime": "~2.5.2", + "minimatch": "~3.0.4", + "xxhashjs": "~0.2.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-url/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -8967,6 +9046,16 @@ "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==", "dev": true }, + "node_modules/xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cuint": "^0.2.2" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -11855,6 +11944,12 @@ } } }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", + "dev": true + }, "data-urls": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz", @@ -13123,6 +13218,23 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -13182,6 +13294,12 @@ } } }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, "mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", @@ -13780,6 +13898,29 @@ "util-deprecate": "^1.0.2" } }, + "postcss-url": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-10.1.3.tgz", + "integrity": "sha512-FUzyxfI5l2tKmXdYc6VTu3TWZsInayEKPbiyW+P6vmmIrrb4I6CGX0BFoewgYHLK+oIL5FECEK02REYRpBvUCw==", + "dev": true, + "requires": { + "make-dir": "~3.1.0", + "mime": "~2.5.2", + "minimatch": "~3.0.4", + "xxhashjs": "~0.2.2" + }, + "dependencies": { + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -14957,6 +15098,15 @@ "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==", "dev": true }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "dev": true, + "requires": { + "cuint": "^0.2.2" + } + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index ed49ebfe..2cc25e7d 100644 --- a/package.json +++ b/package.json @@ -28,10 +28,10 @@ "deps-all-install": "ts-node ./build/npm/installAll", "update-actions": "pin-github-action ./.github/workflows/website.yml", "watch": "tsc -w -p ./src", - "build-languages": "ts-node ./build/build-languages", + "build-all": "npm run build-lsp && npm run build-monaco-editor && npm run package-for-smoketest", + "build": "npm run build-lsp && npm run build-monaco-editor", "build-monaco-editor": "ts-node ./build/build-monaco-editor", - "build-lsp": "cd monaco-lsp-client && npm install && npm run build", - "build": "npm run build-lsp && npm run build-languages && npm run build-monaco-editor" + "build-lsp": "cd monaco-lsp-client && npm install && npm run build" }, "typings": "./esm/vs/editor/editor.api.d.ts", "module": "./esm/vs/editor/editor.main.js", @@ -40,7 +40,6 @@ "url": "https://github.com/microsoft/monaco-editor" }, "devDependencies": { - "@vscode/monaco-lsp-client": "file:./monaco-lsp-client", "@playwright/test": "^1.53.2", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-node-resolve": "^16.0.2", @@ -48,6 +47,7 @@ "@types/shelljs": "^0.8.11", "@types/trusted-types": "^1.0.6", "@typescript/vfs": "^1.3.5", + "@vscode/monaco-lsp-client": "file:./monaco-lsp-client", "chai": "^4.3.6", "clean-css": "^5.2.4", "css-loader": "^6.7.1", @@ -63,6 +63,7 @@ "monaco-editor-core": "^0.55.0-dev-20251008", "parcel": "^2.7.0", "pin-github-action": "^1.8.0", + "postcss-url": "^10.1.3", "prettier": "^2.5.1", "pretty-quick": "^3.1.3", "requirejs": "^2.3.7", diff --git a/src/common/workers.ts b/src/common/workers.ts index 2784b9f5..94bbc257 100644 --- a/src/common/workers.ts +++ b/src/common/workers.ts @@ -6,9 +6,9 @@ function createTrustedTypesPolicy( ): | undefined | Pick< - TrustedTypePolicy, - 'name' | Extract - > { + TrustedTypePolicy, + 'name' | Extract + > { interface IMonacoEnvironment { createTrustedTypesPolicy( policyName: string, @@ -16,9 +16,9 @@ function createTrustedTypesPolicy( ): | undefined | Pick< - TrustedTypePolicy, - 'name' | Extract - >; + TrustedTypePolicy, + 'name' | Extract + >; } const monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment; @@ -52,7 +52,7 @@ if ( }); } -function getWorker(descriptor: { label: string; moduleId: string }): Worker | Promise { +function getWorker(descriptor: { label: string; moduleId: string; createWorker?: () => Worker }): Worker | Promise { const label = descriptor.label; // Option for hosts to overwrite the worker script (used in the standalone editor) interface IMonacoEnvironment { @@ -73,6 +73,10 @@ function getWorker(descriptor: { label: string; moduleId: string }): Worker | Pr } } + if (descriptor.createWorker) { + return descriptor.createWorker(); + } + // const esmWorkerLocation = descriptor.esmModuleLocation; // if (esmWorkerLocation) { // const workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation.toString(true)); @@ -91,7 +95,8 @@ export function createWebWorker( const worker = Promise.resolve( getWorker({ label: opts.label ?? 'monaco-editor-worker', - moduleId: opts.moduleId + moduleId: opts.moduleId, + createWorker: opts.createWorker, }) ).then((w) => { w.postMessage('ignore'); @@ -111,6 +116,7 @@ export interface IWebWorkerOptions { * It should export a function `create` that should return the exported proxy. */ moduleId: string; + createWorker?: () => Worker, /** * The data to send over when calling create on the module. */ diff --git a/src/editor/edcore.main.ts b/src/editor/edcore.main.ts new file mode 100644 index 00000000..b2c570c9 --- /dev/null +++ b/src/editor/edcore.main.ts @@ -0,0 +1,2 @@ +import './internal/initialize'; +export * from 'monaco-editor-core'; diff --git a/src/editor/editor.all.ts b/src/editor/editor.all.ts new file mode 100644 index 00000000..e8e7ebfa --- /dev/null +++ b/src/editor/editor.all.ts @@ -0,0 +1,3 @@ +import './internal/initialize'; +/// @ts-ignore +export * from 'monaco-editor-core/esm/vs/editor/editor.all'; diff --git a/src/editor/editor.api.ts b/src/editor/editor.api.ts new file mode 100644 index 00000000..401981e4 --- /dev/null +++ b/src/editor/editor.api.ts @@ -0,0 +1,3 @@ +import './internal/initialize'; +/// @ts-ignore +export * from 'monaco-editor-core/esm/vs/editor/editor.api'; diff --git a/src/editor/editor.main.ts b/src/editor/editor.main.ts index 37a11ab3..293e2c7d 100644 --- a/src/editor/editor.main.ts +++ b/src/editor/editor.main.ts @@ -1,18 +1,14 @@ -import { createWebWorker } from '../common/workers.js'; -import '../basic-languages/monaco.contribution.js'; -import * as css from '../language/css/monaco.contribution.js'; -import * as html from '../language/html/monaco.contribution.js'; -import * as json from '../language/json/monaco.contribution.js'; -import * as typescript from '../language/typescript/monaco.contribution.js'; -import * as monaco from 'monaco-editor-core'; -export * from 'monaco-editor-core'; +import * as monaco from './internal/editorWithLanguages'; +import './internal/initialize'; +import { getGlobalMonaco } from './internal/initialize'; -export { css, html, json, typescript }; +export * from './internal/editorWithLanguages'; -const existingCreateWebWorker = monaco.editor.createWebWorker; -monaco.editor.createWebWorker = function (options: any) { - if (options.worker === undefined) { - return createWebWorker(options); - } - return existingCreateWebWorker(options); -} as any; +// export to the global based API (for backwards compatibility only). +// Warning: We can only write to objects, not modules / namespaces! +// Writing to modules/namespace would confuse bundlers. +const monacoApi = getGlobalMonaco(); +monacoApi.languages.css = monaco.css; +monacoApi.languages.html = monaco.html; +monacoApi.languages.typescript = monaco.typescript; +monacoApi.languages.json = monaco.json; diff --git a/src/editor/internal/editorWithLanguages.ts b/src/editor/internal/editorWithLanguages.ts new file mode 100644 index 00000000..8297b685 --- /dev/null +++ b/src/editor/internal/editorWithLanguages.ts @@ -0,0 +1,10 @@ +import * as css from '../../language/css/monaco.contribution.js'; +import * as html from '../../language/html/monaco.contribution.js'; +import * as json from '../../language/json/monaco.contribution.js'; +import * as typescript from '../../language/typescript/monaco.contribution.js'; +import '../../basic-languages/monaco.contribution.js'; +import * as lsp from '@vscode/monaco-lsp-client'; + +export * from 'monaco-editor-core'; +export { createWebWorker, type IWebWorkerOptions } from '../../common/workers.js'; +export { css, html, json, typescript, lsp }; diff --git a/src/editor/internal/initialize.ts b/src/editor/internal/initialize.ts new file mode 100644 index 00000000..337494bf --- /dev/null +++ b/src/editor/internal/initialize.ts @@ -0,0 +1,12 @@ +import * as monaco from 'monaco-editor-core/esm/vs/editor/editor.api.js'; + +export function getGlobalMonaco(): any { + return monaco; +} + +// TODO@hediet get rid of the monaco global + +const monacoEnvironment: monaco.Environment | undefined = (globalThis as any).MonacoEnvironment; +if (monacoEnvironment?.globalAPI) { + (globalThis as any).monaco = getGlobalMonaco(); +} diff --git a/src/language/css/monaco.contribution.ts b/src/language/css/monaco.contribution.ts index f00e8f32..0e4e3f71 100644 --- a/src/language/css/monaco.contribution.ts +++ b/src/language/css/monaco.contribution.ts @@ -253,9 +253,6 @@ export const lessDefaults: LanguageServiceDefaults = new LanguageServiceDefaults modeConfigurationDefault ); -// export to the global based API -(languages).css = { cssDefaults, lessDefaults, scssDefaults }; - // --- Registration to monaco editor --- function getMode(): Promise { diff --git a/src/language/css/workerManager.ts b/src/language/css/workerManager.ts index 00a472fe..b2463dc7 100644 --- a/src/language/css/workerManager.ts +++ b/src/language/css/workerManager.ts @@ -59,7 +59,7 @@ export class WorkerManager { this._worker = createWebWorker({ // module that exports the create() method and returns a `CSSWorker` instance moduleId: 'vs/language/css/cssWorker', - + createWorker: () => new Worker(new URL('./css.worker', import.meta.url), { type: 'module' }), label: this._defaults.languageId, // passed in to the create() method diff --git a/src/language/html/monaco.contribution.ts b/src/language/html/monaco.contribution.ts index 67fb5ca5..9eda9784 100644 --- a/src/language/html/monaco.contribution.ts +++ b/src/language/html/monaco.contribution.ts @@ -215,17 +215,6 @@ export const razorLanguageService = registerHTMLLanguageService( ); export const razorDefaults = razorLanguageService.defaults; -// export to the global based API -(languages).html = { - htmlDefaults, - razorDefaults, - handlebarDefaults, - htmlLanguageService, - handlebarLanguageService, - razorLanguageService, - registerHTMLLanguageService -}; - // --- Registration to monaco editor --- function getMode(): Promise { diff --git a/src/language/html/workerManager.ts b/src/language/html/workerManager.ts index a4c9cb04..3c559952 100644 --- a/src/language/html/workerManager.ts +++ b/src/language/html/workerManager.ts @@ -59,6 +59,7 @@ export class WorkerManager { this._worker = createWebWorker({ // module that exports the create() method and returns a `HTMLWorker` instance moduleId: 'vs/language/html/htmlWorker', + createWorker: () => new Worker(new URL('./html.worker', import.meta.url), { type: 'module' }), // passed in to the create() method createData: { diff --git a/src/language/json/monaco.contribution.ts b/src/language/json/monaco.contribution.ts index 2f3b6afe..851769a8 100644 --- a/src/language/json/monaco.contribution.ts +++ b/src/language/json/monaco.contribution.ts @@ -87,10 +87,10 @@ export interface JSONSchema { minProperties?: number; maxProperties?: number; dependencies?: - | JSONSchemaMap - | { - [prop: string]: string[]; - }; + | JSONSchemaMap + | { + [prop: string]: string[]; + }; items?: JSONSchemaRef | JSONSchemaRef[]; minItems?: number; maxItems?: number; @@ -342,9 +342,6 @@ export interface IJSONWorker { export const getWorker = (): Promise<(...uris: Uri[]) => Promise> => getMode().then((mode) => mode.getWorker()); -// export to the global based API -(languages).json = { jsonDefaults, getWorker }; - // --- Registration to monaco editor --- function getMode(): Promise { diff --git a/src/language/json/workerManager.ts b/src/language/json/workerManager.ts index 9af92e0d..b2e66d31 100644 --- a/src/language/json/workerManager.ts +++ b/src/language/json/workerManager.ts @@ -59,6 +59,7 @@ export class WorkerManager { this._worker = createWebWorker({ // module that exports the create() method and returns a `JSONWorker` instance moduleId: 'vs/language/json/jsonWorker', + createWorker: () => new Worker(new URL('./json.worker', import.meta.url), { type: 'module' }), label: this._defaults.languageId, diff --git a/src/language/typescript/monaco.contribution.ts b/src/language/typescript/monaco.contribution.ts index 8bcf385b..95d7da63 100644 --- a/src/language/typescript/monaco.contribution.ts +++ b/src/language/typescript/monaco.contribution.ts @@ -618,7 +618,7 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults { if (this._extraLibs[filePath] && this._extraLibs[filePath].content === content) { // no-op, there already exists an extra lib with this content return { - dispose: () => {} + dispose: () => { } }; } @@ -718,7 +718,7 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults { this._onDidChange.fire(undefined); } - setMaximumWorkerIdleTime(value: number): void {} + setMaximumWorkerIdleTime(value: number): void { } setEagerModelSync(value: boolean) { // doesn't fire an event since no @@ -778,20 +778,6 @@ export const getJavaScriptWorker = (): Promise<(...uris: Uri[]) => Promise mode.getJavaScriptWorker()); }; -// export to the global based API -(languages).typescript = { - ModuleKind, - JsxEmit, - NewLineKind, - ScriptTarget, - ModuleResolutionKind, - typescriptVersion, - typescriptDefaults, - javascriptDefaults, - getTypeScriptWorker, - getJavaScriptWorker -}; - // --- Registration to monaco editor --- function getMode(): Promise { diff --git a/src/language/typescript/workerManager.ts b/src/language/typescript/workerManager.ts index 57ca7a8f..f0cbcacd 100644 --- a/src/language/typescript/workerManager.ts +++ b/src/language/typescript/workerManager.ts @@ -62,6 +62,7 @@ export class WorkerManager { this._worker = createWebWorker({ // module that exports the create() method and returns a `TypeScriptWorker` instance moduleId: 'vs/language/typescript/tsWorker', + createWorker: () => new Worker(new URL('./ts.worker', import.meta.url), { type: 'module' }), label: this._modeId,