diff --git a/src/compiler/bundle/bundle-interface.ts b/src/compiler/bundle/bundle-interface.ts index 35c726383b8..3708619fd57 100644 --- a/src/compiler/bundle/bundle-interface.ts +++ b/src/compiler/bundle/bundle-interface.ts @@ -18,7 +18,11 @@ export interface BundleOptions { */ externalRuntime?: boolean; platform: 'client' | 'hydrate' | 'worker'; - customTransformers?: TransformerFactory[]; + /** + * A collection of TypeScript transformation factories to apply during the "before" stage of the TypeScript + * compilation pipeline (before built-in .js transformations) + */ + customBeforeTransformers?: TransformerFactory[]; /** * This is equivalent to the Rollup `input` configuration option. It's * an object mapping names to entry points which tells Rollup to bundle diff --git a/src/compiler/bundle/typescript-plugin.ts b/src/compiler/bundle/typescript-plugin.ts index 40bdd136616..30ff0b704b8 100644 --- a/src/compiler/bundle/typescript-plugin.ts +++ b/src/compiler/bundle/typescript-plugin.ts @@ -57,7 +57,9 @@ export const typescriptPlugin = (compilerCtx: d.CompilerCtx, bundleOpts: BundleO const tsResult = ts.transpileModule(mod.staticSourceFileText, { compilerOptions: config.tsCompilerOptions, fileName: mod.sourceFilePath, - transformers: { before: bundleOpts.customTransformers }, + transformers: { + before: bundleOpts.customBeforeTransformers ?? [], + }, }); const sourceMap: d.SourceMap = tsResult.sourceMapText ? JSON.parse(tsResult.sourceMapText) : null; return { code: tsResult.outputText, map: sourceMap }; diff --git a/src/compiler/output-targets/dist-custom-elements/index.ts b/src/compiler/output-targets/dist-custom-elements/index.ts index 43288dd3c0c..4403f6bc3e3 100644 --- a/src/compiler/output-targets/dist-custom-elements/index.ts +++ b/src/compiler/output-targets/dist-custom-elements/index.ts @@ -20,6 +20,7 @@ import { addDefineCustomElementFunctions } from '../../transformers/component-na import { proxyCustomElement } from '../../transformers/component-native/proxy-custom-element-function'; import { nativeComponentTransform } from '../../transformers/component-native/tranform-to-native-component'; import { removeCollectionImports } from '../../transformers/remove-collection-imports'; +import { rewriteAliasedSourceFileImportPaths } from '../../transformers/rewrite-aliased-paths'; import { updateStencilCoreImports } from '../../transformers/update-stencil-core-import'; import { getCustomElementsBuildConditionals } from './custom-elements-build-conditionals'; @@ -75,7 +76,7 @@ export const getBundleOptions = ( id: 'customElements', platform: 'client', conditionals: getCustomElementsBuildConditionals(config, buildCtx.components), - customTransformers: getCustomElementCustomTransformer(config, compilerCtx, buildCtx.components, outputTarget), + customBeforeTransformers: getCustomBeforeTransformers(config, compilerCtx, buildCtx.components, outputTarget), externalRuntime: !!outputTarget.externalRuntime, inlineWorkers: true, inputs: { @@ -314,7 +315,7 @@ export const generateEntryPoint = ( * @param outputTarget the output target configuration * @returns a list of transformers to use in the transpilation process */ -const getCustomElementCustomTransformer = ( +const getCustomBeforeTransformers = ( config: d.ValidatedConfig, compilerCtx: d.CompilerCtx, components: d.ComponentCompilerMeta[], @@ -329,11 +330,19 @@ const getCustomElementCustomTransformer = ( style: 'static', styleImportData: 'queryparams', }; - return [ + const customBeforeTransformers = [ addDefineCustomElementFunctions(compilerCtx, components, outputTarget), updateStencilCoreImports(transformOpts.coreImportPath), + ]; + + if (config.transformAliasedImportPaths) { + customBeforeTransformers.push(rewriteAliasedSourceFileImportPaths); + } + + customBeforeTransformers.push( nativeComponentTransform(compilerCtx, transformOpts), proxyCustomElement(compilerCtx, transformOpts), - removeCollectionImports(compilerCtx), - ]; + removeCollectionImports(compilerCtx) + ); + return customBeforeTransformers; }; diff --git a/src/compiler/output-targets/dist-hydrate-script/bundle-hydrate-factory.ts b/src/compiler/output-targets/dist-hydrate-script/bundle-hydrate-factory.ts index 78aa3021179..55042b51eb2 100644 --- a/src/compiler/output-targets/dist-hydrate-script/bundle-hydrate-factory.ts +++ b/src/compiler/output-targets/dist-hydrate-script/bundle-hydrate-factory.ts @@ -1,4 +1,5 @@ import { loadRollupDiagnostics } from '@utils'; +import * as ts from 'typescript'; import type * as d from '../../../declarations'; import type { BundleOptions } from '../../bundle/bundle-interface'; @@ -6,6 +7,7 @@ import { bundleOutput } from '../../bundle/bundle-output'; import { STENCIL_INTERNAL_HYDRATE_ID } from '../../bundle/entry-alias-ids'; import { hydrateComponentTransform } from '../../transformers/component-hydrate/tranform-to-hydrate-component'; import { removeCollectionImports } from '../../transformers/remove-collection-imports'; +import { rewriteAliasedSourceFileImportPaths } from '../../transformers/rewrite-aliased-paths'; import { updateStencilCoreImports } from '../../transformers/update-stencil-core-import'; import { getHydrateBuildConditionals } from './hydrate-build-conditionals'; @@ -21,7 +23,7 @@ export const bundleHydrateFactory = async ( id: 'hydrate', platform: 'hydrate', conditionals: getHydrateBuildConditionals(buildCtx.components), - customTransformers: getHydrateCustomTransformer(config, compilerCtx), + customBeforeTransformers: getCustomBeforeTransformers(config, compilerCtx), inlineDynamicImports: true, inputs: { '@app-factory-entry': '@app-factory-entry', @@ -43,7 +45,19 @@ export const bundleHydrateFactory = async ( return undefined; }; -const getHydrateCustomTransformer = (config: d.ValidatedConfig, compilerCtx: d.CompilerCtx) => { +/** + * Generate a collection of transformations that are to be applied as a part of the `before` step in the TypeScript + * compilation process. + # + * @param config the Stencil configuration associated with the current build + * @param compilerCtx the current compiler context + * @returns a collection of transformations that should be applied to the source code, intended for the `before` part + * of the pipeline + */ +const getCustomBeforeTransformers = ( + config: d.ValidatedConfig, + compilerCtx: d.CompilerCtx +): ts.TransformerFactory[] => { const transformOpts: d.TransformOptions = { coreImportPath: STENCIL_INTERNAL_HYDRATE_ID, componentExport: null, @@ -53,10 +67,15 @@ const getHydrateCustomTransformer = (config: d.ValidatedConfig, compilerCtx: d.C style: 'static', styleImportData: 'queryparams', }; + const customBeforeTransformers = [updateStencilCoreImports(transformOpts.coreImportPath)]; + + if (config.transformAliasedImportPaths) { + customBeforeTransformers.push(rewriteAliasedSourceFileImportPaths); + } - return [ - updateStencilCoreImports(transformOpts.coreImportPath), + customBeforeTransformers.push( hydrateComponentTransform(compilerCtx, transformOpts), - removeCollectionImports(compilerCtx), - ]; + removeCollectionImports(compilerCtx) + ); + return customBeforeTransformers; }; diff --git a/src/compiler/output-targets/dist-lazy/lazy-output.ts b/src/compiler/output-targets/dist-lazy/lazy-output.ts index b0fb0cf12d1..442d9167594 100644 --- a/src/compiler/output-targets/dist-lazy/lazy-output.ts +++ b/src/compiler/output-targets/dist-lazy/lazy-output.ts @@ -1,5 +1,6 @@ import { catchError, isOutputTargetDist, isOutputTargetDistLazy, sortBy } from '@utils'; import MagicString from 'magic-string'; +import * as ts from 'typescript'; import type * as d from '../../../declarations'; import type { BundleOptions } from '../../bundle/bundle-interface'; @@ -17,6 +18,7 @@ import { generateComponentBundles } from '../../entries/component-bundles'; import { generateModuleGraph } from '../../entries/component-graph'; import { lazyComponentTransform } from '../../transformers/component-lazy/transform-lazy-component'; import { removeCollectionImports } from '../../transformers/remove-collection-imports'; +import { rewriteAliasedSourceFileImportPaths } from '../../transformers/rewrite-aliased-paths'; import { updateStencilCoreImports } from '../../transformers/update-stencil-core-import'; import { generateCjs } from './generate-cjs'; import { generateEsm } from './generate-esm'; @@ -42,7 +44,7 @@ export const outputLazy = async ( id: 'lazy', platform: 'client', conditionals: getLazyBuildConditionals(config, buildCtx.components), - customTransformers: getLazyCustomTransformer(config, compilerCtx), + customBeforeTransformers: getCustomBeforeTransformers(config, compilerCtx), inlineWorkers: config.outputTargets.some(isOutputTargetDist), inputs: { [config.fsNamespace]: LAZY_BROWSER_ENTRY_ID, @@ -97,7 +99,19 @@ export const outputLazy = async ( timespan.finish(`${bundleEventMessage} finished`); }; -const getLazyCustomTransformer = (config: d.ValidatedConfig, compilerCtx: d.CompilerCtx) => { +/** + * Generate a collection of transformations that are to be applied as a part of the `before` step in the TypeScript + * compilation process. + # + * @param config the Stencil configuration associated with the current build + * @param compilerCtx the current compiler context + * @returns a collection of transformations that should be applied to the source code, intended for the `before` part + * of the pipeline + */ +const getCustomBeforeTransformers = ( + config: d.ValidatedConfig, + compilerCtx: d.CompilerCtx +): ts.TransformerFactory[] => { const transformOpts: d.TransformOptions = { coreImportPath: STENCIL_CORE_ID, componentExport: 'lazy', @@ -107,11 +121,17 @@ const getLazyCustomTransformer = (config: d.ValidatedConfig, compilerCtx: d.Comp style: 'static', styleImportData: 'queryparams', }; - return [ - updateStencilCoreImports(transformOpts.coreImportPath), + const customBeforeTransformers = [updateStencilCoreImports(transformOpts.coreImportPath)]; + + if (config.transformAliasedImportPaths) { + customBeforeTransformers.push(rewriteAliasedSourceFileImportPaths); + } + + customBeforeTransformers.push( lazyComponentTransform(compilerCtx, transformOpts), - removeCollectionImports(compilerCtx), - ]; + removeCollectionImports(compilerCtx) + ); + return customBeforeTransformers; }; /** diff --git a/src/compiler/transpile/run-program.ts b/src/compiler/transpile/run-program.ts index 7a691895eb7..8f43dce4279 100644 --- a/src/compiler/transpile/run-program.ts +++ b/src/compiler/transpile/run-program.ts @@ -6,10 +6,7 @@ import type * as d from '../../declarations'; import { updateComponentBuildConditionals } from '../app-core/app-data'; import { resolveComponentDependencies } from '../entries/resolve-component-dependencies'; import { convertDecoratorsToStatic } from '../transformers/decorators-to-static/convert-decorators'; -import { - rewriteAliasedDTSImportPaths, - rewriteAliasedSourceFileImportPaths, -} from '../transformers/rewrite-aliased-paths'; +import { rewriteAliasedDTSImportPaths } from '../transformers/rewrite-aliased-paths'; import { updateModule } from '../transformers/static-to-meta/parse-static'; import { generateAppTypes } from '../types/generate-app-types'; import { updateStencilTypesImports } from '../types/stencil-types'; @@ -67,19 +64,20 @@ export const runTsProgram = async ( }; if (config.transformAliasedImportPaths) { - transformers.before.push(rewriteAliasedSourceFileImportPaths); - // TypeScript handles the generation of JS and `.d.ts` files through - // different pipelines. One (possibly surprising) consequence of this is - // that if you modify a source file using a transforming it will not - // automatically result in changes to the corresponding `.d.ts` file. - // Instead, if you want to, for instance, rewrite some import specifiers in - // both the source file _and_ its typedef you'll need to run a transformer - // for both of them. - // - // See here: https://github.com/itsdouges/typescript-transformer-handbook#transforms - // and here: https://github.com/microsoft/TypeScript/pull/23946 - // - // This quirk is not terribly well documented unfortunately. + /** + * Generate a collection of transformations that are to be applied as a part of the `afterDeclarations` step in the + * TypeScript compilation process. + * + * TypeScript handles the generation of JS and `.d.ts` files through different pipelines. One (possibly surprising) + * consequence of this is that if you modify a source file using a transformer, it will not automatically result in + * changes to the corresponding `.d.ts` file. Instead, if you want to, for instance, rewrite some import specifiers + * in both the source file _and_ its typedef you'll need to run a transformer for both of them. + * + * See here: https://github.com/itsdouges/typescript-transformer-handbook#transforms + * and here: https://github.com/microsoft/TypeScript/pull/23946 + * + * This quirk is not terribly well documented, unfortunately. + */ transformers.afterDeclarations.push(rewriteAliasedDTSImportPaths); }