@stencil/core 5.0.0-beta.0 → 5.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ import postcssSelectorParser from "postcss-selector-parser";
17
17
  import MagicString from "magic-string";
18
18
  import { rolldown } from "rolldown";
19
19
  import resolve$1 from "resolve";
20
+ import { minifySync } from "rolldown/utils";
20
21
  import { minify } from "terser";
21
22
  import { SelectorType, parse, stringify } from "css-what";
22
23
  import { execFile } from "node:child_process";
@@ -72,12 +73,13 @@ const restoreSafeSelector = (placeholders, content) => {
72
73
  const _polyfillHost = "-shadowcsshost";
73
74
  const _polyfillSlotted = "-shadowcssslotted";
74
75
  const _polyfillHostContext = "-shadowcsscontext";
76
+ const _parenSuffix = ")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)";
75
77
  let _cssColonHostRe;
76
78
  let _cssColonHostContextRe;
77
79
  let _cssColonSlottedRe;
78
- const getCssColonHostRe = () => _cssColonHostRe ??= /* @__PURE__ */ new RegExp("(-shadowcsshost)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)", "gim");
79
- const getCssColonHostContextRe = () => _cssColonHostContextRe ??= /* @__PURE__ */ new RegExp("(-shadowcsscontext)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)", "gim");
80
- const getCssColonSlottedRe = () => _cssColonSlottedRe ??= /* @__PURE__ */ new RegExp("(-shadowcssslotted)(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)", "gim");
80
+ const getCssColonHostRe = () => _cssColonHostRe ??= new RegExp("(-shadowcsshost" + _parenSuffix, "gim");
81
+ const getCssColonHostContextRe = () => _cssColonHostContextRe ??= new RegExp("(-shadowcsscontext" + _parenSuffix, "gim");
82
+ const getCssColonSlottedRe = () => _cssColonSlottedRe ??= new RegExp("(-shadowcssslotted" + _parenSuffix, "gim");
81
83
  const _polyfillHostNoCombinator = "-shadowcsshost-no-combinator";
82
84
  const _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/;
83
85
  const _shadowDOMSelectorsRe = [/::shadow/g, /::content/g];
@@ -340,12 +342,13 @@ const scopeSelector = (selector, scopeSelectorText, hostSelector, slotSelector)
340
342
  else return shallowPart.trim();
341
343
  }).join(", ");
342
344
  };
