diff --git a/components/Image/Image.tsx b/components/Image/Image.tsx index 64183e9b..949e7a9f 100644 --- a/components/Image/Image.tsx +++ b/components/Image/Image.tsx @@ -4,7 +4,17 @@ import type { ImageProps as NextImageProps } from "next/image"; import styles from "./Image.module.css"; -const Image = ({ src, width, height, placeholder, alt, quality, priority, className, ...rest }: NextImageProps) => { +const CustomImage = ({ + src, + width, + height, + placeholder, + alt, + quality, + priority, + className, + ...rest +}: NextImageProps) => { // passed directly into next/image: https://nextjs.org/docs/api-reference/next/image const imageProps: Partial = { width, @@ -36,4 +46,4 @@ const Image = ({ src, width, height, placeholder, alt, quality, priority, classN ); }; -export default Image; +export default CustomImage; diff --git a/lib/parse-notes.ts b/lib/parse-notes.ts index a33a0b8a..d9901e9a 100644 --- a/lib/parse-notes.ts +++ b/lib/parse-notes.ts @@ -3,6 +3,7 @@ import path from "path"; import { renderToStaticMarkup } from "react-dom/server"; import matter from "gray-matter"; import { serialize } from "next-mdx-remote/serialize"; +import { minify } from "terser"; import { compiler } from "markdown-to-jsx"; import removeMarkdown from "remove-markdown"; import sanitizeHtml from "sanitize-html"; @@ -62,6 +63,7 @@ export const getNoteData = (slug: string): { frontMatter: NoteMetaType; content: }; }; +// fully parses MDX into JS and returns *everything* about a note export const getNote = async (slug: string): Promise => { const { frontMatter, content } = getNoteData(slug); const source = await serialize(content, { @@ -78,7 +80,17 @@ export const getNote = async (slug: string): Promise => { return { frontMatter, - source, + source: { + // next-mdx-remote v4 doesn't (yet?) minify compiled JSX output, see: + // https://github.com/hashicorp/next-mdx-remote/pull/211#issuecomment-1013658514 + // ...so do it manually (and conservatively) with terser for now. + compiledSource: ( + await minify(source.compiledSource, { + parse: { bare_returns: true }, + mangle: false, + }) + ).code, + }, }; }; diff --git a/package.json b/package.json index 90bb4230..f94d58e0 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ "lint": "run-s lint:*", "lint:next": "eslint .", "lint:css": "stylelint '**/*.css'", - "lint:prettier": "prettier --check .", - "postinstall": "next telemetry disable" + "lint:prettier": "prettier --check ." }, "dependencies": { "@fontsource/comic-neue": "4.5.1", @@ -36,12 +35,12 @@ "classnames": "^2.3.1", "copy-to-clipboard": "^3.3.1", "date-fns": "^2.28.0", + "escape-goat": "^4.0.0", "fathom-client": "^3.3.1", "faunadb": "^4.4.1", "feed": "^4.2.2", "formik": "^2.2.9", "gray-matter": "^4.0.3", - "html-escaper": "^3.0.3", "is-absolute-url": "^4.0.1", "is-email-like": "^2.0.0", "markdown-to-jsx": "^7.1.6", @@ -72,12 +71,12 @@ "sanitize-html": "^2.6.1", "simple-icons": "^6.7.0", "swr": "^1.1.2", + "terser": "^5.10.0", "twemoji": "github:twitter/twemoji#v13.1.0" }, "devDependencies": { "@jakejarvis/eslint-config": "github:jakejarvis/eslint-config#main", "@svgr/webpack": "^6.2.0", - "@types/html-escaper": "^3.0.0", "@types/node": "^17.0.10", "@types/prop-types": "^15.7.4", "@types/react": "^17.0.38", diff --git a/pages/notes/[slug].tsx b/pages/notes/[slug].tsx index 551bf94b..6c60fb60 100644 --- a/pages/notes/[slug].tsx +++ b/pages/notes/[slug].tsx @@ -1,7 +1,7 @@ import { InView } from "react-intersection-observer"; import { NextSeo, ArticleJsonLd } from "next-seo"; import { MDXRemote } from "next-mdx-remote"; -import { escape } from "html-escaper"; +import { htmlEscape } from "escape-goat"; import Content from "../../components/Content/Content"; import NoteMeta from "../../components/NoteMeta/NoteMeta"; import NoteTitle from "../../components/NoteTitle/NoteTitle"; @@ -42,8 +42,8 @@ const Note = ({ frontMatter, source }: NoteType) => { />