From fbfedee5988636d2e4a3a2ea817e8bdf8628d4f5 Mon Sep 17 00:00:00 2001 From: Lennart Date: Mon, 25 Nov 2019 14:57:20 +0100 Subject: [PATCH] feat(gatsby-theme-minimal-blog): Lazy load code component (#167) * add loadable to code component of minimal blog * add bundle analyser to example * chore(deps): update dependency @types/theme-ui to ^0.2.5 (#161) * chore(deps): update dependency lerna to ^3.19.0 (#163) * chore(deps): update dependency ts-jest to ^24.2.0 (#164) * chore(deps): update linting & formatting + typescript (#165) * fix(deps): update gatsby (#166) Co-authored-by: null <29139614+renovate[bot]@users.noreply.github.com> --- examples/minimal-blog/gatsby-config.js | 1 + examples/minimal-blog/package.json | 3 +- themes/gatsby-theme-minimal-blog/package.json | 1 + .../src/components/code.tsx | 40 +++-- .../gatsby-theme-minimal-blog/src/index.d.ts | 3 +- .../gatsby-theme-minimal-blog/src/types.d.ts | 149 ++++++++++++++++++ yarn.lock | 93 ++++++++++- 7 files changed, 270 insertions(+), 20 deletions(-) create mode 100644 themes/gatsby-theme-minimal-blog/src/types.d.ts diff --git a/examples/minimal-blog/gatsby-config.js b/examples/minimal-blog/gatsby-config.js index 561d028e4..724bf4f9e 100644 --- a/examples/minimal-blog/gatsby-config.js +++ b/examples/minimal-blog/gatsby-config.js @@ -54,5 +54,6 @@ module.exports = { }, `gatsby-plugin-offline`, `gatsby-plugin-netlify`, + // `gatsby-plugin-webpack-bundle-analyser-v2`, ], } diff --git a/examples/minimal-blog/package.json b/examples/minimal-blog/package.json index 76ae21095..a09e29ca6 100644 --- a/examples/minimal-blog/package.json +++ b/examples/minimal-blog/package.json @@ -27,6 +27,7 @@ "react-dom": "^16.9.0" }, "devDependencies": { - "cross-env": "^5.2.0" + "cross-env": "^5.2.0", + "gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.8" } } diff --git a/themes/gatsby-theme-minimal-blog/package.json b/themes/gatsby-theme-minimal-blog/package.json index ad3a7cb69..1734eb855 100644 --- a/themes/gatsby-theme-minimal-blog/package.json +++ b/themes/gatsby-theme-minimal-blog/package.json @@ -22,6 +22,7 @@ "dependencies": { "@emotion/core": "^10.0.22", "@lekoarts/gatsby-theme-minimal-blog-core": "^1.0.1", + "@loadable/component": "^5.10.3", "@mdx-js/react": "^1.1.5", "@theme-ui/color": "^0.2.49", "@theme-ui/components": "^0.2.49", diff --git a/themes/gatsby-theme-minimal-blog/src/components/code.tsx b/themes/gatsby-theme-minimal-blog/src/components/code.tsx index 17aa409d1..007c56519 100644 --- a/themes/gatsby-theme-minimal-blog/src/components/code.tsx +++ b/themes/gatsby-theme-minimal-blog/src/components/code.tsx @@ -1,9 +1,8 @@ /* eslint react/destructuring-assignment: 0 */ import React from "react" -import Highlight, { defaultProps, Language } from "prism-react-renderer" -import theme from "prism-react-renderer/themes/nightOwl" -import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live" +import loadable from "@loadable/component" import useSiteMetadata from "../hooks/use-site-metadata" +import { HighlightInnerProps, Language } from "../types" type CodeProps = { codeString: string @@ -13,6 +12,27 @@ type CodeProps = { [key: string]: any } +const LazyHighlight = loadable(async () => { + const Module = await import(`prism-react-renderer`) + const Highlight = Module.default + const { defaultProps } = Module + return (props: any) => +}) + +const LazyLiveProvider = loadable(async () => { + const Module = await import(`react-live`) + const { LiveProvider, LiveEditor, LiveError, LivePreview } = Module + return (props: any) => ( + + + + + + ) +}) + +const theme = loadable(() => import(`prism-react-renderer/themes/nightOwl`)) + function getParams(className = ``) { const [lang = ``, params = ``] = className.split(`:`) @@ -67,17 +87,11 @@ const Code = ({ const hasLineNumbers = !noLineNumbers && language !== `noLineNumbers` && showLineNumbers if (props[`react-live`]) { - return ( - - - - - - ) + return } return ( - - {({ className, style, tokens, getLineProps, getTokenProps }) => ( + + {({ className, style, tokens, getLineProps, getTokenProps }: HighlightInnerProps) => ( {title && (
@@ -106,7 +120,7 @@ const Code = ({
)} -
+ ) } diff --git a/themes/gatsby-theme-minimal-blog/src/index.d.ts b/themes/gatsby-theme-minimal-blog/src/index.d.ts index e23de2d9d..759edae00 100644 --- a/themes/gatsby-theme-minimal-blog/src/index.d.ts +++ b/themes/gatsby-theme-minimal-blog/src/index.d.ts @@ -1,3 +1,4 @@ declare module "@theme-ui/components" declare module "@theme-ui/color" -declare module "lodash.kebabcase" \ No newline at end of file +declare module "lodash.kebabcase" +declare module "@loadable/component" \ No newline at end of file diff --git a/themes/gatsby-theme-minimal-blog/src/types.d.ts b/themes/gatsby-theme-minimal-blog/src/types.d.ts new file mode 100644 index 000000000..31960f46d --- /dev/null +++ b/themes/gatsby-theme-minimal-blog/src/types.d.ts @@ -0,0 +1,149 @@ +import * as React from "react" + +export type Language = + | "markup" + | "bash" + | "clike" + | "c" + | "cpp" + | "css" + | "javascript" + | "jsx" + | "coffeescript" + | "actionscript" + | "css-extr" + | "diff" + | "git" + | "go" + | "graphql" + | "handlebars" + | "json" + | "less" + | "makefile" + | "markdown" + | "objectivec" + | "ocaml" + | "python" + | "reason" + | "sass" + | "scss" + | "sql" + | "stylus" + | "tsx" + | "typescript" + | "wasm" + | "yaml" + +type Token = { + types: string[] + content: string + empty?: boolean +} + +type PrismGrammar = { + [key: string]: any +} + +type LanguageDict = { [lang in Language]: PrismGrammar } + +type PrismLib = { + languages: LanguageDict + tokenize: (code: string, grammar: PrismGrammar, language: Language) => PrismToken[] | string[] + highlight: (code: string, grammar: PrismGrammar, language: Language) => string +} + +type PrismThemeEntry = { + color?: string + backgroundColor?: string + fontStyle?: "normal" | "italic" + fontWeight?: "normal" | "bold" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" + textDecorationLine?: "none" | "underline" | "line-through" | "underline line-through" + opacity?: number + [styleKey: string]: string | number | void +} + +type PrismTheme = { + plain: PrismThemeEntry + styles: Array<{ + types: string[] + style: PrismThemeEntry + languages?: Language[] + }> +} + +type ThemeDict = { + root: StyleObj + plain: StyleObj + [type: string]: StyleObj +} + +type PrismToken = { + type: string + content: Array | string +} + +type StyleObj = { + [key: string]: string | number | null +} + +type LineInputProps = { + key?: React.Key + style?: StyleObj + className?: string + line: Token[] + [otherProp: string]: any +} + +type LineOutputProps = { + key?: React.Key + style?: StyleObj + className: string + [otherProps: string]: any +} + +type TokenInputProps = { + key?: React.Key + style?: StyleObj + className?: string + token: Token + [otherProp: string]: any +} + +type TokenOutputProps = { + key?: React.Key + style?: StyleObj + className: string + children: string + [otherProp: string]: any +} + +type RenderProps = { + tokens: Token[][] + className: string + style: StyleObj + getLineProps: (input: LineInputProps) => LineOutputProps + getTokenProps: (input: TokenInputProps) => TokenOutputProps +} + +type DefaultProps = { + Prism: PrismLib + theme: PrismTheme +} + +interface HighlightProps { + Prism: PrismLib + theme?: PrismTheme + language: Language + code: string + children: (props: RenderProps) => React.ReactNode +} + +export interface HighlightInnerProps { + className: string + style: StyleObj + tokens: Token[][] + themeDict: ThemeDict + getLineProps: (lineInputProps: LineInputProps) => LineOutputProps + getStyleForToken: (token: Token) => { [inlineStyle: string]: string } + getTokenProps: (tokenInputPropsL: TokenInputProps) => TokenOutputProps +} diff --git a/yarn.lock b/yarn.lock index cd0be60b3..02246c073 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2308,6 +2308,14 @@ npmlog "^4.1.2" write-file-atomic "^2.3.0" +"@loadable/component@^5.10.3": + version "5.10.3" + resolved "https://registry.yarnpkg.com/@loadable/component/-/component-5.10.3.tgz#e1ad811ac4834a6ed187605d8464351d0c52896f" + integrity sha512-/aSO+tXw4vFMwZ6fgLaNQgLuEa7bgTpoBE4PxNzf08/ewAjymrCS3J7v3SbGE7IjGmmKL6vVwkpb7S3cYrk+ag== + dependencies: + "@babel/runtime" "^7.6.0" + hoist-non-react-statics "^3.3.0" + "@mdx-js/mdx@^1.3.1", "@mdx-js/mdx@^1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.5.1.tgz#470ce07e01cef4f7b1d5051640e5235d5e75aebb" @@ -3391,7 +3399,7 @@ acorn-jsx@^5.1.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== -acorn-walk@^6.0.1: +acorn-walk@^6.0.1, acorn-walk@^6.1.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== @@ -3401,7 +3409,7 @@ acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1, acorn@^6.2.1: +acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== @@ -4248,6 +4256,16 @@ better-queue@^3.8.10: node-eta "^0.9.0" uuid "^3.0.0" +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -4960,6 +4978,11 @@ check-more-types@2.24.0: resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== + cheerio@^0.22.0: version "0.22.0" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" @@ -5338,7 +5361,7 @@ commander@2.15.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== -commander@^2.11.0, commander@^2.20.0, commander@~2.20.3: +commander@^2.11.0, commander@^2.18.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -6934,6 +6957,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + electron-to-chromium@^1.3.306, electron-to-chromium@^1.3.47: version "1.3.309" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.309.tgz#9e1e5e23c73d04f0364e524afaafd6659289ae1b" @@ -7682,7 +7710,7 @@ express-graphql@^0.9.0: http-errors "^1.7.3" raw-body "^2.4.1" -express@^4.17.1: +express@^4.16.3, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -8033,6 +8061,11 @@ filesize@3.5.11: resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee" integrity sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g== +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -8660,6 +8693,14 @@ gatsby-plugin-typescript@^2.1.19: "@babel/runtime" "^7.7.2" babel-plugin-remove-graphql-queries "^2.7.16" +gatsby-plugin-webpack-bundle-analyser-v2@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/gatsby-plugin-webpack-bundle-analyser-v2/-/gatsby-plugin-webpack-bundle-analyser-v2-1.1.8.tgz#2fd3e44c71b0fa74b6cf574f447e699a8e187e0a" + integrity sha512-xVC6JYP1n1CaLml9VTBqdrmBEkCUgcAk5jW8hpJVH9gAn3dVQYyOgUxAavi88ZBLN7Ff6M7uZ80COMRWtdlpbA== + dependencies: + "@babel/runtime" "^7.7.2" + webpack-bundle-analyzer "^3.6.0" + gatsby-react-router-scroll@^2.1.16: version "2.1.16" resolved "https://registry.yarnpkg.com/gatsby-react-router-scroll/-/gatsby-react-router-scroll-2.1.16.tgz#7e1ac76ceda23d049fe1453bed3cb0c3664a94de" @@ -9405,6 +9446,14 @@ gzip-size@3.0.0: dependencies: duplexer "^0.1.1" +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + handle-thing@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" @@ -9666,6 +9715,11 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: version "2.8.5" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" @@ -13612,6 +13666,11 @@ opencollective-postinstall@^2.0.2: resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== +opener@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" + integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + opentracing@^0.14.4: version "0.14.4" resolved "https://registry.yarnpkg.com/opentracing/-/opentracing-0.14.4.tgz#a113408ea740da3a90fde5b3b0011a375c2e4268" @@ -17924,6 +17983,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-2.2.1.tgz#c5bf04a5bbec3fd118be4084461b3a27c4d796bf" integrity sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q== +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + ts-jest@^24.2.0: version "24.2.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.2.0.tgz#7abca28c2b4b0a1fdd715cd667d65d047ea4e768" @@ -18719,6 +18783,25 @@ webpack-assets-manifest@^3.1.1: tapable "^1.0.0" webpack-sources "^1.0.0" +webpack-bundle-analyzer@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz#39b3a8f829ca044682bc6f9e011c95deb554aefd" + integrity sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g== + dependencies: + acorn "^6.0.7" + acorn-walk "^6.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.15" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + webpack-dev-middleware@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" @@ -19329,7 +19412,7 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^6.2.1: +ws@^6.0.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==