345
+ const isScopableAtRule = (selector) => selector.startsWith("@media") || selector.startsWith("@supports") || selector.startsWith("@page") || selector.startsWith("@document") || selector.startsWith("@layer");
343
346
  const scopeSelectors = (cssText, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector) => {
344
347
  return processRules(cssText, (rule) => {
345
348
  let selector = rule.selector;
346
349
  let content = rule.content;
347
350
  if (rule.selector[0] !== "@") selector = scopeSelector(rule.selector, scopeSelectorText, hostSelector, slotSelector);
348
- else if (rule.selector.startsWith("@media") || rule.selector.startsWith("@supports") || rule.selector.startsWith("@page") || rule.selector.startsWith("@document")) content = scopeSelectors(rule.content, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector);
351
+ else if (isScopableAtRule(rule.selector)) content = scopeSelectors(rule.content, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector);
349
352
  return {
350
353
  selector: selector.replace(/\s{2,}/g, " ").trim(),
351
354
  content
@@ -437,14 +440,12 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
437
440
  rule.selector = placeholder + rule.selector;
438
441
  return rule;
439
442
  };
440
- cssText = processRules(cssText, (rule) => {
443
+ const commentSelectors = (input) => processRules(input, (rule) => {
441
444
  if (rule.selector[0] !== "@") return processCommentedSelector(rule);
442
- else if (rule.selector.startsWith("@media") || rule.selector.startsWith("@supports") || rule.selector.startsWith("@page") || rule.selector.startsWith("@document")) {
443
- rule.content = processRules(rule.content, processCommentedSelector);
444
- return rule;
445
- }
445
+ if (isScopableAtRule(rule.selector)) rule.content = commentSelectors(rule.content);
446
446
  return rule;
447
447
  });
448
+ cssText = commentSelectors(cssText);
448
449
  }
449
450
  const scoped = scopeCssText(cssText, scopeId, hostScopeId, slotScopeId, commentOriginalSelector);
450
451
  cssText = [scoped.cssText, ...commentsWithHash].join("\n");
@@ -460,9 +461,9 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
460
461
  };
461
462
  //#endregion
462
463
  //#region src/version.ts
463
- const version = "5.0.0-beta.0";
464
- const buildId = "1787699045";
465
- const vermoji = "🐥";
464
+ const version = "5.0.0-beta.2";
465
+ const buildId = "1788550154";
466
+ const vermoji = "🛩";
466
467
  /**
467
468
  * Get the installed version of a tool/dependency.
468
469
  * Handles packages with exports maps that point to subdirectories.
@@ -1020,6 +1021,7 @@ const REGISTER_HOST = "__stencil_registerHost";
1020
1021
  const H = "__stencil_h";
1021
1022
  const TRANSFORM_TAG = "__stencil_transformTag";
1022
1023
  const GET_REGISTRY = "__stencil_getRegistry";
1024
+ const INJECT_SIDE_EFFECT_STYLE = "__stencil_injectSideEffectStyle";
1023
1025
  const RUNTIME_APIS = {
1024
1026
  createEvent: `createEvent as ${CREATE_EVENT}`,
1025
1027
  defineCustomElement: `defineCustomElement as ${DEFINE_CUSTOM_ELEMENT}`,
@@ -2421,7 +2423,7 @@ function addTagTransformToCssString(cssCode, tagNames) {
2421
2423
  rule.selectors = rule.selectors.map((sel) => {
2422
2424
  const parsedSelector = postcssSelectorParser().astSync(sel);
2423
2425
  parsedSelector.walkTags((tag) => {
2424
- if (tagNames.includes(tag.value)) tag.value = "${__stencil_transformTag(\"" + tag.value + "\")}";
2426
+ if (tagNames.includes(tag.value)) tag.value = "${" + TRANSFORM_TAG + "(\"" + tag.value + "\")}";
2425
2427
  });
2426
2428
  return parsedSelector.toString();
2427
2429
  });
@@ -3354,9 +3356,9 @@ const runPluginTransformsEsmImports = async (config, compilerCtx, buildCtx, code
3354
3356
  return transformResults;
3355
3357
  };
3356
3358
  //#endregion
3357
- //#region src/compiler/style/optimize-css.ts
3359
+ //#region src/compiler/style/optimize-style-css.ts
3358
3360
  const getCssToolVersions = () => `autoprefixer@${getToolVersion("autoprefixer")}_postcss@${getToolVersion("postcss")}`;
3359
- const optimizeCss$1 = async (config, compilerCtx, diagnostics, styleText, filePath) => {
3361
+ const optimizeStyleCss = async (config, compilerCtx, diagnostics, styleText, filePath) => {
3360
3362
  if (typeof styleText !== "string" || !styleText.length) return styleText;
3361
3363
  if ((config.autoprefixCss === false || config.autoprefixCss === null) && !config.minifyCss) return styleText;
3362
3364
  if (typeof filePath === "string") filePath = normalizePath(filePath);
@@ -3441,7 +3443,7 @@ const collectAndBuildComponentGlobalStyles = async (config, compilerCtx, buildCt
3441
3443
  if (!result) continue;
3442
3444
  const cssCode = typeof result === "string" ? result : result.code;
3443
3445
  if (!cssCode) continue;
3444
- const optimized = await optimizeCss$1(config, compilerCtx, buildCtx.diagnostics, cssCode, path);
3446
+ const optimized = await optimizeStyleCss(config, compilerCtx, buildCtx.diagnostics, cssCode, path);
3445
3447
  compilerCtx.globalStyleCache.set(path, optimized);
3446
3448
  parts.push(optimized);
3447
3449
  }
@@ -3523,7 +3525,7 @@ const buildGlobalStyleFromInput = async (config, compilerCtx, buildCtx, inputPat
3523
3525
  }
3524
3526
  if (hasStencilGlobalsImport(cssCode)) cssCode = await resolveStencilGlobalsImport(cssCode, config, compilerCtx, buildCtx, normalizedPath);
3525
3527
  if (hasStencilHydrateImport(cssCode)) cssCode = resolveStencilHydrateImport(cssCode, config, buildCtx);
3526
- const optimizedCss = await optimizeCss$1(config, compilerCtx, buildCtx.diagnostics, cssCode, normalizedPath);
3528
+ const optimizedCss = await optimizeStyleCss(config, compilerCtx, buildCtx.diagnostics, cssCode, normalizedPath);
3527
3529
  compilerCtx.globalStyleCache.set(normalizedPath, optimizedCss);
3528
3530
  if (Array.isArray(dependencies)) {
3529
3531
  const cssModuleImports = compilerCtx.cssModuleImports.get(normalizedPath) || [];
@@ -3795,9 +3797,22 @@ const appendGlobalStyles = async (config, compilerCtx, buildCtx, s, platform) =>
3795
3797
  * @param s a `MagicString` to append the generated constant onto
3796
3798
  */
3797
3799
  const appendBuildConditionals = (config, buildConditionals, s) => {
3798
- const buildData = Object.keys(buildConditionals).sort().map((key) => key + ": " + JSON.stringify(buildConditionals[key])).join(", ");
3800
+ const buildData = getSortedBuildConditionalEntries(buildConditionals).map(([key, value]) => key + ": " + JSON.stringify(value)).join(", ");
3799
3801
  s.append(`export const BUILD = /* ${config.fsNamespace} */ { ${buildData} };\n`);
3800
3802
  };
3803
+ /**
3804
+ * Builds a `<flag> -> literal-value-as-source-text` map for every build conditional, for use by
3805
+ * {@link buildConditionalsPlugin} to replace `BUILD.<flag>` reads with their literal values.
3806
+ *
3807
+ * @param buildConditionals the build conditionals for this build
3808
+ * @returns a flag name > literal source text map
3809
+ */
3810
+ const getBuildConditionalsLiterals = (buildConditionals) => {
3811
+ const literals = /* @__PURE__ */ new Map();
3812
+ for (const [key, value] of getSortedBuildConditionalEntries(buildConditionals)) literals.set(key, JSON.stringify(value));
3813
+ return literals;
3814
+ };
3815
+ const getSortedBuildConditionalEntries = (buildConditionals) => Object.keys(buildConditionals).sort().map((key) => [key, buildConditionals[key]]);
3801
3816
  const appendEnv = (config, s) => {
3802
3817
  s.append(`export const Env = /* ${config.fsNamespace} */ ${JSON.stringify(config.env)};\n`);
3803
3818
  };
@@ -3912,7 +3927,6 @@ const coreResolvePlugin = (config, compilerCtx, platform, externalRuntime, lazyL
3912
3927
  const hydratedFlag = config.hydratedFlag;
3913
3928
  const hydratedFlagHead = hydratedFlag ? getHydratedFlagHead(hydratedFlag) : null;
3914
3929
  const hydratedReplacements = hydratedFlag && hydratedFlagHead !== "{visibility:hidden}.hydrated{visibility:inherit}" ? buildHydratedReplacements(hydratedFlag, hydratedFlagHead) : null;
3915
- const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3916
3930
  return {
3917
3931
  name: "coreResolvePlugin",
3918
3932
  resolveId: {
@@ -3952,7 +3966,7 @@ const coreResolvePlugin = (config, compilerCtx, platform, externalRuntime, lazyL
3952
3966
  }
3953
3967
  },
3954
3968
  load: {
3955
- filter: { id: new RegExp(`^(${escapeRegex(internalClient)}|${escapeRegex(internalSsr)})(\\?.*)?$`) },
3969
+ filter: { id: getStencilInternalModuleFilter(internalClient, internalSsr) },
3956
3970
  async handler(filePath) {
3957
3971
  if (filePath && !filePath.startsWith("\0")) {
3958
3972
  filePath = normalizeFsPath(filePath);
@@ -3984,6 +3998,19 @@ export const Build = {
3984
3998
  }
3985
3999
  };
3986
4000
  };
4001
+ /**
4002
+ * Builds a filter regex matching only Stencil's own resolved internal runtime module(s),
4003
+ * tolerant of query-string suffixes (e.g. `?app-data=conditional` for lazy builds). Shared by
4004
+ * any plugin that needs to scope its work to Stencil's own runtime code, rather than the rest
4005
+ * of a downstream app's bundle.
4006
+ *
4007
+ * @param moduleIds absolute paths to Stencil's resolved internal runtime module(s)
4008
+ * @returns a regex suitable for a rolldown hook's `id` filter
4009
+ */
4010
+ const getStencilInternalModuleFilter = (...moduleIds) => {
4011
+ const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4012
+ return new RegExp(`^(${moduleIds.map(escapeRegex).join("|")})(\\?.*)?$`);
4013
+ };
3987
4014
  const getStencilInternalModule = (config, compilerExe, internalModule) => {
3988
4015
  if (isRemoteUrl(compilerExe)) return normalizePath(config.sys.getLocalModulePath({
3989
4016
  rootDir: config.rootDir,
@@ -4016,6 +4043,53 @@ const buildHydratedReplacements = (hydratedFlag, hydratedFlagHead) => {
4016
4043
  return replacements;
4017
4044
  };
4018
4045
  //#endregion
4046
+ //#region src/compiler/bundle/build-conditionals-plugin.ts
4047
+ const BUILD_FLAG_RE = /\bBUILD(?:\$\d+)?\.([A-Za-z_$][\w$]*)\b/g;
4048
+ /**
4049
+ * Scoped by `id` to Stencil's own resolved internal runtime module(s) only
4050
+ * and only when the `jsMinifier` = `oxc`.
4051
+ *
4052
+ * Replaces `BUILD.<flag>` reads with their literal values, so a minifier's basic literal-boolean
4053
+ * folding (e.g. `false && x` -> nothing) can eliminate the resulting dead branches.
4054
+ * Oxc cannot dead-code-eliminate using `BUILD.<flag>` reads directly.
4055
+ *
4056
+ * @param config the Stencil configuration for the project
4057
+ * @param buildConditionals the build conditionals for this build
4058
+ * @returns a rolldown plugin, or null if this build doesn't need it
4059
+ */
4060
+ const buildConditionalsPlugin = (config, buildConditionals) => {
4061
+ if (config.jsMinifier !== "oxc" || !buildConditionals) return null;
4062
+ const literals = getBuildConditionalsLiterals(buildConditionals);
4063
+ if (literals.size === 0) return null;
4064
+ const compilerExe = config.sys.getCompilerExecutingPath();
4065
+ const internalClient = getStencilInternalModule(config, compilerExe, "client/runtime.js");
4066
+ const internalSsr = getStencilInternalModule(config, compilerExe, "server/index.mjs");
4067
+ return {
4068
+ name: "stencil-build-conditionals",
4069
+ transform: {
4070
+ filter: {
4071
+ id: getStencilInternalModuleFilter(internalClient, internalSsr),
4072
+ code: /\bBUILD(?:\$\d+)?\.\w/
4073
+ },
4074
+ handler(code) {
4075
+ const s = new MagicString(code);
4076
+ let didReplace = false;
4077
+ for (const match of code.matchAll(BUILD_FLAG_RE)) {
4078
+ const literal = literals.get(match[1]);
4079
+ if (literal === void 0) continue;
4080
+ s.overwrite(match.index, match.index + match[0].length, literal);
4081
+ didReplace = true;
4082
+ }
4083
+ if (!didReplace) return null;
4084
+ return {
4085
+ code: s.toString(),
4086
+ map: s.generateMap({ hires: true })
4087
+ };
4088
+ }
4089
+ }
4090
+ };
4091
+ };
4092
+ //#endregion
4019
4093
  //#region src/compiler/bundle/constants.ts
4020
4094
  const DEV_MODULE_DIR = `~dev-module`;
4021
4095
  //#endregion
@@ -4250,9 +4324,10 @@ const extTransformsPlugin = (config, compilerCtx, buildCtx) => {
4250
4324
  if (typeof code !== "string") compilerCtx.cssTransformCache.set(id, null);
4251
4325
  else {
4252
4326
  const pluginTransforms = await runPluginTransformsEsmImports(config, compilerCtx, buildCtx, code, filePath);
4327
+ const cssInput = data.tag ? pluginTransforms.code : inlineRelativeCssUrlAssets(pluginTransforms.code, filePath);
4253
4328
  const cssTransformResults = await compilerCtx.worker.transformCssToEsm({
4254
4329
  file: pluginTransforms.id,
4255
- input: pluginTransforms.code,
4330
+ input: cssInput,
4256
4331
  tag: data.tag,
4257
4332
  tags: buildCtx.components.map((c) => c.tagName),
4258
4333
  addTagTransformers: !!buildCtx.config.compat.additionalTagTransformers,
@@ -4340,13 +4415,46 @@ const extTransformsPlugin = (config, compilerCtx, buildCtx) => {
4340
4415
  return {
4341
4416
  code: cacheEntry.cssTransformOutput.output,
4342
4417
  map: cacheEntry.cssTransformOutput.map,
4343
- moduleSideEffects: false
4418
+ moduleSideEffects: cacheEntry.cssTransformOutput.moduleSideEffects ?? false
4344
4419
  };
4345
4420
  }
4346
4421
  return null;
4347
4422
  }
4348
4423
  };
4349
4424
  };
4425
+ /**
4426
+ * 3rd-party stylesheets with relative `url(./font.ttf)` (font-face `src`, a background-image, ...)
4427
+ * have nowhere to resolve that path once this CSS is self-injected as a CSSStyleSheet:
4428
+ * there's no bundler output location for it to be relative *to*.
4429
+ * Inlining the referenced file as a `data:` URI sidesteps needing one - no separate asset
4430
+ * to serve, works the same regardless of how/where the final bundle is deployed.
4431
+ */
4432
+ const CSS_URL_RE = /url\(\s*(['"]?)([^'"()]+)\1\s*\)/g;
4433
+ const CSS_URL_ASSET_MIME_TYPES = {
4434
+ ttf: "font/ttf",
4435
+ otf: "font/otf",
4436
+ woff: "font/woff",
4437
+ woff2: "font/woff2",
4438
+ eot: "application/vnd.ms-fontobject",
4439
+ png: "image/png",
4440
+ jpg: "image/jpeg",
4441
+ jpeg: "image/jpeg",
4442
+ gif: "image/gif",
4443
+ svg: "image/svg+xml"
4444
+ };
4445
+ const inlineRelativeCssUrlAssets = (cssText, cssFilePath) => cssText.replace(CSS_URL_RE, (original, _quote, url) => {
4446
+ if (/^(data:|[a-z][a-z0-9+.-]*:|\/\/|\/)/i.test(url)) return original;
4447
+ const cleanUrl = url.split(/[?#]/)[0];
4448
+ const ext = cleanUrl.split(".").pop()?.toLowerCase();
4449
+ const mimeType = ext && CSS_URL_ASSET_MIME_TYPES[ext];
4450
+ if (!mimeType) return original;
4451
+ try {
4452
+ const assetPath = resolve(dirname(cssFilePath), cleanUrl);
4453
+ return `url("data:${mimeType};base64,${readFileSync(assetPath).toString("base64")}")`;
4454
+ } catch {
4455
+ return original;
4456
+ }
4457
+ });
4350
4458
  //#endregion
4351
4459
  //#region src/compiler/bundle/file-load-plugin.ts
4352
4460
  const RESOLVE_EXTENSIONS = [
@@ -4482,11 +4590,13 @@ const pluginHelper = (config, builtCtx, platform) => {
4482
4590
  handler(importee, importer) {
4483
4591
  if (importee.endsWith("/")) importee = importee.slice(0, -1);
4484
4592
  if (builtIns.has(importee)) {
4593
+ const alias = config.nodeResolve?.alias;
4594
+ if (alias?.[importee] ?? alias?.[`${importee}$`]) return null;
4485
4595
  let fromMsg = "";
4486
4596
  if (importer) fromMsg = ` from ${relative$1(config.rootDir, importer)}`;
4487
4597
  const diagnostic = buildError(builtCtx.diagnostics);
4488
4598
  diagnostic.header = `Node Polyfills Required`;
4489
- diagnostic.messageText = `For the import "${importee}" to be bundled${fromMsg}, ensure the "rolldown-plugin-node-polyfills" plugin is installed and added to the stencil config plugins (${platform}). Please see the bundling docs for more information.
4599
+ diagnostic.messageText = `For the import "${importee}" to be bundled${fromMsg}, ensure the "@rolldown/plugin-node-polyfills" plugin is installed and added to the stencil config plugins (${platform}). Please see the bundling docs for more information.
4490
4600
  Further information: https://stenciljs.com/docs/module-bundling`;
4491
4601
  }
4492
4602
  return null;
@@ -4713,7 +4823,59 @@ const userIndexPlugin = (config, compilerCtx) => {
4713
4823
  };
4714
4824
  };
4715
4825
  //#endregion
4716
- //#region src/compiler/optimize/minify-js.ts
4826
+ //#region src/compiler/optimize/minify-js-oxc.ts
4827
+ /**
4828
+ * Performs the minification of JavaScript source using oxc
4829
+ * @param input the JavaScript source to minify
4830
+ * @param opts the options used by the minifier
4831
+ * @returns the resulting minified JavaScript
4832
+ */
4833
+ const minifyJsOxc = async (input, opts) => {
4834
+ const results = {
4835
+ output: input,
4836
+ sourceMap: null,
4837
+ diagnostics: []
4838
+ };
4839
+ try {
4840
+ const minifyResult = minifySync("module.js", input, opts);
4841
+ if (minifyResult.errors.length > 0) {
4842
+ loadMinifyJsOxcDiagnostics(results.diagnostics, minifyResult.errors);
4843
+ return results;
4844
+ }
4845
+ results.output = minifyResult.code;
4846
+ results.sourceMap = minifyResult.map ? {
4847
+ file: minifyResult.map.file ?? "module.js",
4848
+ mappings: minifyResult.map.mappings,
4849
+ names: minifyResult.map.names,
4850
+ sourceRoot: minifyResult.map.sourceRoot,
4851
+ sources: minifyResult.map.sources,
4852
+ sourcesContent: minifyResult.map.sourcesContent,
4853
+ version: minifyResult.map.version
4854
+ } : null;
4855
+ } catch (e) {
4856
+ if (e instanceof Error) console.log(e.stack);
4857
+ loadMinifyJsOxcDiagnostics(results.diagnostics, [{
4858
+ message: String(e),
4859
+ codeframe: null
4860
+ }]);
4861
+ }
4862
+ return results;
4863
+ };
4864
+ const loadMinifyJsOxcDiagnostics = (diagnostics, errors) => {
4865
+ for (const error of errors) diagnostics.push({
4866
+ level: "error",
4867
+ type: "build",
4868
+ language: "javascript",
4869
+ header: "Minify JS (oxc)",
4870
+ code: "",
4871
+ messageText: error.codeframe ?? error.message,
4872
+ absFilePath: void 0,
4873
+ relFilePath: void 0,
4874
+ lines: []
4875
+ });
4876
+ };
4877
+ //#endregion
4878
+ //#region src/compiler/optimize/minify-js-terser.ts
4717
4879
  /**
4718
4880
  * Performs the minification of JavaScript source
4719
4881
  * @param input the JavaScript source to minify
@@ -4732,14 +4894,6 @@ const minifyJs = async (input, opts) => {
4732
4894
  const mangleProperties = mangle.properties;
4733
4895
  if (mangleProperties && mangleProperties.regex) mangleProperties.regex = new RegExp(mangleProperties.regex);
4734
4896
  }
4735
- if (opts.sourceMap)
4736
- /**
4737
- * sourceMap, when used in conjunction with compress, can lead to sourcemaps that don't in every browser. despite
4738
- * there being a sourcemap spec, each browser has it's own tricks for trying to get sourcemaps to properly map
4739
- * minified JS back to its original form. for the most consistent results across all browsers, explicitly disable
4740
- * compress.
4741
- */
4742
- opts.compress = void 0;
4743
4897
  }
4744
4898
  try {
4745
4899
  const minifyResults = await minify(input, opts);
@@ -4845,7 +4999,8 @@ const optimizeModule = async (config, compilerCtx, opts) => {
4845
4999
  sourceMap: opts.sourceMap
4846
5000
  };
4847
5001
  const isDebug = config.logLevel === "debug";
4848
- const cacheKey = await compilerCtx.cache.createKey("optimizeModule", getToolVersion("terser"), opts, isDebug);
5002
+ const jsMinifier = config.jsMinifier;
5003
+ const cacheKey = await compilerCtx.cache.createKey("optimizeModule", jsMinifier, getToolVersion(jsMinifier === "oxc" ? "rolldown" : "terser"), opts, isDebug);
4849
5004
  const cachedContent = await compilerCtx.cache.get(cacheKey);
4850
5005
  if (cachedContent != null) {
4851
5006
  const cachedMap = await compilerCtx.cache.get(cacheKey + "Map");
@@ -4855,8 +5010,26 @@ const optimizeModule = async (config, compilerCtx, opts) => {
4855
5010
  sourceMap: cachedMap ? JSON.parse(cachedMap) : null
4856
5011
  };
4857
5012
  }
4858
- const minifyOpts = getTerserOptions(config, opts.sourceTarget, isDebug);
4859
5013
  const code = opts.input;
5014
+ const results = jsMinifier === "oxc" ? await minifyJsOxc(code, getOxcMinifyOptions(config, opts, isDebug)) : await compilerCtx.worker.prepareModule(code, getTerserMinifyOptions(config, opts, isDebug));
5015
+ if (results != null && typeof results.output === "string" && results.diagnostics.length === 0 && compilerCtx != null) {
5016
+ if (opts.isCore) results.output = results.output.replace(/disconnectedCallback\(\)\{\},/g, "");
5017
+ await compilerCtx.cache.put(cacheKey, results.output);
5018
+ if (results.sourceMap) await compilerCtx.cache.put(cacheKey + "Map", JSON.stringify(results.sourceMap));
5019
+ }
5020
+ return results;
5021
+ };
5022
+ /**
5023
+ * Builds the terser options for a specific module being optimized, layering the module's
5024
+ * `isCore`/source map needs on top of the baseline options from {@link getTerserOptions}.
5025
+ *
5026
+ * @param config the Stencil configuration file that was provided as a part of the build step
5027
+ * @param opts the options for the module being optimized
5028
+ * @param isDebug if true, set the necessary flags to produce readable, debuggable output
5029
+ * @returns the minification options to hand to terser
5030
+ */
5031
+ const getTerserMinifyOptions = (config, opts, isDebug) => {
5032
+ const minifyOpts = getTerserOptions(config, opts.sourceTarget, isDebug);
4860
5033
  if (config.sourceMap) minifyOpts.sourceMap = { content: opts.sourceMap != null ? {
4861
5034
  ...opts.sourceMap,
4862
5035
  version: 3
@@ -4878,13 +5051,7 @@ const optimizeModule = async (config, compilerCtx, opts) => {
4878
5051
  compressOpts.unsafe = true;
4879
5052
  compressOpts.unsafe_undefined = true;
4880
5053
  }
4881
- const results = await compilerCtx.worker.prepareModule(code, minifyOpts);
4882
- if (results != null && typeof results.output === "string" && results.diagnostics.length === 0 && compilerCtx != null) {
4883
- if (opts.isCore) results.output = results.output.replace(/disconnectedCallback\(\)\{\},/g, "");
4884
- await compilerCtx.cache.put(cacheKey, results.output);
4885
- if (results.sourceMap) await compilerCtx.cache.put(cacheKey + "Map", JSON.stringify(results.sourceMap));
4886
- }
4887
- return results;
5054
+ return minifyOpts;
4888
5055
  };
4889
5056
  /**
4890
5057
  * Builds a configuration object to be used by Terser for the purposes of minifying a user's JavaScript
@@ -4941,6 +5108,81 @@ function getTerserManglePropertiesConfig() {
4941
5108
  };
4942
5109
  }
4943
5110
  /**
5111
+ * Builds the oxc (rolldown minifier) options for a specific module being optimized.
5112
+ *
5113
+ * A few terser knobs have no oxc equivalent and so are dropped:
5114
+ * - `global_defs` (used to fold `supportsListenerOptions` to `true` in the core runtime bundle)
5115
+ * - `unsafe`/`unsafe_undefined`/`inline` compress passes
5116
+ * - `passes` (oxc's compressor iterates to a fix point automatically)
5117
+ *
5118
+ * @param config the Stencil configuration file that was provided as a part of the build step
5119
+ * @param opts the options for the module being optimized
5120
+ * @param isDebug if true, set the necessary flags to produce readable, debuggable output
5121
+ * @returns the minification options to hand to oxc
5122
+ */
5123
+ const getOxcMinifyOptions = (config, opts, isDebug) => {
5124
+ const minifyOpts = {
5125
+ module: true,
5126
+ sourcemap: !!config.sourceMap,
5127
+ inputMap: config.sourceMap ? opts.sourceMap ?? void 0 : void 0,
5128
+ mangleProps: getOxcManglePropertiesConfig(isDebug)
5129
+ };
5130
+ if (isDebug) {
5131
+ minifyOpts.mangle = false;
5132
+ minifyOpts.compress = {
5133
+ dropConsole: false,
5134
+ dropDebugger: false
5135
+ };
5136
+ minifyOpts.codegen = {
5137
+ removeWhitespace: false,
5138
+ legalComments: "inline"
5139
+ };
5140
+ } else {
5141
+ minifyOpts.mangle = { toplevel: true };
5142
+ minifyOpts.compress = { treeshake: {
5143
+ propertyReadSideEffects: false,
5144
+ manualPureFunctions: opts.isCore ? ["getHostRef"] : []
5145
+ } };
5146
+ }
5147
+ return minifyOpts;
5148
+ };
5149
+ /**
5150
+ * `ComponentRuntimeMeta` (the shape of a component class's static `cmpMeta` getter) is
5151
+ * produced by one compiled unit and read by another (e.g. a component's own chunk vs the
5152
+ * SSR/hydrate runtime, or a lazy component's entry chunk vs the core runtime chunk).
5153
+ *
5154
+ * Oxc's mangleProps` has been observed to mangle a property at its read site but leave the same
5155
+ * property's key unmangled silently breaking that read (e.g. `cmpMeta.$tagName$` reads as `undefined`).
5156
+ * Reserving these names avoids the mismatch entirely.
5157
+ *
5158
+ * Assess in time with rolldown / oxc updates via `cd test/build/output && pnpm test`
5159
+ */
5160
+ const RESERVED_CMP_META_PROPS = [
5161
+ "$flags$",
5162
+ "$tagName$",
5163
+ "$members$",
5164
+ "$listeners$",
5165
+ "$attrsToReflect$",
5166
+ "$watchers$",
5167
+ "$lazyBundleId$",
5168
+ "$serializers$",
5169
+ "$deserializers$"
5170
+ ];
5171
+ /**
5172
+ * Get baseline configuration for oxc's `mangleProps` option, mirroring
5173
+ * {@link getTerserManglePropertiesConfig}.
5174
+ *
5175
+ * @param isDebug if true, produce readable `_$name$_`-style output names instead of minified ones
5176
+ * @returns an object with our baseline property mangling configuration
5177
+ */
5178
+ function getOxcManglePropertiesConfig(isDebug) {
5179
+ return {
5180
+ include: /^\$.+\$$/,
5181
+ reserved: ["$hostElement$", ...RESERVED_CMP_META_PROPS],
5182
+ debug: isDebug
5183
+ };
5184
+ }
5185
+ /**
4944
5186
  * This method is likely to be called by a worker on the compiler context, rather than directly.
4945
5187
  * @param input the source code to minify
4946
5188
  * @param minifyOpts options to be used by the minifier
@@ -5089,7 +5331,7 @@ const buildWorker = async (config, compilerCtx, buildCtx, ctx, workerEntryPath)
5089
5331
  let code = entryPoint.code;
5090
5332
  const results = await optimizeModule(config, compilerCtx, {
5091
5333
  input: code,
5092
- sourceTarget: "es2017",
5334
+ sourceTarget: "es2022",
5093
5335
  isCore: false,
5094
5336
  minify: config.minifyJs,
5095
5337
  inlineHelpers: true
@@ -5393,6 +5635,7 @@ const getRolldownOptions = (config, compilerCtx, buildCtx, bundleOpts) => {
5393
5635
  },
5394
5636
  coreResolvePlugin(config, compilerCtx, bundleOpts.platform, !!bundleOpts.externalRuntime, bundleOpts.conditionals?.lazyLoad ?? false),
5395
5637
  appDataPlugin(config, compilerCtx, buildCtx, bundleOpts.conditionals, bundleOpts.platform),
5638
+ buildConditionalsPlugin(config, bundleOpts.conditionals),
5396
5639
  lazyComponentPlugin(buildCtx),
5397
5640
  loaderPlugin(bundleOpts.loader),
5398
5641
  userIndexPlugin(config, compilerCtx),
@@ -6569,10 +6812,6 @@ const addStaticImports = (rolldownChunkResults, bundleModules) => {
6569
6812
  const generateCjs = isCjsFormat(index) ? generateCaseClauseCjs : generateCaseClause;
6570
6813
  index.code = index.code.replace("/*!__STENCIL_STATIC_IMPORT_SWITCH__*/", `
6571
6814
  if (!hmrVersionId || !BUILD.hotModuleReplacement) {
6572
- const processMod = importedModule => {
6573
- cmpModules.set(bundleId, importedModule);
6574
- return importedModule[exportName];
6575
- }
6576
6815
  switch(bundleId) {
6577
6816
  ${bundleModules.map((mod) => generateCjs(mod.output.bundleId)).join("")}
6578
6817
  }
@@ -6606,7 +6845,7 @@ const generateCaseClause = (bundleId) => {
6606
6845
  case '${bundleId}':
6607
6846
  return import(
6608
6847
  /* webpackMode: "lazy" */
6609
- './${bundleId}.entry.js').then(processMod, consoleError);`;
6848
+ './${bundleId}.entry.js').then(onLoad, onError);`;
6610
6849
  };
6611
6850
  /**
6612
6851
  * Generate a 'case' clause to be used within a `switch` statement. The case clause generated will key-off the provided
@@ -6619,7 +6858,7 @@ const generateCaseClauseCjs = (bundleId) => {
6619
6858
  case '${bundleId}':
6620
6859
  return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(
6621
6860
  /* webpackMode: "lazy" */
6622
- './${bundleId}.entry.js')); }).then(processMod, consoleError);`;
6861
+ './${bundleId}.entry.js')); }).then(onLoad, onError);`;
6623
6862
  };
6624
6863
  const generateLazyEntryModule = async (config, compilerCtx, buildCtx, rolldownResult, outputTargetType, destinations, sourceTarget, shouldMinify, isBrowserBuild) => {
6625
6864
  const entryModule = buildCtx.entryModules.find((em) => em.entryKey === rolldownResult.entryKey);
@@ -6847,7 +7086,7 @@ const generateCjs = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
6847
7086
  const results = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
6848
7087
  if (results != null) {
6849
7088
  const destinations = cjsOutputs.map((o) => o.cjsDir).filter((cjsDir) => typeof cjsDir === "string");
6850
- buildCtx.commonJsComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, destinations, results, "es2017", false);
7089
+ buildCtx.commonJsComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, destinations, results, "es2022", false);
6851
7090
  await generateShortcuts$1(compilerCtx, results, cjsOutputs);
6852
7091
  }
6853
7092
  }
@@ -12688,6 +12927,7 @@ const IS_CASE_SENSITIVE_FILE_NAMES = !(process.platform === "win32");
12688
12927
  //#endregion
12689
12928
  //#region src/compiler/sys/typescript/typescript-sys.ts
12690
12929
  const patchTsSystemFileSystem = (config, compilerSys, inMemoryFs, tsSys) => {
12930
+ if (!tsSys) return;
12691
12931
  const realpath = (path) => {
12692
12932
  const rp = compilerSys.realpathSync(path);
12693
12933
  if (isString$1(rp)) return rp;
@@ -12765,6 +13005,7 @@ const patchTsSystemFileSystem = (config, compilerSys, inMemoryFs, tsSys) => {
12765
13005
  return tsSys;
12766
13006
  };
12767
13007
  const patchTsSystemWatch = (compilerSystem, tsSys) => {
13008
+ if (!tsSys) return;
12768
13009
  tsSys.watchDirectory = (p, cb, recursive) => {
12769
13010
  const watcher = compilerSystem.watchDirectory(p, (filePath) => {
12770
13011
  cb(filePath);
@@ -12788,26 +13029,6 @@ const patchTypescript = (config, inMemoryFs) => {
12788
13029
  patchTsSystemFileSystem(config, config.sys, inMemoryFs, ts.sys);
12789
13030
  patchTsSystemWatch(config.sys, ts.sys);
12790
13031
  };
12791
- const patchTypeScriptSysMinimum = () => {
12792
- if (!ts.sys) ts.sys = {
12793
- args: [],
12794
- createDirectory: noop,
12795
- directoryExists: () => false,
12796
- exit: noop,
12797
- fileExists: () => false,
12798
- getCurrentDirectory: process.cwd,
12799
- getDirectories: () => [],
12800
- getExecutingFilePath: () => "./",
12801
- readDirectory: () => [],
12802
- readFile: noop,
12803
- newLine: "\n",
12804
- resolvePath: resolve$2,
12805
- useCaseSensitiveFileNames: false,
12806
- write: noop,
12807
- writeFile: noop
12808
- };
12809
- };
12810
- patchTypeScriptSysMinimum();
12811
13032
  const getTypescriptPathFromUrl = (config, tsExecutingUrl, url) => {
12812
13033
  const tsBaseUrl = new URL("..", tsExecutingUrl).href;
12813
13034
  if (url.startsWith(tsBaseUrl)) {
@@ -15251,6 +15472,22 @@ const parseStaticWatchers = (staticMembers) => {
15251
15472
  //#endregion
15252
15473
  //#region src/compiler/transformers/static-to-meta/class-extension/shared.ts
15253
15474
  /**
15475
+ * Warns when an `extends`/`Mixin(...)` target resolved to *something* but no class declaration
15476
+ * could be found inside it - e.g. a mixin factory whose class isn't a named declaration
15477
+ * (`(Base) => class extends Base {}` rather than `(Base) => { class Foo extends Base {} return
15478
+ * Foo; }`). Without this, the target is silently dropped: any `@Prop`/`@State` etc. it declares
15479
+ * just never appears on the extending component, with no diagnostic explaining why.
15480
+ * @param buildCtx used to surface the warning - omit to warn silently (e.g. from tests)
15481
+ * @param targetName the identifier the target was reached through
15482
+ * @param anchor the node to attach the warning to
15483
+ */
15484
+ function warnMixinFactoryClassNotFound(buildCtx, targetName, anchor) {
15485
+ if (!buildCtx) return;
15486
+ const err = buildWarn(buildCtx.diagnostics);
15487
+ err.messageText = `Found "${targetName}", but couldn't find a class declaration inside it. If it's meant to be a mixin factory, make sure it declares and returns a named class, e.g. \`(Base) => { class ${targetName}Class extends Base {} return ${targetName}Class; }\` - a factory that returns a class expression directly (\`(Base) => class extends Base {}\`) isn't recognized, and any \`@Prop\`/\`@State\`/etc. it declares won't be applied.`;
15488
+ if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, anchor);
15489
+ }
15490
+ /**
15254
15491
  * Walks the AST looking for a class declaration, optionally by name - descends
15255
15492
  * into a mixin factory's wrapping function (arrow function or `function`
15256
15493
  * declaration) body too, since a mixin factory's class is always nested one
@@ -15453,6 +15690,7 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
15453
15690
  if (!foundClassDeclaration && matchedStatement) {
15454
15691
  foundClassDeclaration = findClassWalk(matchedStatement);
15455
15692
  keepLooking = false;
15693
+ if (!foundClassDeclaration) warnMixinFactoryClassNotFound(buildCtx, className, classDeclaration);
15456
15694
  }
15457
15695
  if (foundClassDeclaration && !dependentClasses.some((dc) => dc.classNode === foundClassDeclaration)) {
15458
15696
  dependentClasses.push({
@@ -15508,6 +15746,7 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
15508
15746
  foundClassDeclaration = findClassWalk(node);
15509
15747
  if (!node) throw "revert to sad path";
15510
15748
  keepLooking = false;
15749
+ if (!foundClassDeclaration) warnMixinFactoryClassNotFound(buildCtx, extendee.getText(), classDeclaration);
15511
15750
  }
15512
15751
  if (foundClassDeclaration && !dependentClasses.some((dc) => dc.classNode === foundClassDeclaration)) {
15513
15752
  const foundModule = compilerCtx.moduleMap.get(foundClassDeclaration.getSourceFile().fileName);
@@ -15538,6 +15777,7 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
15538
15777
  else if (matchedStatement) {
15539
15778
  foundClassDeclaration = findClassWalk(matchedStatement);
15540
15779
  keepLooking = false;
15780
+ if (!foundClassDeclaration) warnMixinFactoryClassNotFound(buildCtx, extendee.getText(), classDeclaration);
15541
15781
  } else {
15542
15782
  foundClassDeclaration = findClassWalk(currentSource, extendee.getText());
15543
15783
  keepLooking = false;
@@ -15971,6 +16211,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
15971
16211
  else {
15972
16212
  foundClass = findClassWalk(sameFileStatement);
15973
16213
  keepLooking = false;
16214
+ if (!foundClass) warnMixinFactoryClassNotFound(buildCtx, parentName, rootClassDeclaration);
15974
16215
  }
15975
16216
  } else {
15976
16217
  const specifier = findImportSpecifier(sf, parentName);
@@ -15998,6 +16239,7 @@ function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors
15998
16239
  else {
15999
16240
  foundClass = findClassWalk(found.statement);
16000
16241
  keepLooking = false;
16242
+ if (!foundClass) warnMixinFactoryClassNotFound(buildCtx, parentName, rootClassDeclaration);
16001
16243
  }
16002
16244
  }
16003
16245
  if (!foundClass || ancestors.some((a) => a.classNode === foundClass)) continue;
@@ -16727,7 +16969,7 @@ const parseCollectionComponents = (config, compilerCtx, buildCtx, collectionDir,
16727
16969
  };
16728
16970
  const transpileCollectionModule = (config, compilerCtx, buildCtx, collection, inputFileName) => {
16729
16971
  const sourceText = compilerCtx.fs.readFileSync(inputFileName);
16730
- const sourceFile = ts.createSourceFile(inputFileName, sourceText, ts.ScriptTarget.ES2017, true, ts.ScriptKind.JS);
16972
+ const sourceFile = ts.createSourceFile(inputFileName, sourceText, ts.ScriptTarget.ES2022, true, ts.ScriptKind.JS);
16731
16973
  return updateModule(config, compilerCtx, buildCtx, sourceFile, sourceText, inputFileName, void 0, collection);
16732
16974
  };
16733
16975
  //#endregion
@@ -20389,6 +20631,7 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
20389
20631
  logger,
20390
20632
  minifyCss: config.minifyCss ?? !devMode,
20391
20633
  minifyJs: config.minifyJs ?? !devMode,
20634
+ jsMinifier: config.jsMinifier ?? "oxc",
20392
20635
  outputTargets: config.outputTargets ?? [],
20393
20636
  rolldownConfig: validateRolldownConfig(config),
20394
20637
  sourceMap: config.sourceMap === true || devMode && (config.sourceMap === "dev" || typeof config.sourceMap === "undefined"),
@@ -22897,29 +23140,36 @@ const generateTransformCssToEsm = (input, results) => {
22897
23140
  results.styleText = results.styleText.replace(/\\/g, "\\\\").replace(/\n/g, " ").replace(/\r/g, " ").replace(/\t/g, " ").replace(/\u000c/g, "\\\\f").replace(/\u0008/g, "\\\\b").replace(/\u000b/g, "\\\\v").replace(/\0/g, "\\\\0").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
22898
23141
  if (input.addTagTransformers) results.styleText = addTagTransformToCssString(results.styleText, input.tags);
22899
23142
  results.styleText = stripCssComments(results.styleText);
23143
+ const isComponentStyle = isString$1(input.tag);
23144
+ const defaultAssignment = `const ${results.defaultVarName} = ${isComponentStyle ? "() => " : ""}`;
22900
23145
  if (input.module === "cjs") {
22901
23146
  if (input.addTagTransformers) s.append(`const ${TRANSFORM_TAG} = require('${STENCIL_CORE_ID}').transformTag;\n`);
23147
+ if (!isComponentStyle) s.append(`const ${INJECT_SIDE_EFFECT_STYLE} = require('${STENCIL_CORE_ID}').injectSideEffectStyle;\n`);
22902
23148
  results.imports.forEach((cssImport) => {
22903
23149
  s.append(`const ${cssImport.varName} = require('${cssImport.importPath}');\n`);
22904
23150
  });
22905
- s.append(`const ${results.defaultVarName} = () => `);
23151
+ s.append(defaultAssignment);
22906
23152
  results.imports.forEach((cssImport) => {
22907
23153
  s.append(`${cssImport.varName} + `);
22908
23154
  });
22909
23155
  s.append(`\`${results.styleText}\`;\n`);
23156
+ if (!isComponentStyle) s.append(`${INJECT_SIDE_EFFECT_STYLE}(${results.defaultVarName});\n`);
22910
23157
  s.append(`module.exports = ${results.defaultVarName};`);
22911
23158
  } else {
22912
23159
  if (input.addTagTransformers) s.append(`import { transformTag as ${TRANSFORM_TAG} } from '${STENCIL_CORE_ID}';\n`);
23160
+ if (!isComponentStyle) s.append(`import { injectSideEffectStyle as ${INJECT_SIDE_EFFECT_STYLE} } from '${STENCIL_CORE_ID}';\n`);
22913
23161
  results.imports.forEach((cssImport) => {
22914
23162
  s.append(`import ${cssImport.varName} from '${cssImport.importPath}';\n`);
22915
23163
  });
22916
- s.append(`const ${results.defaultVarName} = () => `);
23164
+ s.append(defaultAssignment);
22917
23165
  results.imports.forEach((cssImport) => {
22918
23166
  s.append(`${cssImport.varName} + `);
22919
23167
  });
22920
23168
  s.append(`\`${results.styleText}\`;\n`);
23169
+ if (!isComponentStyle) s.append(`${INJECT_SIDE_EFFECT_STYLE}(${results.defaultVarName});\n`);
22921
23170
  s.append(`export default ${results.defaultVarName};`);
22922
23171
  }
23172
+ results.moduleSideEffects = !isComponentStyle;
22923
23173
  results.output = s.toString();
22924
23174
  return results;
22925
23175
  };
@@ -22947,6 +23197,7 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
22947
23197
  isNodeModule: false
22948
23198
  };
22949
23199
  if (!isLocalCssImport(cssImportData.srcImportText)) continue;
23200
+ else if (cssImportData.url === "stencil-globals" || cssImportData.url === "stencil-hydrate") continue;
22950
23201
  else if (isCssNodeModule(cssImportData.url)) {
22951
23202
  cssImportData.filePath = cssImportData.url.substring(1);
22952
23203
  cssImportData.isNodeModule = true;
@@ -24458,8 +24709,8 @@ const transpileModule = (config, input, transformOpts) => {
24458
24709
  getDefaultLibFileName: () => `lib.d.ts`,
24459
24710
  useCaseSensitiveFileNames: () => false,
24460
24711
  getCanonicalFileName: (fileName) => fileName,
24461
- getCurrentDirectory: () => transformOpts.currentDirectory || process.cwd(),
24462
- getNewLine: () => ts.sys.newLine || "\n",
24712
+ getCurrentDirectory: () => transformOpts.currentDirectory || (typeof process !== "undefined" ? process.cwd() : "/"),
24713
+ getNewLine: () => ts.sys && ts.sys.newLine || "\n",
24463
24714
  fileExists: (fileName) => normalizePath(fileName) === normalizePath(sourceFilePath),
24464
24715
  readFile: () => "",
24465
24716
  directoryExists: () => true,