(please note - this is a live document. I'm adding more things as I work on them)
Over the past couple of months I've been working hard getting Stencil core into a better place; squashing lots of long-standing, annoying bugs (this is continuing) plus adding long .... long requested features that Stencil should have had earlier (extends, Mixin, @Prop get / set, runtime custom @Decorators to name a few).
As I look to v5 I'm looking at consolidation, organisation and deprecation - this will include breaking changes.
Stencil has always been pretty stable when it comes to it's API.
Whilst this is nice from a upgrade POV it has come at the cost of technical debt - Stencil recently had it's 10th birthday 🎂 - 10 years worth of technical debt!
In this issue I want to publicly make known what is currently just in my head (or actively being worked on) and let's discuss it here.
BREAKING CHANGE - Integrated testing removal
Back in the days of 2016, setting up testing for front-end things was hard. The original authors wanted a first class, seamless testing experience which involved a hard-coupling with a custom Jest runner and environment, in combination with a custom Puppeteer setup.
This coupling has hamstrung Stencil core and it's users in many ways.
- Stencil core needs to offer a different, custom Jest setup for every major version of Jest. When this became too burdensome to maintain, users became locked to Jest v291
- Stencil's
--spec tests do a 'compile lite' on-the-fly for a given component class, then bootstrap it in Stencil's integrated node-dom - MockDoc. This whole process is increasingly problematic:
- it reaches into Stencil's internals to work which is prone to error and is fundamentally not representative of the final output.
- is very difficult to make work with classes that can now use
extends (optionally in combination with Mixin)
- doesn't give devs the option to use their 'node dom' of choice (e.g. happy-dom, JSDOM)
- Stencil's
--e2e tests are hard baked to use Puppeteer which doesn't have the same DevX around browser testing as newer options like Cypress and Playwright.
Migration pathway
- For
--spec style tests, migrate to using https://github.com/stenciljs/vitest. It has a similar API to the current Jest integration but gives devs far greater control. Test against different bundles / outputs, test in a real browser (a11y tests, visual regressions etc), or pick your node-dom of choice.
- For
--e2e style tests I would probably say that many library authors actually want 'component' tests - isolated testing of their components that just happen to run in a browser - again - use https://github.com/stenciljs/vitest. For those cases where actual e2e tests are required (routing, full applications, proper onload initialisation, SSR) use https://github.com/stenciljs/playwright
BREAKING CHANGE - @Component API
The @Component API is convoluted and not very amenable to updates or changes.
Current
interface ComponentConfig {
tag: string;
/* not relevant unless you use `shadow` */
formAssociated?: boolean;
/* don't use shadowDOM < use scoped classes instead */
scoped?: boolean;
/* use shadowDOM if true ... use nothing if false. Or you can omit to use nothing // then you can also have scoped */
shadow?: boolean | {
delegatesFocus?: boolean, slotAssignment?: 'manual' | 'named'
}
// .. some other things around styling / assets that make sense //
}
Proposed
interface ComponentConfig {
tag: string;
encapsulation?:
| { type: 'shadow'; mode?: 'open' | 'closed'; delegatesFocus?: boolean; slotAssignment?: 'manual' | 'named' }
| { type: 'none'; patches?: ('all' | 'children' | 'clone' | 'insert')[] }
| { type: 'scoped'; patches?: ('all' | 'children' | 'clone' | 'insert')[] };
// ^ nb - these patches can be applied globally via `config.extras` as they now
// other unrelated config
}
Whilst this is slightly more verbose I think it's much clearer around intent plus much easier to add more options in future. Feedback welcome.
formAssociation will move into the @AttachInternals decorator options
Migration pathway
A new stencil migrate CLI option will be added to update from old > new
BREAKING CHANGE - CommonJS
Stencil itself will migrate it's compiled source from CJS to ESM.
User's dist and dist-hydrate-script output targets now are opt-in via a cjs: true config option within stencil.config.
Migration pathway
Add cjs: true to both dist and dist-hydrate-script outputs to continue getting commonjs output. Additionally, read the specific breaking changes below regarding dist-hydrate-script.
BREAKING CHANGE - ES5 / Polyfills removal
Removal of all options around old polyfills / shims and ES5, 'system' modules.
Migration pathway
Users should 1) remove any imports and calls to applyPolyfills() from their dist output and 2) remove the es5 config option their stencil.config
BREAKING CHANGE - internal structure
Many internal paths will be moved / renamed / become their own packages
@stencil/core/internal → @stencil/core/runtime
@stencil/core/internal/client → @stencil/core/runtime/client
@stencil/core/internal/hydrate → @stencil/core/runtime/server
@stencil/core/cli → @stencil/cli
@stencil/core/dev-server → @stencil/dev-server
@stencil/core/mock-doc → @stencil/mock-doc
BREAKING CHANGE - openBrowser
The dev-server will no longer open the browser by default.
Migration pathway
- No need to pass in
--no-open anymore.
- Pass in
--open (in the cli) or openBrowser to the devServer config options, for previous auto-open behaviour
BREAKING CHANGE - @Watch initialisation
The documentation around Stencil's lifecycle (https://stenciljs.com/docs/component-lifecycle#component-lifecycle-methods) is quite clear; watchers should, by default, not fire until the component has been fully rendered. At present - especially within the dist output, watch methods can be called during every lifecycle stage.
In v5 @Watch methods adhere to the documentation. Whilst this is strictly a fix, the current behaviour is so long-standing users may have started to rely on it.
Migration pathway
If you need to call watch methods before the component is completely ready, manually call them within lifecycle methods.
Alternatively, use the immediate flag - @Watch({ immediate: true }).
BREAKING CHANGE - Rollup replaced with Rolldown
In v5 Rollup was removed and replaced with Rolldown; all references to rollup* in stencil.config have been replaced accordingly.
Migration pathway
Replace any rollup* references with rolldown* in stencil.config (running stencil migrate will automatically do this).
If referencing any rollup types or internals, make sure to find out what the equivalents are in rolldown.
A number of supported rollup options have no new equivalents (so should be removed) whilst others have new names; running stencil migrate will automatically do handle this for you.
BREAKING CHANGES - dist-hydrate-script output
- Output name has changed from
dist-hydrate-script to ssr (read about all core output targets renamed below).
- The output no-longer writes a
package.json file
- The default
hydrate.js is now esm whilst commonJS is opt-in (via cjs: true) and outputs as hydrate.cjs
- The exported
hydrateDocument has been renamed to ssrDocument (hydrateDocument is still exported as deprecated for now)
- All config options with
*hydrate (beforeHydrate / afterHydrate) have been renamed to *ssr (*hydrate are still exported as deprecated options for now)
- To make the output environment agnostic (not just Node.js) the
streamToString() return type has been changed from Node.js Readable to web-standard ReadableStream<string> which works in Node 22+, Cloudflare Workers, Deno, Bun, and all WinterCG runtimes.
Migration pathway
Users must make sure to adjust their package.json exports accordingly - pointing to updated file names.
BREAKING CHANGES - remove buildDist and buildDocs global config options.
The buildDist and buildDocs global configuration options are
- not particularly clear in intent
- pretty nuclear (e.g. users are forced via
buildDocs to build ALL docs outputs during dev)
- In the case of
buildDist is slightly inconsistent (other flags can overrule whether outputs are built or not)
A new, per output target has been added skipInDev: boolean allowing devs granular control over what is built during --dev / devMode. By default everything else is skipInDev: true except for the dist browser bundle (and related www output)
Migration pathway
buildDist and buildDocs are detected during cli tasks and users are invited to automatically migrate (using stencil migrate)
BREAKING CHANGES - core output targets renamed
dist and dist-custom-elements are not at all obvious what they are or what they do. The naming comes from original decisions made about the project; dist always designed to be the 'main' target, dist-custom-elements being a later addition when users requested standalone / cherry-pickable components.
These original decisions resulted in dist-custom-elements always seeming like an afterthought; some work being copied (like type generation) whilst other work (like globalStyles) being completely omitted. With this in-mind, the 2 targets have become equal in weighting with other implicit outputs now being explicitly configurable (if required, but not necessary).
TLDR:
dist > loader-bundle. Default output dir was dist now dist/loader-bundle
dist-custom-elements > standalone. Default output dir was custom-elements now is dist/standalone
dist-hydrate-script > ssr. Default output dir was hydrate now is dist/ssr
- new (optional)
types output. Customisable with skipInDev and dir options - defaults to dist/types. Is auto-generated in production builds.
- new (optional)
collection is now an explicit output. Customisable with skipInDev and dir options - defaults to dist/collection. Is auto-generated in production builds.
dist.typesDir removed. Use types.dir
dist.collectionsDir removed. Use collection.dir
dist-custom-elements.isPrimaryPackageOutputTarget removed. Choose your own default export in package.json (cli hints will guide you to choose one depending on your outputs).
dist-custom-elements.generateTypeDeclarations removed. Auto generated and written to types.dir
dist.esmLoaderPath renamed to loaderPath. Path is now calculated from dist/loader-bundle instead of dist (so use loaderPath: '../' to recreate old behaviour)
Migration pathway
Deprecated outputs are detected during cli tasks and users are invited to automatically migrate (using stencil migrate).
Be mindful of the new default output directories - you may need to update package.json exports or explicitly set the dir in each output if you want to retain old / legacy paths.
For the dist cdn path, if you want to retain the same path as before (because the default path is now dist/loader-bundle (was dist)) set buildDir: '../'
BREAKING CHANGES - prod / dev
- The
--prod cli flag has been removed (was redundant as prod builds are the default without explicit --dev flag)
- The
devMode config option has been removed. Antithetical to usual safety norms - it should be explicit and obvious to devs when they're opting into a dev build - not hidden in a config option.
Migration pathway
Devs should remove --prod from their cli commands. Won't error - just not required.
stencil migrate will automatically remove devMode from stencil.config. Devs should use the --dev cli flag.
BREAKING CHANGE - module extensions
With cjs being a fringe requirement and (therefore becoming opt-in in Stencil), type: module is now strongly recommended and old file extension formats (*.cjs.js / *.esm.js) will be standardised to *.cjs (should you opt-in to cjs) and *.js)
Migration pathway
Devs will need to update properties in their package.json. Extra warnings are raised when key package.json fields point to non-existing paths.
note - because the browser loader-bundle output is public facing, references to it may not be controlled by library maintainers. Therefore the current main entrypoint - path/to/loader/NAMESPACE.esm.js - will not be removed and kept as a forwarding module.
BREAKING CHANGE - extras.addGlobalStyleToComponents removed
In v5 globalStyle has been elevated to it's own configurable output target (and you can have multiple now!). Although the current globalStyle config property is still available for ease of use, the extras.addGlobalStyleToComponents has been removed.
Migration pathway
A new inject property is available on any global-style output target:
{
type: 'global-style',
inject: 'client' // 'all' | 'none' < default
...
}
Explicit extras.addGlobalStyleToComponents is detected during cli tasks and users are invited to automatically migrate (using stencil migrate) which will create an explicit global-style output target with corresponding inject setting.
BREAKING CHANGE - JSX types
Previously, JSX.Element was undefined in the h namespace, causing ts to silently fall back to any for JSX expressions (which surfaced as no-unsafe-return errors in strict @typescript-eslint setups, for example).
3 type-level changes:
h.JSX.Element > VNode (was FunctionalComponent<...>)
Host / Fragment > (props) => VNode(wasFunctionalComponent<...>) FunctionalComponent>VNode | null(wasVNode | VNode[] | null`)
Migration pathway
No runtime changes.
If you have a FunctionalComponent<T> that returns an array (via utils.map or similar), wrap the result in a fragment instead:
// Before
const MyList: FunctionalComponent<Props> = (props, children, utils) => utils.map(children, transform);
// After
const MyList: FunctionalComponent<Props> = (props, children, utils) => <>{utils.map(children, transform)}</>;
BREAKING CHANGE - extras.*
The extras section of stencil.config has been renamed compat
experimentalSlotFixes (and slotChildNodesFix, scopedSlotTextContentFix, appendChildSlotFix)
experimentalSlotFixes: true used to set slotChildNodesFix, scopedSlotTextContentFix and appendChildSlotFix to true too ... but you could also set those individually?
This has now become:
lightDomPatches: boolean | {
slotChildNodes: boolean,
slotCloneNode: boolean,
slotDomMutations: boolean,
slotTextContent: boolean,
}
Additionally:
lightDomPatches is true by default (but will only be bundled if you use lightDOM components with slots)
insertAdjacentText and insertAdjacentElement patched methods have been removed to save on runtime bytes.
enableImportInjection default
This option was previously opt-in. It's now opt-out.
Deprecated tagNameTransform, experimentalImportInjection, experimentalScopedSlotChanges
These deprecated options have now been removed.
Any unique functionality previously covered via experimentalScopedSlotChanges is now within lightDomPatches options.
Migration pathway
extras > compat and explicit *fix options can be auto-migrated by stencil migrate
BREAKING CHANGE - hashFile* settings moved from global to output targets options
hashFileNames and hashFileNameLength were top level configuration options, but they only really make sense for outputs that are:
- to be loaded directly in the browser / in a CDN and
- naturally have a single entry point
Therefore these options have been moved into the loader-bundle and www outputs.
Migration pathway
Any explicit hashFile* options can be auto migrated into appropriate output targets via stencil migrate
BREAKING CHANGE - collection importing / rebundling
In v4, importing any module / utility / type from a 3rd party node_module stencil lib would re-bundle the whole library.
Although this behaviour wasn't documented (documentation mentioned only importing as a sideEffect import "@ionic/core") users may have come to rely upon it.
Migration pathway
Users now have 2 options to re-bundle a 3rd party Stencil lib:
- The documented import from a stencil lib as a sideEffect -
import "@ionic/core"
- A new top-level stencil.config option
collections: [] has been added
BREAKING CHANGE - dist-custom-elements: externalRuntime (now standalone)
externalRuntime now defaults to false (was true). Component bundles are now self-contained - the runtime is included as a local shared chunk rather than left as an external @stencil/core/runtime/client import.
Setting externalRuntime: true is only recommended if you intend on having multiple Stencil component libraries (or components from different libraries) on the same page to limit the bytes sent to the end-user via multiple runtimes.
Migration pathway
Opt back in by setting externalRuntime: true. Run stencil migrate to remove any now-redundant externalRuntime: false from your config.
BREAKING CHANGE - www: serviceWorker
serviceWorker now defaults to null (was 'create Workbox-powered service worker' by default).
Migration pathway
Opt back in by setting serviceWorker: true for the auto-service worker creation.
Run stencil migrate to remove any now-redundant serviceWorker: null from your config.
More TBD
This is a live document ... I'm adding more things as I work on them
(please note - this is a live document. I'm adding more things as I work on them)
Over the past couple of months I've been working hard getting Stencil core into a better place; squashing lots of long-standing, annoying bugs (this is continuing) plus adding long .... long requested features that Stencil should have had earlier (
extends, Mixin,@Propget / set, runtime custom@Decoratorsto name a few).As I look to v5 I'm looking at consolidation, organisation and deprecation - this will include breaking changes.
Stencil has always been pretty stable when it comes to it's API.
Whilst this is nice from a upgrade POV it has come at the cost of technical debt - Stencil recently had it's 10th birthday 🎂 - 10 years worth of technical debt!
In this issue I want to publicly make known what is currently just in my head (or actively being worked on) and let's discuss it here.
BREAKING CHANGE - Integrated testing removal
Back in the days of 2016, setting up testing for front-end things was hard. The original authors wanted a first class, seamless testing experience which involved a hard-coupling with a custom Jest runner and environment, in combination with a custom Puppeteer setup.
This coupling has hamstrung Stencil core and it's users in many ways.
--spectests do a 'compile lite' on-the-fly for a given component class, then bootstrap it in Stencil's integrated node-dom -MockDoc. This whole process is increasingly problematic:extends(optionally in combination with Mixin)--e2etests are hard baked to use Puppeteer which doesn't have the same DevX around browser testing as newer options like Cypress and Playwright.Migration pathway
--specstyle tests, migrate to using https://github.com/stenciljs/vitest. It has a similar API to the current Jest integration but gives devs far greater control. Test against different bundles / outputs, test in a real browser (a11y tests, visual regressions etc), or pick your node-dom of choice.--e2estyle tests I would probably say that many library authors actually want 'component' tests - isolated testing of their components that just happen to run in a browser - again - use https://github.com/stenciljs/vitest. For those cases where actual e2e tests are required (routing, full applications, proper onload initialisation, SSR) use https://github.com/stenciljs/playwrightBREAKING CHANGE -
@ComponentAPIThe
@ComponentAPI is convoluted and not very amenable to updates or changes.Current
Proposed
Whilst this is slightly more verbose I think it's much clearer around intent plus much easier to add more options in future. Feedback welcome.
formAssociationwill move into the@AttachInternalsdecorator optionsMigration pathway
A new
stencil migrateCLI option will be added to update from old > newBREAKING CHANGE - CommonJS
Stencil itself will migrate it's compiled source from CJS to ESM.
User's
distanddist-hydrate-scriptoutput targets now are opt-in via acjs: trueconfig option within stencil.config.Migration pathway
Add
cjs: trueto bothdistanddist-hydrate-scriptoutputs to continue getting commonjs output. Additionally, read the specific breaking changes below regardingdist-hydrate-script.BREAKING CHANGE - ES5 / Polyfills removal
Removal of all options around old polyfills / shims and ES5, 'system' modules.
Migration pathway
Users should 1) remove any imports and calls to
applyPolyfills()from theirdistoutput and 2) remove thees5config option their stencil.configBREAKING CHANGE - internal structure
Many internal paths will be moved / renamed / become their own packages
@stencil/core/internal→@stencil/core/runtime@stencil/core/internal/client→@stencil/core/runtime/client@stencil/core/internal/hydrate→@stencil/core/runtime/server@stencil/core/cli→@stencil/cli@stencil/core/dev-server→@stencil/dev-server@stencil/core/mock-doc→@stencil/mock-docBREAKING CHANGE -
openBrowserThe dev-server will no longer open the browser by default.
Migration pathway
--no-openanymore.--open(in the cli) oropenBrowserto thedevServerconfig options, for previous auto-open behaviourBREAKING CHANGE -
@WatchinitialisationThe documentation around Stencil's lifecycle (https://stenciljs.com/docs/component-lifecycle#component-lifecycle-methods) is quite clear; watchers should, by default, not fire until the component has been fully rendered. At present - especially within the
distoutput, watch methods can be called during every lifecycle stage.In v5
@Watchmethods adhere to the documentation. Whilst this is strictly a fix, the current behaviour is so long-standing users may have started to rely on it.Migration pathway
If you need to call watch methods before the component is completely ready, manually call them within lifecycle methods.
Alternatively, use the immediate flag -
@Watch({ immediate: true }).BREAKING CHANGE - Rollup replaced with Rolldown
In v5 Rollup was removed and replaced with Rolldown; all references to
rollup*in stencil.config have been replaced accordingly.Migration pathway
Replace any
rollup*references withrolldown*in stencil.config (runningstencil migratewill automatically do this).If referencing any rollup types or internals, make sure to find out what the equivalents are in rolldown.
A number of supported rollup options have no new equivalents (so should be removed) whilst others have new names; running
stencil migratewill automatically do handle this for you.BREAKING CHANGES -
dist-hydrate-scriptoutputdist-hydrate-scripttossr(read about all core output targets renamed below).package.jsonfilehydrate.jsis now esm whilst commonJS is opt-in (viacjs: true) and outputs ashydrate.cjshydrateDocumenthas been renamed tossrDocument(hydrateDocumentis still exported asdeprecatedfor now)*hydrate(beforeHydrate/afterHydrate) have been renamed to*ssr(*hydrateare still exported asdeprecatedoptions for now)streamToString()return type has been changed from Node.jsReadableto web-standardReadableStream<string>which works in Node 22+, Cloudflare Workers, Deno, Bun, and all WinterCG runtimes.Migration pathway
Users must make sure to adjust their package.json
exportsaccordingly - pointing to updated file names.BREAKING CHANGES - remove
buildDistandbuildDocsglobal config options.The
buildDistandbuildDocsglobal configuration options arebuildDocsto build ALL docs outputs during dev)buildDistis slightly inconsistent (other flags can overrule whether outputs are built or not)A new, per output target has been added
skipInDev: booleanallowing devs granular control over what is built during--dev/devMode. By default everything else isskipInDev: trueexcept for thedistbrowser bundle (and relatedwwwoutput)Migration pathway
buildDistandbuildDocsare detected during cli tasks and users are invited to automatically migrate (usingstencil migrate)BREAKING CHANGES - core output targets renamed
distanddist-custom-elementsare not at all obvious what they are or what they do. The naming comes from original decisions made about the project;distalways designed to be the 'main' target,dist-custom-elementsbeing a later addition when users requested standalone / cherry-pickable components.These original decisions resulted in
dist-custom-elementsalways seeming like an afterthought; some work being copied (like type generation) whilst other work (like globalStyles) being completely omitted. With this in-mind, the 2 targets have become equal in weighting with other implicit outputs now being explicitly configurable (if required, but not necessary).TLDR:
dist>loader-bundle. Default output dir wasdistnowdist/loader-bundledist-custom-elements>standalone. Default output dir wascustom-elementsnow isdist/standalonedist-hydrate-script>ssr. Default output dir washydratenow isdist/ssrtypesoutput. Customisable withskipInDevanddiroptions - defaults todist/types. Is auto-generated in production builds.collectionis now an explicit output. Customisable withskipInDevanddiroptions - defaults todist/collection. Is auto-generated in production builds.dist.typesDirremoved. Usetypes.dirdist.collectionsDirremoved. Usecollection.dirdist-custom-elements.isPrimaryPackageOutputTargetremoved. Choose your own default export inpackage.json(cli hints will guide you to choose one depending on your outputs).dist-custom-elements.generateTypeDeclarationsremoved. Auto generated and written totypes.dirdist.esmLoaderPathrenamed toloaderPath. Path is now calculated fromdist/loader-bundleinstead ofdist(so useloaderPath: '../'to recreate old behaviour)Migration pathway
Deprecated outputs are detected during cli tasks and users are invited to automatically migrate (using
stencil migrate).Be mindful of the new default output directories - you may need to update
package.jsonexports or explicitly set thedirin each output if you want to retain old / legacy paths.For the
distcdn path, if you want to retain the same path as before (because the default path is nowdist/loader-bundle(wasdist)) setbuildDir: '../'BREAKING CHANGES - prod / dev
--prodcli flag has been removed (was redundant as prod builds are the default without explicit--devflag)devModeconfig option has been removed. Antithetical to usual safety norms - it should be explicit and obvious to devs when they're opting into a dev build - not hidden in a config option.Migration pathway
Devs should remove
--prodfrom their cli commands. Won't error - just not required.stencil migratewill automatically removedevModefrom stencil.config. Devs should use the--devcli flag.BREAKING CHANGE - module extensions
With cjs being a fringe requirement and (therefore becoming opt-in in Stencil),
type: moduleis now strongly recommended and old file extension formats (*.cjs.js/*.esm.js) will be standardised to*.cjs(should you opt-in to cjs) and*.js)Migration pathway
Devs will need to update properties in their package.json. Extra warnings are raised when key
package.jsonfields point to non-existing paths.note - because the browser loader-bundle output is public facing, references to it may not be controlled by library maintainers. Therefore the current main entrypoint -
path/to/loader/NAMESPACE.esm.js- will not be removed and kept as a forwarding module.BREAKING CHANGE -
extras.addGlobalStyleToComponentsremovedIn v5
globalStylehas been elevated to it's own configurable output target (and you can have multiple now!). Although the currentglobalStyleconfig property is still available for ease of use, theextras.addGlobalStyleToComponentshas been removed.Migration pathway
A new
injectproperty is available on anyglobal-styleoutput target:Explicit
extras.addGlobalStyleToComponentsis detected during cli tasks and users are invited to automatically migrate (usingstencil migrate) which will create an explicit global-style output target with correspondinginjectsetting.BREAKING CHANGE - JSX types
Previously,
JSX.Elementwas undefined in thehnamespace, causing ts to silently fall back toanyfor JSX expressions (which surfaced asno-unsafe-returnerrors in strict@typescript-eslintsetups, for example).3 type-level changes:
h.JSX.Element>VNode(wasFunctionalComponent<...>)Host/Fragment>(props) =>VNode(wasFunctionalComponent<...>)FunctionalComponent>VNode | null(wasVNode | VNode[] | null`)Migration pathway
No runtime changes.
If you have a
FunctionalComponent<T>that returns an array (via utils.map or similar), wrap the result in a fragment instead:BREAKING CHANGE -
extras.*The
extrassection of stencil.config has been renamedcompatexperimentalSlotFixes(andslotChildNodesFix,scopedSlotTextContentFix,appendChildSlotFix)experimentalSlotFixes: trueused to setslotChildNodesFix,scopedSlotTextContentFixandappendChildSlotFixtotruetoo ... but you could also set those individually?This has now become:
Additionally:
lightDomPatchesistrueby default (but will only be bundled if you use lightDOM components with slots)insertAdjacentTextandinsertAdjacentElementpatched methods have been removed to save on runtime bytes.enableImportInjectiondefaultThis option was previously opt-in. It's now opt-out.
Deprecated
tagNameTransform,experimentalImportInjection,experimentalScopedSlotChangesThese deprecated options have now been removed.
Any unique functionality previously covered via
experimentalScopedSlotChangesis now withinlightDomPatchesoptions.Migration pathway
extras>compatand explicit*fixoptions can be auto-migrated bystencil migrateBREAKING CHANGE -
hashFile*settings moved from global to output targets optionshashFileNamesandhashFileNameLengthwere top level configuration options, but they only really make sense for outputs that are:Therefore these options have been moved into the
loader-bundleandwwwoutputs.Migration pathway
Any explicit
hashFile*options can be auto migrated into appropriate output targets viastencil migrateBREAKING CHANGE - collection importing / rebundling
In v4, importing any module / utility / type from a 3rd party node_module stencil lib would re-bundle the whole library.
Although this behaviour wasn't documented (documentation mentioned only importing as a sideEffect
import "@ionic/core") users may have come to rely upon it.Migration pathway
Users now have 2 options to re-bundle a 3rd party Stencil lib:
import "@ionic/core"collections: []has been addedBREAKING CHANGE -
dist-custom-elements: externalRuntime(nowstandalone)externalRuntimenow defaults tofalse(wastrue). Component bundles are now self-contained - the runtime is included as a local shared chunk rather than left as an external@stencil/core/runtime/clientimport.Setting
externalRuntime: trueis only recommended if you intend on having multiple Stencil component libraries (or components from different libraries) on the same page to limit the bytes sent to the end-user via multiple runtimes.Migration pathway
Opt back in by setting
externalRuntime: true. Runstencil migrateto remove any now-redundantexternalRuntime: falsefrom your config.BREAKING CHANGE - www: serviceWorker
serviceWorkernow defaults tonull(was 'create Workbox-powered service worker' by default).Migration pathway
Opt back in by setting
serviceWorker: truefor the auto-service worker creation.Run
stencil migrateto remove any now-redundantserviceWorker: nullfrom your config.More TBD
This is a live document ... I'm adding more things as I work on them
Footnotes
- I know this exists to allow for Jest to be updated however it has all of the same problems... but worse a) because core changes are not synced to the downstream package and b) has no e2e solution
↩