1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-11-05 09:05:39 -05:00

add a *very* basic minifier to remove the insane amount of whitespace from compiled MDX

This commit is contained in:
2024-02-28 14:59:01 -05:00
parent 1c1f2ef9e9
commit e661ca48b8
4 changed files with 64 additions and 24 deletions

25
lib/helpers/minifier.ts Normal file
View File

@@ -0,0 +1,25 @@
import { trimLines } from "trim-lines";
import stripComments from "strip-comments";
// do some _very_ rudimentary JS minifying.
export const minifier = (source: string): string => {
// save the first line for later, it might be important?
const firstLine = source.split("\n")[0];
// remove JS comments
source = stripComments(source, {
block: false,
keepProtected: true,
});
// remove indentation
source = trimLines(source);
// remove newlines
source = source.replace(/\n/g, "");
// restore JSX flags if they were there at the beginning
if (firstLine.startsWith("/*@jsx")) {
source = `${firstLine}${source}`;
}
return source;
};

View File

@@ -6,6 +6,7 @@ import pMap from "p-map";
import pMemoize from "p-memoize"; import pMemoize from "p-memoize";
import matter from "gray-matter"; import matter from "gray-matter";
import { formatDate } from "./format-date"; import { formatDate } from "./format-date";
import { minifier } from "./minifier";
import type { PostFrontMatter, PostWithSource } from "../../types"; import type { PostFrontMatter, PostWithSource } from "../../types";
// path to directory with .mdx files, relative to project root // path to directory with .mdx files, relative to project root
@@ -18,15 +19,15 @@ export const getPostData = async (
frontMatter: PostFrontMatter; frontMatter: PostFrontMatter;
markdown: string; markdown: string;
}> => { }> => {
const fullPath = path.join(process.cwd(), POSTS_DIR, `${slug}.mdx`);
const rawContent = await fs.readFile(fullPath, "utf8");
const { data, content } = matter(rawContent);
const { unified } = await import("unified"); const { unified } = await import("unified");
const { remarkParse, remarkSmartypants, remarkRehype, rehypeSanitize, rehypeStringify } = await import( const { remarkParse, remarkSmartypants, remarkRehype, rehypeSanitize, rehypeStringify } = await import(
"./remark-rehype-plugins" "./remark-rehype-plugins"
); );
const fullPath = path.join(process.cwd(), POSTS_DIR, `${slug}.mdx`);
const rawContent = await fs.readFile(fullPath, "utf8");
const { data, content } = matter(rawContent);
// allow *very* limited markdown to be used in post titles // allow *very* limited markdown to be used in post titles
const parseTitle = async (title: string, allowedTags: string[] = []): Promise<string> => { const parseTitle = async (title: string, allowedTags: string[] = []): Promise<string> => {
return String( return String(
@@ -68,12 +69,12 @@ export const getPostData = async (
// fully parses MDX into JS and returns *everything* about a post // fully parses MDX into JS and returns *everything* about a post
export const compilePost = async (slug: string): Promise<PostWithSource> => { export const compilePost = async (slug: string): Promise<PostWithSource> => {
const { frontMatter, markdown } = await getPostData(slug);
const { remarkGfm, remarkSmartypants, remarkUnwrapImages, rehypeSlug, rehypePrism } = await import( const { remarkGfm, remarkSmartypants, remarkUnwrapImages, rehypeSlug, rehypePrism } = await import(
"./remark-rehype-plugins" "./remark-rehype-plugins"
); );
const { frontMatter, markdown } = await getPostData(slug);
const { compiledSource } = await serialize(markdown, { const { compiledSource } = await serialize(markdown, {
parseFrontmatter: false, parseFrontmatter: false,
mdxOptions: { mdxOptions: {
@@ -105,7 +106,8 @@ export const compilePost = async (slug: string): Promise<PostWithSource> => {
return { return {
frontMatter, frontMatter,
source: { source: {
compiledSource, // save some bytes
compiledSource: minifier(compiledSource),
}, },
}; };
}; };

View File

@@ -26,7 +26,6 @@
"@prisma/client": "^5.10.2", "@prisma/client": "^5.10.2",
"@react-spring/web": "^9.7.3", "@react-spring/web": "^9.7.3",
"@stitches/react": "1.3.1-1", "@stitches/react": "1.3.1-1",
"@vercel/edge": "^1.1.1",
"comma-number": "^2.1.0", "comma-number": "^2.1.0",
"copy-to-clipboard": "^3.3.3", "copy-to-clipboard": "^3.3.3",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
@@ -68,19 +67,22 @@
"remark-unwrap-images": "^4.0.0", "remark-unwrap-images": "^4.0.0",
"sitemap": "^7.1.1", "sitemap": "^7.1.1",
"stitches-normalize": "^3.0.1", "stitches-normalize": "^3.0.1",
"strip-comments": "^2.0.1",
"swr": "^2.2.5", "swr": "^2.2.5",
"trim-lines": "^3.0.1",
"unified": "^11.0.4" "unified": "^11.0.4"
}, },
"devDependencies": { "devDependencies": {
"@jakejarvis/eslint-config": "^3.1.0", "@jakejarvis/eslint-config": "^3.1.0",
"@types/comma-number": "^2.1.2", "@types/comma-number": "^2.1.2",
"@types/node": "^20.11.20", "@types/node": "^20.11.22",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/novnc__novnc": "^1.3.4", "@types/novnc__novnc": "^1.3.4",
"@types/prop-types": "^15.7.11", "@types/prop-types": "^15.7.11",
"@types/react": "^18.2.60", "@types/react": "^18.2.60",
"@types/react-dom": "^18.2.19", "@types/react-dom": "^18.2.19",
"@types/react-is": "^18.2.4", "@types/react-is": "^18.2.4",
"@types/strip-comments": "^2.0.4",
"@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0", "@typescript-eslint/parser": "^7.1.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",

41
pnpm-lock.yaml generated
View File

@@ -29,9 +29,6 @@ dependencies:
'@stitches/react': '@stitches/react':
specifier: 1.3.1-1 specifier: 1.3.1-1
version: 1.3.1-1(react@18.2.0) version: 1.3.1-1(react@18.2.0)
'@vercel/edge':
specifier: ^1.1.1
version: 1.1.1
comma-number: comma-number:
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.0 version: 2.1.0
@@ -155,9 +152,15 @@ dependencies:
stitches-normalize: stitches-normalize:
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.0.1(@stitches/react@1.3.1-1) version: 3.0.1(@stitches/react@1.3.1-1)
strip-comments:
specifier: ^2.0.1
version: 2.0.1
swr: swr:
specifier: ^2.2.5 specifier: ^2.2.5
version: 2.2.5(react@18.2.0) version: 2.2.5(react@18.2.0)
trim-lines:
specifier: ^3.0.1
version: 3.0.1
unified: unified:
specifier: ^11.0.4 specifier: ^11.0.4
version: 11.0.4 version: 11.0.4
@@ -175,8 +178,8 @@ devDependencies:
specifier: ^2.1.2 specifier: ^2.1.2
version: 2.1.2 version: 2.1.2
'@types/node': '@types/node':
specifier: ^20.11.20 specifier: ^20.11.22
version: 20.11.20 version: 20.11.22
'@types/nodemailer': '@types/nodemailer':
specifier: ^6.4.14 specifier: ^6.4.14
version: 6.4.14 version: 6.4.14
@@ -195,6 +198,9 @@ devDependencies:
'@types/react-is': '@types/react-is':
specifier: ^18.2.4 specifier: ^18.2.4
version: 18.2.4 version: 18.2.4
'@types/strip-comments':
specifier: ^2.0.4
version: 2.0.4
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^7.1.0 specifier: ^7.1.0
version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3) version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3)
@@ -943,7 +949,7 @@ packages:
/@types/concat-stream@2.0.0: /@types/concat-stream@2.0.0:
resolution: {integrity: sha512-t3YCerNM7NTVjLuICZo5gYAXYoDvpuuTceCcFQWcDQz26kxUR5uIWolxbIR5jRNIXpMqhOpW/b8imCR1LEmuJw==} resolution: {integrity: sha512-t3YCerNM7NTVjLuICZo5gYAXYoDvpuuTceCcFQWcDQz26kxUR5uIWolxbIR5jRNIXpMqhOpW/b8imCR1LEmuJw==}
dependencies: dependencies:
'@types/node': 20.11.20 '@types/node': 20.11.22
dev: true dev: true
/@types/debug@4.1.12: /@types/debug@4.1.12:
@@ -1020,15 +1026,15 @@ packages:
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
dev: false dev: false
/@types/node@20.11.20: /@types/node@20.11.22:
resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} resolution: {integrity: sha512-/G+IxWxma6V3E+pqK1tSl2Fo1kl41pK1yeCyDsgkF9WlVAme4j5ISYM2zR11bgLFJGLN5sVK40T4RJNuiZbEjA==}
dependencies: dependencies:
undici-types: 5.26.5 undici-types: 5.26.5
/@types/nodemailer@6.4.14: /@types/nodemailer@6.4.14:
resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==}
dependencies: dependencies:
'@types/node': 20.11.20 '@types/node': 20.11.22
dev: true dev: true
/@types/novnc__novnc@1.3.4: /@types/novnc__novnc@1.3.4:
@@ -1064,7 +1070,7 @@ packages:
/@types/sax@1.2.5: /@types/sax@1.2.5:
resolution: {integrity: sha512-9jWta97bBVC027/MShr3gLab8gPhKy4l6qpb+UJLF5pDm3501NvA7uvqVCW+REFtx00oTi6Cq9JzLwgq6evVgw==} resolution: {integrity: sha512-9jWta97bBVC027/MShr3gLab8gPhKy4l6qpb+UJLF5pDm3501NvA7uvqVCW+REFtx00oTi6Cq9JzLwgq6evVgw==}
dependencies: dependencies:
'@types/node': 20.11.20 '@types/node': 20.11.22
dev: false dev: false
/@types/scheduler@0.16.4: /@types/scheduler@0.16.4:
@@ -1074,6 +1080,10 @@ packages:
resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==}
dev: true dev: true
/@types/strip-comments@2.0.4:
resolution: {integrity: sha512-YwcQqIGy90zEHrReYrMTpZfq003Um77WayeE8UwJTHvaM9g9XR9N7GMVSnjRhhDzQYVX375JnB5P6q5kAg221g==}
dev: true
/@types/supports-color@8.1.1: /@types/supports-color@8.1.1:
resolution: {integrity: sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==} resolution: {integrity: sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==}
dev: true dev: true
@@ -1287,10 +1297,6 @@ packages:
/@ungap/structured-clone@1.2.0: /@ungap/structured-clone@1.2.0:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
/@vercel/edge@1.1.1:
resolution: {integrity: sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==}
dev: false
/abbrev@2.0.0: /abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -5601,6 +5607,11 @@ packages:
engines: {node: '>=4'} engines: {node: '>=4'}
dev: true dev: true
/strip-comments@2.0.1:
resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
engines: {node: '>=10'}
dev: false
/strip-final-newline@3.0.0: /strip-final-newline@3.0.0:
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
engines: {node: '>=12'} engines: {node: '>=12'}
@@ -5821,7 +5832,7 @@ packages:
'@types/concat-stream': 2.0.0 '@types/concat-stream': 2.0.0
'@types/debug': 4.1.12 '@types/debug': 4.1.12
'@types/is-empty': 1.2.1 '@types/is-empty': 1.2.1
'@types/node': 20.11.20 '@types/node': 20.11.22
'@types/unist': 3.0.2 '@types/unist': 3.0.2
'@ungap/structured-clone': 1.2.0 '@ungap/structured-clone': 1.2.0
concat-stream: 2.0.0 concat-stream: 2.0.0