Exclude markdownIt from vendor
What problem does this feature solve?
Currently, I have a huge bundle size because prism.js is included in my vendor build. I want to avoid the Mb cost...
What does the proposed changes look like?
Essentially, the markdownit component needs to be available to the asyncData instance directly. I was thinking I could just use require in asnycdata—not sure if this will actually work—but if it were an option in the module that would be a lot easier. Some ways to do that are discussed in the nextjs blog post. https://arunoda.me/blog/ssr-and-server-only-modules
I tried the second option but couldn't get it working... maybe someone had success with another one of the options?
I'd like to second this. I'm trying to find a way to use markdown-it to preprocess my pages on generate.
I believe you can prevent markdown from injecting it's self into your pages:
// nuxt.config.js
markdownit: {
injected: false
},
I use this on my blog and there is no markdownit or prismjs code in my vendor file.
I just gave that a go and it does remove it from the vendor. But it also breaks my app because of when I'm parsing the markdown.
I get the markdown in asyncData then have this in my template:
<post-to-render :content="$md.render(post.body)" />
I just followed the Netlify CMS Nuxt Tutorial. But figured there must be a better way of doing it.
I'd really appreciate it if you could share how you preprocessed your markdown.
It's been a over a year since I wrote this code so it took me a bit to remember where it was all hiding. It turns out that I do still have to include markdownit and prismjs in the page level code, but not in the top level vendor code. I used Contentful as the CMS, so it's probably fairly similar in implementation to Netlify CMS.
<!-- _slug.vue -->
<template>
<section class="blog-post">
<p class="back-link">
<nuxt-link to="/blog/">Back to Latest Blog Posts</nuxt-link>
<a :href="'/blog/amp/' + post.slug + '/'">To AMP Version⚡</a>
</p>
<article>
<div v-if="post.bannerImg" class="banner">
<img :src="post.bannerImg.src" :alt="post.bannerImg.alt" :height="post.bannerImg.height" :width="post.bannerImg.width">
</div>
<h1>{{ post.title }}</h1>
<div class="meta">
<time :datetime="post.publishedAt">Published on {{ post.publishedAt | formatDate }}</time>
</div>
<div class="content" v-html="mdRender(post.content)"></div>
</article>
</section>
</template>
<script src="~/mixins/slug/slug.js"></script>
<style lang="scss">
@import "~/mixins/slug/slug.scss";
</style>
// slug.scss
@import "~/node_modules/prismjs/themes/prism-tomorrow.css";
.blog-post {
.content {
pre {
margin-bottom: 1.4rem;
}
p code {
color: $color-white;
background-color: $color-bg-secondary;
padding: .25rem .5rem;
border-radius: .4rem;
}
pre {
background-color: $color-bg-secondary;
padding: 2rem;
code {
white-space: pre-wrap;
}
@include for-phone-only {
padding: .5rem;
overflow-x: scroll;
code {
white-space: pre;
}
}
}
}
}
// slug.js
import MarkdownIt from 'markdown-it'
import MDPrism from 'markdown-it-prism'
import stripMd from '~/mixins/stripMd'
import { formatDate } from '~/mixins/filters'
import contentfulClient from '~/plugins/contentful'
const md = new MarkdownIt()
md.use(MDPrism)
const processPost = (post) => {
return {
post: {
title: post.fields.title,
slug: post.fields.slug,
publishedAt: post.sys.createdAt,
updatedAt: post.sys.updatedAt,
description: post.fields.description,
content: post.fields.content,
bannerImg: post.fields.banner ? {
src: 'https:' + post.fields.banner.fields.file.url,
alt: post.fields.banner.fields.description,
height: post.fields.banner.fields.file.details.image.height,
width: post.fields.banner.fields.file.details.image.width
} : null
}
}
}
export default {
head () {
const rawContent = stripMd(this.post.content)
return {
title: this.post.title,
meta: [
{ hid: 'description', name: 'description', content: this.post.description }
],
link: [
{ rel: 'canonical', href: `/blog/${this.post.slug}/` },
{ rel: 'amphtml', href: `/blog/amp/${this.post.slug}/` }
],
script: [ ],
__dangerouslyDisableSanitizers: ['script']
}
},
filters: { formatDate },
asyncData ({ params, error, payload }) {
if (payload) return processPost(payload)
return contentfulClient
.getEntries({
content_type: 'blogPost',
'fields.slug': params.slug,
})
.then(entries => {
if (entries.items.length == 0) {
throw new Error('article not found')
}
return processPost(entries.items[0])
})
.catch(e => { error({ statusCode: 404, message: e.message }) })
},
methods: {
mdRender (content) {
if (!content) return ''
return md.render(content)
}
}
}
I tried your solution but the markdown-it module stay in vendor app when i run webpack analyse
Is there still no simple solution out there to render markdown on build? It seems silly to include this package when using static site generation.