Closed ItsMrCube closed 4 months ago
Hi! You're right, there should be an option to prevent all those languages to be bundled into the highlighter. I think there should be an option with different strategies for importing languages:
bundled
: all languages are bundled into the output (current one);fetch
: on the client, necessary languages are fetched at runtime when needed from some online repo(like raw github files or npm);empty
: no languages are bundled by default.Something similar (maybe except for the fetch
part) could be done for themes.
However, this could reopen an issue with plugin-code
, which was recently fixed (#75).
Also, this may fix this issue here: #54
please correct me if this is a crazy or bad idea (I'm still very new to Svelte)..
but wouldn't it be possible to wrap all of the places that initialize Shiki in a conditional: if (browser)
..
and completely tree shake Shiki from the server-side bundle?
related:
doing a quick grep of the source..
highlighter.ts
getHighlighter
from shiki
loadHighlighter
, which is the one and only place that calls getHighlighter
carta.ts
highlighter()
, which is the one and only place that calls loadHighlighter
Input.svelte
carta.highlighter()
in: highlight()
and highlightNestedLanguages()
onMount()
$: value; ...
if (browser) onValueChange(value)
carta.ts
render()
, which calls carta.highlighter()
Renderer.svelte
carta.render()
from debouncedRenderer
$: value; ...
if (browser) onValueChange(value)
Markdown.svelte
carta.render()
onMount()
..and that's it,
although index.ts
would probably also need to remove: export * from '$lib/internal/highlight'
so.. in theory, a few minor tweaks and Shiki should get shook.. from the server bundle. any thoughts?
PS: although the intention of my previous comment is to prevent including Shiki in the server-side bundle that gets uploaded to and executed by Cloudflare Workers, because (I believe that..) it isn't even used when performing SSR'ing.. the following is info that I found regarding the correct way to do so:
Shiki has a document that specifically addresses this.
Apparently, the way it imports .wasm
doesn't work without a little workaround.
Although, I should probably point out that this workaround still involves importing a .wasm
file that is 455 KB:
update: conflicting info
I'm having the same issue as well now. I'm just making a bloody mess chopping Carta up with patch-package to essentially disable the highlighting.
I'm not seeing a way to use shiki on Cloudflare at all if it depends on a wasm, because like the link warren-bank shared , that is for setting up a separate Worker instead of the Pages Functions bundling. (along with the Shiki doc linked).
Edit: Looks like even @shiki/core requires the wasm. So shiki simply makes it impossible for Cloudflare Pages unless theres a way of linking the wasm to a separate Worker.
Hello, thanks everyone for the help.
I'll be quite busy for a couple of days, but then I could roll out a fix that would allow using an custom bundle (getHighlighterCore
instead of getHighlighter
). I would have to add some sort of check to make sure plugin-code
does not try to load a language that is not bundled.
I'm pretty sure this won't work, as even if the languages are only used in the client, they would still have to be bundled, so that the client can request them when needed.
Edit: this should fix the issue with the large bundle size, but we'll have to see about the wasm import support, as I don't know how we could approach that
@ItsMrCube , hi.. can I ask you a quick question to clarify the problem, since you know Cloudflare Pages better than I do? It wasn't until I just did some reading that I now realize that CF_P is full-stack; I was under the impression that CF_P was static and CF_W was dynamic, but apparently that changed about 2.5 years ago.
So, if I..
npm install
CF_PAGES=1 # when the project uses 'adapter-auto', and I want to target CF_P
npm run build
Then..
.svelte-kit/cloudflare
Which I can test locally, if I..
run:
del wrangler.toml # remove a file in the example repo which appears to be VERY out of date (for CF_W)
npm install --save-dev wrangler@2.20.0
npm install --save-dev @miniflare/tre@3.0.0-next.13
./node_modules/.bin/wrangler pages dev .svelte-kit/cloudflare --experimental-local
The thing that I want to clarify is..
.svelte-kit/cloudflare/_worker.js
@ItsMrCube , hi.. can I ask you a quick question to clarify the problem, since you know Cloudflare Pages better than I do?
It wasn't until I just did some reading that I now realize that CF_P is full-stack;
I was under the impression that CF_P was static and CF_W was dynamic, but apparently that changed about 2.5 years ago.
So, if I..
have a SvelteKit project (for example)..
run:
npm install CF_PAGES=1 # when the project uses 'adapter-auto', and I want to target CF_P npm run build
Then..
this will produce the output directory:
.svelte-kit/cloudflare
having the structure..
```text .svelte-kit/cloudflare | 404.html | about.html | favicon.png | index.html | robots.txt | _headers | _routes.json | _worker.js | _worker.js.map | +---sverdle | how-to-play.html | \---_app | version.json | \---immutable +---assets | 0.rgE380Ej.css | 2.Cs8KR-Bb.css | 4.DOkkq0IA.css | 5.CU6psp88.css | fira-mono-cyrillic-400-normal.36-45Uyg.woff2 | fira-mono-cyrillic-400-normal.Dq7SlH2J.woff | fira-mono-cyrillic-ext-400-normal.0xXfcOOq.woff | fira-mono-cyrillic-ext-400-normal.B04YIrm4.woff2 | fira-mono-greek-400-normal.C3zng6O6.woff2 | fira-mono-greek-400-normal.DUeQbRz0.woff | fira-mono-greek-ext-400-normal.BEhC8Nsh.woff | fira-mono-greek-ext-400-normal.CsqI23CO.woff2 | fira-mono-latin-400-normal.DKjLVgQi.woff2 | fira-mono-latin-400-normal.g4W12wf9.woff | fira-mono-latin-ext-400-normal.D6XfiR-_.woff2 | fira-mono-latin-ext-400-normal.lWlD_NAB.woff | svelte-welcome.0pIiHnVF.webp | svelte-welcome.VNiyy3gC.png | _layout.VxX115KI.css | _page.BBloWWo2.css | _page.CU6psp88.css | _page.DOkkq0IA.css | +---chunks | entry.oJCVYmsm.js | index.B-IpIKmi.js | index.Ice1EKvx.js | index.R8ovVqwX.js | scheduler.Dk-snqIU.js | stores.CG-4iMoZ.js | +---entry | app.gAIOTSnC.js | start.DfoGsIKh.js | \---nodes 0.DYViTZ7U.js 1.D9rQhYdI.js 2.QKAvpFF6.js 3.DDQOcn6V.js 4.B6WkqrZ0.js 5.DtMLlR0M.js ```Which I can test locally, if I..
run:
del wrangler.toml # remove a file in the example repo which appears to be VERY out of date (for CF_W) npm install --save-dev wrangler@2.20.0 npm install --save-dev @miniflare/tre@3.0.0-next.13 ./node_modules/.bin/wrangler pages dev .svelte-kit/cloudflare --experimental-local
off-topic:
- I'm using wrangler v2.20.0 because v3.61.0 (the current version) doesn't seem to do anything on my system,
and I don't feel like debugging itopen URL:
The thing that I want to clarify is..
does this 1 MB limit apply only to the file:
.svelte-kit/cloudflare/_worker.js
is every other file in this output directory considered an "asset",
which has a 25 MB limit?
Hi, I'm very sorry but I have no idea if the 1mb limit applies only to that file, this is the first time I've encountered an error like this and I'm pretty clueless about it. I've made a quick search and found out that, according to this post, you can have how many files ad you'd like, as long as they're all under 25mb. I can't really give you a definitive answer for your second question, I think it's a "yes" but I don't have a computer in front of me at this time.
As a side note, this might help you verify if your pages projects is within the limits: https://developers.cloudflare.com/workers/platform/limits/#worker-size
I'll make sure to research this topic more thoroughly tomorrow as it's really late for me at the moment.
Hey there. Yes the 1MB limit only pertains to the _workers.js
file specifically. (After compression. And it may have bumped up to 1.5MB)
So if you want to try externalizing the WASM with Vite as an asset, might be worth trying. Not sure if the adapter will bundle it anyways because its a module import.
As it is right now, if we can import the shiki wasm source from a separate Cloudflare Worker, or perhaps import it as an asset, and then remove most of the bundled languages, it'd work.
When I first pushed to Cloudflare Pages yesterday, my _workers.js
file was 11MB. It took completely removing the wasm, all the languages and nulling some of Carta's highlighting references, to be able to build and deploy successfully.
@KyleFontenot , thanks for the clarification. Knowing that the size of this one file is the bottleneck, I'll do some experimentation with building a minimal SvelteKit project that uses carta.. and watch the effects on its size.
summary:
test 005
results in a _worker.js
file that is 693 KB
and works perfectly when both SSR and CSR are enabledPR#84 adds the changes derived from test 006
.
I built this version of carta-md
and copied its dist/
into the same minimal SvelteKit project used for testing.
When compiled with adapter-cloudflare
, the resulting _worker.js
is still only 693 KB
,
and the resulting build runs as expected in wrangler
.
update:
I created a free Cloudflare account and uploaded a demo: here.
It's super minimal, but it does include a server-side component.. just to test that it works.
The page starts with a MarkdownEditor
component, and when the markdown value is non-empty, a submit button is visible.
When clicked, the content of the markdown editor is POST to the backend, which is then made available to the frontend.
When the frontend sees that markdown has been made available by the backend,
it displays its content in a Markdown
(readonly) component.
Hello everyone, and thanks for the wonderful work.
The idea proposed by @warren-bank in #84 is good, however there's an issue with that: you are no longer able to render the whole content on node. Originally, I never thought that would be a problem, but after using the library to render a respectable amount of content, I noticed that first loading the library and then executing all the plugins takes a good amount of time (sometimes more than a second). That's the reason I recently created the <PreRendered>
component (docs), so that content could be rendered once and stored along with the other component, making loading content originally created with Carta extremely fast.
Now, I think that disabling this possibility for everyone "just" because it's not working with cloudflare is a bit too much. An option could certainly be added, but I'd first try the following, in order:
highlighterCore
;I'll now try with option 1 and see how it goes
please correct me if I'm wrong.. but my understanding is that:
renderSSR
{execution: 'sync'}
render
{execution: 'async'}
if so.. then since plugin-code
is {execution: 'async'}
,
this means that this particular plugin (ie: code highlighting) only runs in the browser;
I don't understand what SSR functionality you say is being disabled
by not loading the shiki
library when running plugins on the server.
Please explain.
PS: my most recent commit to this PR actually goes one step farther, and prevents the initialization of all async
plugins when running on the server. Not only is this more efficient, since there's no need to construct a bunch of plugins that ultimately don't get used.. but it also prevents them from running code on the server that is intended for use only in the browser.
With respect to comparing the behavior of carta when:
I tested this a while back.. against the unmodified repo, to inspect original behavior.. and it confirmed that SSR-only does not perform any code highlighting.
Originally that was how it worked, and it still does the same if you only use the <MarkdownEditor>
and <Markdown>
components. However, if you wanted to export the rendered HTML for any reason(performance, using it somewhere where Svelte is not available, etc..) you would need to use the render
method. renderSSR
is just a "downgraded" version of that, since you cannot use async code for SSR, otherwise I would have used render
there too. You can get around the SSR limitation by rendering the content on SvelteKit server-side load functions.
I've now nearly finished a change that would allow custom bundles, this should prevent the 1MB file limit. If it still causes issues, I'll add an option that completely removes shiki from the server-side bundle(your changes).
I opened a new PR #85 , you can now select which bundle you wish to use:
I also noticed that we can specify custom ways to load the wasm, would this be useful?
If you guys could test this and tell me if it now works it would be great!
PR #85 test at e17221b
w/ bundle: full
+page.svelte:
<script lang="ts">
import { Carta, MarkdownEditor } from 'carta-md'
import { code } from '@cartamd/plugin-code'
import 'carta-md/default.css'
const carta = new Carta({
extensions: [
code()
]
})
let value
</script>
<MarkdownEditor mode="split" bind:value {carta} />
10.0 MB
PR #85 test at e17221b
w/ bundle: core
+page.svelte:
<script lang="ts">
import { Carta, MarkdownEditor } from 'carta-md'
import { code } from '@cartamd/plugin-code'
import 'carta-md/default.css'
const carta = new Carta({
extensions: [
code({
onError: (e) => {console.log(e.message)}
})
],
shikiOptions: {
bundle: 'core'
}
})
let value
</script>
<MarkdownEditor mode="split" bind:value {carta} />
10.0 MB
Oh, thank you. That's weird... I guess your PR works because you are using the browser
SvelteKit env variable specifically, and svelte-package does some magic stuff removing it from the server bundle. This is also an issue since as we were planning on keeping the library framework-agnostic. Since I'm using just a "normal" variable, the bundler has no way to know that it will keep being core
, so it bundles everything.
However, I might have an idea to make it work...
Ok, should be working now. If no bundle is specified, no langugages are present in the build directory, so I hope it will work:
<script lang="ts">
import { Carta, MarkdownEditor } from 'carta-md'
import { code } from '@cartamd/plugin-code'
import 'carta-md/default.css'
const carta = new Carta({
extensions: [code()],
shikiOptions: {
bundle: () => import('carta-md/bundle/web')
}
})
let value
</script>
<MarkdownEditor mode="split" bind:value {carta} />
By default the bundle is empty. I did not find a way to use the full bundle by default without having it forcefully added to the final build.
PR #85 test at 4621830
w/ bundle: undefined
+page.svelte:
<script lang="ts">
import { Carta, MarkdownEditor } from 'carta-md'
import { code } from '@cartamd/plugin-code'
import 'carta-md/default.css'
const carta = new Carta({
extensions: [
code({
onError: (e) => {console.log(e.message)}
})
],
shikiOptions: {
bundle: undefined
}
})
let value
</script>
<MarkdownEditor mode="split" bind:value {carta} />
1.59 MB
Is it still too much?
max allowed is 1.0 MB
.. and this 1.59 MB
does not include:
carta
component library alonePR #85 test at 4621830
w/ bundle: web
+page.svelte:
<script lang="ts">
import { Carta, MarkdownEditor } from 'carta-md'
import { code } from '@cartamd/plugin-code'
import 'carta-md/default.css'
const carta = new Carta({
extensions: [
code({
onError: (e) => {console.log(e.message)}
})
],
shikiOptions: {
bundle: () => import('carta-md/bundle/web')
}
})
let value
</script>
<MarkdownEditor mode="split" bind:value {carta} />
[commonjs--resolver] Missing "./bundle/web" specifier in "carta-md" package
"exports": {
".": {
"types": "./dist/index.d.ts",
"svelte": "./dist/index.js",
"import": "./dist/index.js"
},
"./default.css": "./dist/default.css",
"./bundle/full": "./dist/bundle/full.js",
"./bundle/web": "./dist/bundle/web.js"
}
10.0 MB
Well, I guess that's as much as I could do leaving shiki in the package.
If you update you PR so that:
carta.render
to work server-side;$browser
.I'll happily proceed with that.
meta.import.env
might be interesting: it looks to be tree-shakable. (Edit: it might be removed during build, it's better to check that. In that case, maybe some vite/rollup plugin may be useful)
PS: I think the error [commonjs--resolver] Missing "./bundle/web" specifier in "carta-md" package
is because you have not rebuilt the package; I added the exports for those entrypoints and it was working for me
oh shoot, you're right..
I only copied dist
to node_modules in the demo SvelteKit/Cloudflare project;
package.json wasn't updated.. my bad.
can you give an example that shows SSR'ing w/ async plugins?
ie, a demo page that includes:
export const ssr = true;
export const csr = false;
With SvelteKit you can do it this way. You do not need change when the page is renderd, it just renders on the server and use the HTML in the page.
ohhh, ok.. reading docs, it's such a crazy idea that it might just work
reminds me of my early days in perl.. where my answer to nearly every noob question was: RTFM
how would you feel about adding an optional parameter to every function that currently performs a browser
check?
ex:
render(markdown: string, allowSSR?: boolean = false)
so.. for this use case,
specifically.. calling carta.render()
directly from a server load
function..
it could pass the optional boolean as truthy.
so.. render
can say:
if (!browser && !allowSSR) ...
which keeps the server bundle lean and clean by default.. but could add some delayed initialization when this pattern is used.
presumably, the code bunder would detect this usage pattern,
and include shiki
in the server bundle if used by the project,
but (in the default case) it gets excluded.
PS: I assume that the browser
variable gets statically inlined to either true
or false
when bundled. I don't see any reason to avoid using this feature of SvelteKit.
PPS: If this usage pattern is something you want to fully support, is it worth considering allowing separate shikiOptions
for use on the server vs. in the browser? The above methodology would make this easy to implement. For example:
{
shiki: browser ? this.shikiOptions?.csr : this.shikiOptions?.ssr
}
nope..
I pushed the commit to a different branch, because it doesn't work as expected.
The build works great..
but shiki
is always included in the server bundle..
even if render(md, /* allowSSR */ true)
is never called from server code,
which results in a 10 MB
file.
PS: I added some tests to that branch that demonstrate its usage..
update:
workspace
branch
Ehy, thanks for your effort. Trying to change the build based on some static env variable is quite hard.
However I think I found a solution that will make everyone happy, without weird settings. I'll try that as soon as I got some time.
I'll keep you updated!
I'd be curious to know what idea you have in mind.
As you indicated, I've made a few new commits.
Based on my tests, the only way to tree shake shiki is if there's absolutely no path of execution by which the server code could possibly use highlighter. It doesn't matter if there is a path of execution and the project doesn't use it. For example, my first attempt was to add a 2nd parameter to carta.render(markdown, allowSSR)
. The idea was that if a project never tries to render async plugins on the server, then the path of execution that is followed when allowSSR
is passed a truthy value isn't used.. and it would be eliminated by the compiler. However, that didn't happen.
The only solution that I could think of was to define global constants at compile time. Code paths of execution that cannot be reached because of these contant values are successfully removed from the bundle. As such, I defined two. Their values are defined in the file: vite.config.js
export default defineConfig({
plugins: [sveltekit()],
define: {
__ENABLE_CARTA_SSR_ASYNC_PLUGINS__ : 'true',
__ENABLE_CARTA_SSR_HIGHLIGHTER__ : 'false'
}
});
__ENABLE_CARTA_SSR_ASYNC_PLUGINS__
allows async plugins to be run during SSR by a direct call to carta.render(markdown)
__ENABLE_CARTA_SSR_HIGHLIGHTER__
allows the async plugin plugin-code
to be run during SSR
__ENABLE_CARTA_SSR_ASYNC_PLUGINS__
is trueshiki
to be included in the server bundle.. increasing its size to 10 MB
plugin-code
to noop when attempted to be run during SSRI'd agree with you.. that requiring additional configuration is annoying.
But on the other hand, it's only 4 lines.. and gives the user very fine grain control.
Also, strictly speaking, unless a user actually attempts to call carta.render()
from SSR..
nothing bad would happen if these flags were left undefined.. though I wouldn't recommend it.
To be clear:
__ENABLE_CARTA_SSR_HIGHLIGHTER__
is false,693 KB
__ENABLE_CARTA_SSR_HIGHLIGHTER__
is true,10 MB
To be fair:
139 KB
I'd be curious to see whether this size could be reduced farther, possibly with the use of additional globally constant boolean flags.
693 KB
_worker.js file..Should be working now, this is what I've done:
highlighter
is no longer initialized by the Carta
class, but is set by the MarkdownEditor
component on the onMount
callback. This way, it should not be present in the server bundle;Carta
class into three classes(bundles):
CartaBase
: base class, with support for rendering content;CartaBrowser
: extends CartaBase
, adds support for DOM utilities (e.g. shortcuts, listeners, icons...) and the highlighter;CartaServer
: extends CartaBase
, and is meant to be used only server side.By default, the CartaBrowser
is the Carta
one exported by the package. The others can be found in /bundle/[name]
. The browser variant is the one required for the components.
The split into different is not really related to this issue, but I've done that to keep the project a bit more organized.
Without changing anything, you should see the _worker.js
file go down in size, as the highlighter
is not required in the server. It would be great if you can test that, but I'm confident it will work, as it is basically the same strategy used by @warren-bank
Hi, I've tried the changes on my project and the worker size went down to around 1.2MB, while it's not quite enough to work with Cloudflare it's an huge improvement from when it weighed more than 10MB. I still haven't looked into what's taking up this space so I'll make sure to check since the issue might be on my side.
PS: I wanted to thank you all for working on this issue with this level of dedication. :heart:
I just rechecked the sizes for the _worker.js
file again, here are the results for my project:
Without carta: 588,8KiB
With, before the changes: 11MiB
With, after the changes: 1.7MiB
(Please ignore the part where, in my previous comment, I said that the worker weighed 1.2MB, that wasn't accurate, sorry for that.)
Thanks, is there any way to see what is taking all that space in the bundle? So we can see what's left in there. Maybe using the same tool that you used before?
Edit: you are using PR #85 right?
Hi, I can confirm that I was doing the testing with the custom-bundle
branch that's part of #85, I tried my best to build the package myself and used it in my project (this was my first time using pnpm)
Here's a map of what's taking up space, it refers to a worker file that's 1.7MiB. Looks like shiki is still taking up most of the space, at least with my project.
It seems so, however I think that is the whole bundle, and not the one that goes to the server. In fact, if you hover over the root element of the graph it should say 10MB, which is the original whole bundle(I tried that now myself and it shows that). I wonder if there's a way to only show what make up the worker file... Maybe @warren-bank can help us? As he seemed able to reduce the bundle further
@BearToCode , hello.. I haven't had a chance to look at your new version yet. I'll do that this afternoon. Off-hand, I'm not sure that I understand how it would be used to handle the normal use case.. where the same code is used for both SSR and CSR. Anyway.. I'll just need to do a little reading before I can discuss pros and cons.
@ItsMrCube , hello.. for comparison sake, would you be willing to quickly do a test build using the version in PR #84 ? If so, please remember to configure vite.config.js. PS: to simplify, you can use the packages that I've already built: carta-md, plugin-code
@BearToCode , early days.. initial thoughts:
shiki
can only be loaded (via: $lib/core/highlight
) by MarkdownEditor.svelte::onMount()
Markdown.svelte
only)carta.highlight()
returns a Promise that will never resolveMarkdownEditor.svelte
is mountedCartaServer
with plugin-code
, which happens when the constructor is called.. would cause setupAsynchronousProcessor
to yield and never completequick aside.. kind of a dumb question.. but have you written any tests to see this library in action?
I suppose the following could (maybe) work:
Markdown.svelte
:
onMount(async () => {
const module = await import('$lib/core/highlight');
highlighter = await module.loadHighlighter({
grammarRules: carta.grammarRules,
highlightingRules: carta.highlightingRules,
theme: carta.theme ?? (await module.loadDefaultTheme()),
shiki: carta.shikiOptions
});
carta.$setHighlighter(highlighter);
});
add new class: lib/bundle/server-highlighter.js
(or whatever)
export interface ServerHighlighterOptions extends BaseOptions {
/**
* Highlighter options.
*/
shikiOptions?: ShikiOptions;
/**
* ShikiJS theme
* @default 'carta-light' for light mode and 'carta-dark' for dark mode.
*/
theme?: Theme | DualTheme;
}
export class CartaServerHighlighter extends CartaBase {
public override readonly bundle = () => 'server-highlighter';
public readonly theme?: Theme | DualTheme;
public readonly shikiOptions?: ShikiOptions;
public readonly grammarRules: GrammarRule[];
public readonly highlightingRules: HighlightingRule[];
public constructor(options: ServerHighlighterOptions) {
super(options);
this.theme = options?.theme;
this.shikiOptions = options?.shikiOptions;
this.grammarRules = [];
this.highlightingRules = [];
}
public async init() {
const module = await import('$lib/core/highlight');
highlighter = await module.loadHighlighter({
grammarRules: this.grammarRules,
highlightingRules: this.highlightingRules,
theme: this.theme ?? (await module.loadDefaultTheme()),
shiki: this.shikiOptions
});
this.$setHighlighter(highlighter);
this.initExtensions();
}
}
notes:
ServerHighlighterOptions
vs. BrowserOptions
CartaServerHighlighter
vs. CartaBrowser
grammarRules
and highlightingRules
$setHighlighter
CartaHighlighterBase
) could be added to abstract the common bitsThe design choice is:
onMount()
of every component that uses cartaThis is a question of personal opinion and preference. Personally, I prefer the current design and find that this change is a move in the wrong direction. Open to discussion..
You're right, this is becoming more complex than it need to be. I closed my PR and worked a bit on yours: I cleaned it up a bit (I also think your intellisense does not work correctly), I removed the __ENABLE_CARTA_SSR_ASYNC_PLUGINS_
, as it didn't seem really necessary.
I tested it locally and it seems to work perfectly! The highlight
module is not present in the server bundle.
All you have to do now is edit the vite.config.js
:
import { sveltekit } from '@sveltejs/kit/vite';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit()],
define: {
__ENABLE_CARTA_SSR_HIGHLIGHTER__ : false
}
};
export default config;
Good job everyone. Have a nice day!
:tada: This issue has been resolved in version carta-md-v4.3.0 :tada:
The release is available on:
Your semantic-release bot :package::rocket:
I'm unable to use this package with Cloudflare Pages since the bundle size becomes too large, this is probably due to shiki taking up a large amount of space.
I'd like to mention that I found some documentation that might be helpful, according to the shiki docs it's possible to use a "fine-grained bundle" to reduce the bundle size: shiki.style/guide/install#fine-grained-bundle
I'm using SvelteKit along with the latest version of carta (
4.2.1
), I've included some error messages along with some info on the bundle size below.(!) Some chunks are larger than 500 kB after minification. Consider:
Thank you in advance.