4

In my current NextJS project, I am using Tailwind as a CSS framework. When I run yarn dev, everything works fine, but whenever I run yarn build followed by a yarn start, all of my CSS seems to be purged as the layout of my page is completely different.

Before: enter image description here

After: enter image description here

My tailwind.config.js file:

    /* eslint-disable global-require */

const defaultTheme = require('tailwindcss/defaultTheme');

module.exports = {
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    screens: {
      sm: '640px',
      md: '768px',
      max_md: { max: '767px' },
      lg: '1024px',
      xl: '1536px',
    },
    colors: {
      primary: '#f2a53f',
      white: '#fff',
    },
    fontFamily: {
      title: ['Dancing Script', 'Times New Roman', 'sans-serif'],
      sans: ['Roboto', ...defaultTheme.fontFamily.sans],
    },
    textShadow: {
      default: '1px 1px 3px #000',
    },
    zIndex: {
      1: -1,
    },
    extend: {
      height: {
        128: '32rem',
      },
      margin: {},
    },
  },
  variants: {
    extend: {},
  },
  plugins: [require('tailwindcss-textshadow')],
};

postcss.config.js file:

const purgecss = [
  '@fullhuman/postcss-purgecss',
  {
    content: [
      './pages/**/*.{js,jsx,ts,tsx}',
      './components/**/*.{js,jsx,ts,tsx}',
    ],
    defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
  },
];

module.exports = {
  plugins: [
    'tailwindcss',
    process.env.NODE_ENV === 'production' ? purgecss : undefined,
  ],
};

_app.tsx:

import Head from 'next/head';
import { ApolloProvider } from '@apollo/client';
import { AppProps } from 'next/app';
import { useApollo } from '../../apollo/client';

import '../styles/globals.css';

const MyApp = ({ Component, pageProps }: AppProps) => (
  <ApolloProvider client={useApollo(pageProps.initialApolloState)}>
    <Component {...pageProps} />
  </ApolloProvider>
);

export default MyApp;

globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

@font-face {
  font-family: 'Dancing Script';
  font-style: medium;
  font-weight: 500;
  font-display: swap;
  src: local('Dancing Script'),
    url(/fonts/DancingScript-Medium.tff) format('tff');
}
body {
  margin: 0 !important;
}

package.json dependencies:

"dependencies": {
    "@apollo/client": "3.3.12",
    "@apollo/react-hooks": "4.0.0",
    "@contentful/rich-text-react-renderer": "14.1.2",
    "@contentful/rich-text-types": "14.1.2",
    "apollo-cache-inmemory": "1.6.6",
    "apollo-client": "2.6.10",
    "apollo-link-http": "1.5.17",
    "autoprefixer": "10.2.5",
    "clsx": "1.1.1",
    "contentful": "8.2.0",
    "graphql": "15.5.0",
    "graphql-tag": "2.11.0",
    "next": "10.0.9",
    "next-with-apollo": "5.1.1",
    "postcss": "8.2.8",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-icons": "4.2.0",
    "tailwindcss": "2.0.4",
    "tailwindcss-textshadow": "2.1.3"
  },
  "devDependencies": {
    "@commitlint/cli": "12.0.1",
    "@commitlint/config-conventional": "12.0.1",
    "@fullhuman/postcss-purgecss": "4.0.3",
    "@types/node": "14.14.35",
    "@types/react": "17.0.3",
    "@types/react-dom": "17.0.2",
    "@typescript-eslint/eslint-plugin": "4.18.0",
    "@typescript-eslint/parser": "4.18.0",
    "add": "2.0.6",
    "commitizen": "4.2.3",
    "cz-conventional-changelog": "3.3.0",
    "eslint": "7.22.0",
    "eslint-config-airbnb": "18.2.1",
    "eslint-config-prettier": "8.1.0",
    "eslint-import-resolver-typescript": "2.4.0",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-prettier": "3.3.1",
    "eslint-plugin-react": "7.22.0",
    "eslint-plugin-react-hooks": "4.2.0",
    "husky": "5.1.3",
    "lint-staged": "10.5.4",
    "postcss-preset-env": "6.7.0",
    "prettier": "2.2.1",
    "typescript": "4.2.3",
    "yarn": "1.22.10"
  },
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  }

If there is anything that seems off, feel free to let me know. I have looked at other issues online but did not find and solution to my problem.

4

2 回答 2

12

仔细检查tailwind.config.js. 如果您的组件不在components目录中,那么您需要更新purge路径以反映这一点。

于 2021-05-07T10:24:18.580 回答
2

我想我看到了这个问题。@fullhuman/postcss-purgecss从 v1.4 左右开始与 tailwindcss 捆绑在一起。由于它也是在您的 postcss 文件中手动声明的,因此它被执行了两次,这会擦除您的所有样式。此外,它仅在生产中擦除您的样式这一事实表明它是罪魁祸首,因为该特定包的执行取决于process.env.NODE_ENV===production. 从您的 postcss 文件中删除它应该可以解决您的问题,因为它已经由 tailwindcss 包在后台执行。

这是我的postcsstailwindcss@2.0.3用于比较:

postcss.config.js

module.exports = {
    plugins: [
        'postcss-import',
        'tailwindcss',
        'postcss-nesting',
        'postcss-flexbugs-fixes',
        [
            'postcss-preset-env',
            {
                autoprefixer: {
                    flexbox: 'no-2009'
                },
                stage: 3,
                features: {
                    'custom-properties': false,
                    'nesting-rules': true
                }
            }
        ]
    ]
};

另一种可能性是您没有将要清除的路径/​​文件类型包装在顶级content对象中。从为您的tailwind.config.js文件提供的代码中:

module.exports = {
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  //...
}

这是我tailwind.config.js的交叉比较

const defaultTheme = require('tailwindcss/defaultTheme');

module.exports = {
    important: true,
    purge: {
        content: [
            './components/**/*.{js,ts,jsx,tsx}',
            './pages/**/*.{js,ts,jsx,tsx}'
        ],
        options: {
            safelist: {
                standard: ['outline-none']
            }
        }
    },
    darkMode: 'class',
    theme: {
        lineClamp: {
            1: 1,
            2: 2,
            3: 3,
            4: 4
        },
        extend: {
            zIndex: {
                '-10': '-10',
                100: '100',
                150: '150'
            },
            maxWidth: {
                '9xl': '121rem', // 1936px
                '8xl': '96rem' // 1536px
            },
            screens: {
                xs: '375px',
                sm: '640px',
                md: '768px',
                lg: '1024px',
                xl: '1280px',
                '2xl': '1440px',
                '3xl': '1920px'
            },
            transitionDuration: {
                0: '0ms',
                300: '300ms',
                500: '500ms',
                700: '700ms',
                1000: '1000ms'
            },
            rotate: {
                0: '0deg',
                45: '45deg',
                90: '90deg',
                125: '125deg',
                180: '180deg',
                270: '270deg',
                360: '360deg'
            },
            fontFamily: {
                header: ['goudy-bookletter-1911', 'serif'],
                poppins: ['poppins', 'sans-serif'],
                somaRoman: ['neue-haas-grotesk-text', 'sans-serif'],
                somaDisplay: ['neue-haas-grotesk-display', 'sans-serif'],
                sans: ['Inter var', ...defaultTheme.fontFamily.sans]
            },
            colors: {
                'reddit-0': 'var(--reddit-0)',
                'reddit-1': 'var(--reddit-1)',
                'reddit-2': 'var(--reddit-2)',
                'reddit-3': 'var(--reddit-3)',
                'reddit-4': 'var(--reddit-4)',
                'primary-0': 'var(--primary-0)',
                'primary-1': 'var(--primary-1)',
                'primary-2': 'var(--primary-2)',
                'primary-3': 'var(--primary-3)',
                'primary-4': 'var(--primary-4)',
                'primary-5': 'var(--primary-5)',
                'primary-6': 'var(--primary-6)',
                'primary-7': 'var(--primary-7)',
                'primary-8': 'var(--primary-8)',
                'primary-9': 'var(--primary-9)',
                'secondary-0': 'var(--secondary-0)',
                'secondary-1': 'var(--secondary-1)',
                'secondary-2': 'var(--secondary-2)',
                'accents-0': 'var(--accents-0)',
                'accents-1': 'var(--accents-1)',
                'accents-2': 'var(--accents-2)',
                'accents-3': 'var(--accents-3)',
                'accents-4': 'var(--accents-4)',
                'accents-5': 'var(--accents-5)',
                'accents-6': 'var(--accents-6)',
                'accents-7': 'var(--accents-7)',
                'accents-8': 'var(--accents-8)',
                'accents-9': 'var(--accents-9)',
                'theme-0': 'var(--theme-0)',
                'theme-1': 'var(--theme-1)',
                lightBlue: {
                    0: '#E3F8FF',
                    100: '#B3ECFF',
                    200: '#81DEFD',
                    300: '#5ED0FA',
                    400: '#40C3F7',
                    500: '#2BB0ED',
                    600: '#1992D4',
                    700: '#127FBF',
                    800: '#0B69A3',
                    900: '#035388'
                },
                cyan: {
                    0: '#E0FCFF',
                    100: '#BEF8FD',
                    200: '#87EAF2',
                    300: '#54D1DB',
                    400: '#38BEC9',
                    500: '#2CB1BC',
                    600: '#14919B',
                    700: '#0E7C86',
                    800: '#0A6C74',
                    900: '#044E54'
                },
                rojo: {
                    0: '#610316',
                    100: '#8A041A',
                    200: '#AB091E',
                    300: '#CF1124',
                    400: '#E12D39',
                    500: '#EF4E4E',
                    600: '#F86A6A',
                    700: '#FF9B9B',
                    800: '#FFBDBD',
                    900: '#FFE3E3'
                },
                rosado: {
                    0: '#620042',
                    100: '#870557',
                    200: '#A30664',
                    300: '#BC0A6F',
                    400: '#DA127D',
                    500: '#E8368F',
                    600: '#F364A2',
                    700: '#FF8CBA',
                    800: '#FFB8D2',
                    900: '#FFE3EC'
                },
                amarillo: {
                    0: 'hsl(15, 86%, 30%)',
                    100: 'hsl(22, 82%, 39%)',
                    200: 'hsl(29, 80%, 44%)',
                    300: 'hsl(36, 77%, 49%)',
                    400: 'hsl(42, 87%, 55%)',
                    500: 'hsl(44, 92%, 63%)',
                    600: 'hsl(48, 94%, 68%)',
                    700: 'hsl(48, 95%, 76%)',
                    800: 'hsl(48, 100%, 88%)',
                    900: 'hsl(49, 100%, 96%)'
                },
                verdeAzulado: {
                    // blueish-green === teal (espanol)
                    0: 'hsl(170, 97%, 15%)',
                    100: 'hsl(168, 80%, 23%)',
                    200: 'hsl(166, 72%, 28%)',
                    300: 'hsl(164, 71%, 34%)',
                    400: 'hsl(162, 63%, 41%)',
                    500: 'hsl(160, 51%, 49%)',
                    600: 'hsl(158, 58%, 62%)',
                    700: 'hsl(156, 73%, 74%)',
                    800: 'hsl(154, 75%, 87%)',
                    900: 'hsl(152, 68%, 96%)'
                },
                redditRed: '#FF4500',
                redditNav: '#1A1A1B',
                redditSearch: '#272729',
                redditBG: '#141415'
            },
            keyframes: {
                wiggle: {
                    '0%, 100%': { transform: 'rotate(-3deg)' },
                    '50%': { transform: 'rotate(3deg)' }
                },
                hero: {
                    transform: 'translate3d(0px, 0px, 0px)'
                }
            },
            animation: {
                wiggle: 'wiggle 10s ease-in-out infinite',
                hero: 'hero 1s ease-in-out infinite',
                slowPing: 'pulse 10s cubic-bezier(0, 0, 0.2, 1) infinite'
            },
            width: {
                82: '20.5rem',
                100: '25rem',
                200: '50rem',
                '8xl': '96rem'
            },
            height: {
                75: '75vh'
            },
            spacing: {
                7: '1.75rem',
                14: '3.5rem',
                18: '4.5rem',
                25: '6.25rem',
                26: '6.5rem',
                28: '7rem',
                44: '11rem',
                82: '20.5rem',
                100: '25rem',
                104: '26rem',
                156: '39rem'
            },
            boxShadow: {
                'outline-2': '0 0 0 2px var(--accents-0)',
                magical:
                    'rgba(0, 0, 0, 0.02) 0px 30px 30px, rgba(0, 0, 0, 0.03) 0px 0px 8px, rgba(0, 0, 0, 0.05) 0px 1px 0px',
                cardHover:
                    '0 4px 4.1px rgba(0, 0, 0, 0.012),0 4.9px 5.8px rgba(0, 0, 0, 0.018),0 6.3px 8.4px rgba(0, 0, 0, 0.029),0 8.8px 12.9px rgba(0, 0, 0, 0.05),0 15px 23px rgba(0, 0, 0, 0.11)'
            }
        },
        variants: {
            padding: [
                'responsive',
                'group-hover',
                'hover',
                'focus',
                'even',
                'odd',
                'first',
                'last'
            ],
            textColor: [
                'responsive',
                'group-hover',
                'hover',
                'focus',
                'even',
                'first',
                'last',
                'odd'
            ],
            backgroundColor: [
                'responsive',
                'group-hover',
                'hover',
                'focus',
                'even',
                'first',
                'last',
                'odd'
            ],
            display: ['responsive', 'hover', 'group-hover'],
            visibility: ['responsive', 'hover', 'group-hover'],
            transitionDuration: ['responsive', 'hover', 'group-hover'],
            gridColumn: ['responsive', 'hover', 'first', 'odd', 'even'],
            extend: {
                ringWidth: [
                    'responsive',
                    'hover',
                    'active',
                    'focus',
                    'group-hover'
                ],
                ringColor: [
                    'responsive',
                    'hover',
                    'active',
                    'focus',
                    'group-hover'
                ],
                fontSize: ['responsive', 'last', 'first', 'hover', 'focus'],
                stroke: ['responsive', 'hover', 'focus', 'group-hover'],
                fill: ['responsive', 'hover', 'focus', 'group-hover'],
                gridTemplateColumns: [
                    'responsive',
                    'last',
                    'first',
                    'hover',
                    'focus'
                ],
                animation: [
                    'responsive',
                    'hover',
                    'focus',
                    'motion-safe',
                    'motion-reduce'
                ],
                transitionProperty: [
                    'responsive',
                    'hover',
                    'focus',
                    'motion-safe',
                    'motion-reduce'
                ],
                transitionDuration: ['responsive', 'hover', 'focus'],
                transitionTimingFunction: ['responsive', 'hover', 'focus'],
                transitionDelay: ['responsive', 'hover', 'focus'],
                scale: [
                    'responsive',
                    'hover',
                    'focus',
                    'active',
                    'group-hover'
                ],
                rotate: [
                    'responsive',
                    'hover',
                    'focus',
                    'active',
                    'group-hover'
                ]
            }
        }
    },
    plugins: [
        require('tailwindcss-line-clamp'),
        require('@tailwindcss/typography'),
        require('@tailwindcss/forms'),
        require('@tailwindcss/aspect-ratio')
    ]
};

如果你想知道为什么我postcss-import之前tailwindcss在 postcss.config.js 中使用了这个包,它是为了分离关注点和更简洁的代码。我有一个包含、、、和的顶级styles目录。它们的内容如下:index.cssbase.cssutilities.csscomponents.csschrome-bug.css

index.css

@import 'tailwindcss/base';
@import './base.css';

@import 'tailwindcss/components';
@import './components.css';

@import 'tailwindcss/utilities';
@import './utilities.css';

components.css

.fit {
    min-height: calc(100vh - 88px);
}

utilities.css

#tsparticles {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    margin: 0;
}

.skeleton {
    display: block;
    width: 100%;
    border-radius: 5px;

    background-image: linear-gradient(
        270deg,
        var(--accents-1),
        var(--accents-2),
        var(--accents-2),
        var(--accents-1)
    );
    background-size: 400% 100%;
    animation: loading 8s ease-in-out infinite;
}

@keyframes loading {
    0% {
        background-position: 200% 0;
    }
    100% {
        background-position: -200% 0;
    }
}

base.css

#__next {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

:root {
    --reddit-0: hsl(240, 2%, 8%);
    --reddit-1: hsl(240, 2%, 10%);
    --reddit-2: hsl(240, 3%, 16%);
    --reddit-3: hsl(16, 100%, 50%);
    --primary-0: hsl(209, 61%, 16%);
    --primary-1: hsl(211, 39%, 23%);
    --primary-2: hsl(209, 34%, 30%);
    --primary-3: hsl(209, 28%, 39%);
    --primary-4: hsl(210, 22%, 49%);
    --primary-5: hsl(209, 23%, 60%);
    --primary-6: hsl(211, 27%, 70%);
    --primary-7: hsl(210, 31%, 80%);
    --primary-8: hsl(212, 33%, 89%);
    --primary-9: hsl(210, 36%, 96%);
    --secondary-0: #d7be69;
    --secondary-1: #486581;
    --secondary-2: #9fb3c8;
    --accents-0: hsl(195, 7%, 11%);
    --accents-1: hsl(140, 2%, 26%);
    --accents-2: hsl(0, 0%, 49%);
    --accents-3: hsl(0, 0%, 64%);
    --accents-4: hsl(0, 1%, 81%);
    --accents-5: hsl(0, 0%, 89%);
    --accents-6: hsl(50, 21%, 95%);
    --theme-0: hsl(210, 24%, 84%);
    --theme-1: hsl(209, 28%, 39%);
    @apply overflow-x-hidden;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}

/* Remove Safari input shadow on mobile */
textarea,
input:matches([type='email'], [type='number'], [type='password'], [type='search'], [type='tel'], [type='text'], [type='url']) {
    -webkit-appearance: none;
}

html {
    height: 100%;
    box-sizing: border-box;
    touch-action: manipulation;
    font-feature-settings: 'case' 1, 'rlig' 1, 'calt' 0;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    -moz-osx-font-smoothing: grayscale;
    --webkit-text-size-adjust: none;
    text-size-adjust: none;
    scroll-behavior: smooth;
}

html,
body {
    font-family: var(--font-sans);
    text-rendering: optimizeLegibility;
    ::--webkit-font-smoothing: antialiased;
    ::--moz-osx-font-smoothing: grayscale;
    background-color: var(--reddit-0);
    color: var(--text-accents-6);
}

body {
    position: relative;
    min-height: 100%;
    margin: 0;
    scrollbar-width: none;
    scrollbar-color: var(--primary-0) var(--primary-9); /* scroll thumb and track */
}

body::-webkit-scrollbar {
    display: thin; /* Hide scrollbar for Chrome, Safari and Opera https://www.w3schools.com/howto/howto_css_hide_scrollbars.asp */
    width: 10px;
}

body::-webkit-scrollbar-track {
    background: var(--accents-7); /* color of the tracking area */
}

body::-webkit-scrollbar-thumb {
    background-color: var(
        --secondary-0
    ); /* color of the scroll thumb */
    border-radius: 0px; /* roundness of the scroll thumb */
    border: 3px var(--secondary-0); /* creates padding around scroll thumb */
}

a {
    -webkit-tap-highlight-color: hsla(0, 0%, 0%, 0);
}

.animated {
    --webkit-animation-duration: 1s;
    --animation-duration: 1s;
    -animation-duration: 1s;
    --webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}

.fadeIn {
    -webkit-animation-name: fadeIn;
    animation-name: fadeIn;
}

@-webkit-keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

chrome-bug.css

/**
 * Chrome has a bug with transitions onLoad since 2012!
 *
 * To prevent a "pop" of content, you have to disable all transitions until
 * the page is done loading.
 *
 * https://lab.laukstein.com/bug/input
 * https://twitter.com/timer150/status/1345217126680899584
 */
body.loading * {
    transition: none !important;
}

chrome-bug 类通过useEffect钩子有条件地处理,_app.tsx并在_document.tsx

_app.tsx

import '@/styles/index.css';
import '@/styles/chrome-bug.css';
import 'keen-slider/keen-slider.min.css';

import App, {
    AppContext,
    AppInitialProps,
    AppProps,
    NextWebVitalsMetric
} from 'next/app';
import { useRouter } from 'next/router';
import { ApolloProvider } from '@apollo/client';
import { useEffect, FC } from 'react';
import {
    useApollo,
    initializeApollo,
    addApolloState
} from '@/lib/apollo';
import * as gtag from '@/lib/analytics';
import { MediaContextProvider } from '@/lib/artsy-fresnel';
import { Head } from '@/components/Head';
import { GTagPageview } from '@/types/analytics';
// import { AppLayout } from '@/components/Layout';
import {
    DynamicNavQuery,
    DynamicNavQueryVariables,
    DynamicNavDocument,
    MenuNodeIdTypeEnum
} from '@/graphql/generated/graphql';

const Noop: FC = ({ children }) => <>{children}</>;

function NextApp({
    Component,
    pageProps: { ...pageProps }
}: AppProps<typeof NextApp.getInitialProps>) {
    const apolloClient = useApollo(pageProps);
    const LayoutNoop = (Component as any).LayoutNoop || Noop;
    const router = useRouter();
    useEffect(() => {
        document.body.classList?.remove('loading');
    }, []);
    useEffect(() => {
        const handleRouteChange = (url: GTagPageview) => {
            gtag.pageview(url);
        };
        router.events.on('routeChangeComplete', handleRouteChange);
        return () => {
            router.events.off('routeChangeComplete', handleRouteChange);
        };
    }, [router.events]);
    return (
        <>
            <Head />
            <ApolloProvider client={apolloClient}>
                <MediaContextProvider>
                    <LayoutNoop pageProps={pageProps}>
                        <Component {...pageProps} />
                    </LayoutNoop>
                </MediaContextProvider>
            </ApolloProvider>
        </>
    );
}

NextApp.getInitialProps = async (
    appContext: AppContext
): Promise<AppInitialProps> => {
    const pageProps = await App.getInitialProps(appContext);

    const graphqlClient = initializeApollo();
    const dynamicNav = await graphqlClient.query<
        DynamicNavQuery,
        DynamicNavQueryVariables
    >({
        query: DynamicNavDocument,
        variables: {
            idHead: 'Header',
            idTypeHead: MenuNodeIdTypeEnum.Name,
            idFoot: 'Footer',
            idTypeFoot: MenuNodeIdTypeEnum.Name
        }
    });
    return addApolloState(graphqlClient, {
        pageProps: {
            ...pageProps.pageProps,
            Header: dynamicNav.data.Header,
            Footer: dynamicNav.data.Footer
        }
    });
};

export function reportWebVitals(metric: NextWebVitalsMetric) {
    console.debug('vital: ', metric);
}

export default NextApp;

_document.tsx

import Document, {
    Head,
    Html,
    Main,
    NextScript,
    DocumentContext
} from 'next/document';
import { mediaStyles } from '@/lib/artsy-fresnel';
const GA_TRACKING_ID = 'G-RJQZB1C7TR';

class MyDocument extends Document {
    static async getInitialProps(ctx: DocumentContext) {
        const initialProps = await Document.getInitialProps(ctx);
        return { ...initialProps };
    }
    render() {
        return (
            <Html lang='en-US'>
                <Head>
                    <meta charSet='utf-8' />
                    <link
                        rel='stylesheet'
                        href='https://rsms.me/inter/inter.css'
                    />
                    <link rel='shortcut icon' href='/assets/favicon.ico' />
                    <style
                        type='text/css'
                        dangerouslySetInnerHTML={{ __html: mediaStyles }}
                    />
                    <script
                        async
                        src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
                    />
                    <script
                        dangerouslySetInnerHTML={{
                            __html: `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());

        gtag('config', '${GA_TRACKING_ID}', {
            page_path: window.location.pathname,
        });
    `
                        }}
                    />
                </Head>
                <body className='loading'>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

export default MyDocument;

为了彻底起见,这是我的package.json

{
    "name": "clean-fade",
    "version": "1.0.0",
    "main": "index.js",
    "repository": "git@gitlab.com:windy-city-devs-llc/clean-fade.git",
    "author": "Andrew Ross <andrew.simpson.ross@gmail.com>",
    "license": "MIT",
    "scripts": {
        "test": "jest",
        "test-all": "yarn lint && yarn type-check && yarn test",
        "codegen": "graphql-codegen --config codegen.yml -r dotenv/config",
        "dev": "next -p 5005",
        "prod:build": "yarn codegen && yarn build",
        "dev:debug": "cross-env NODE_OPTIONS='--inspect' next dev",
        "build": "next build",
        "analyze": "cross-env ANALYZE=true yarn build",
        "find:unused": "next-unused",
        "tsconfig:effective": "tsc --showConfig",
        "pretty:quick": "yarn pretty-quick --staged",
        "prepare": "husky install",
        "lint": "eslint . --ext ts --ext tsx --ext js",
        "format": "prettier --write .",
        "type-check": "tsc --pretty --noEmit"
    },
    "lint-staged": {
        "*.@(ts|tsx)": [
            "yarn lint",
            "yarn format"
        ]
    },
    "next-unused": {
        "alias": {
            "@/components/*": [
                "components/*"
            ],
            "@/config/*": [
                "config/*"
            ],
            "@/graphql/*": [
                "graphql/*"
            ],
            "@/lib/*": [
                "lib/*"
            ],
            "@/pages/*": [
                "pages/*"
            ],
            "@/scripts/*": [
                "scripts/*"
            ],
            "@/styles/*": [
                "styles/*"
            ],
            "@/test/*": [
                "test/*"
            ],
            "@/types/*": [
                "types/*"
            ]
        },
        "debug": true,
        "include": [
            "components",
            "lib",
            "pages"
        ],
        "exclude": [],
        "entrypoints": [
            "pages"
        ]
    },
    "dependencies": {
        "@apollo/client": "^3.3.12",
        "@artsy/fresnel": "^1.3.1",
        "@headlessui/react": "^0.3.1",
        "@reach/portal": "^0.13.2",
        "body-scroll-lock": "^3.1.5",
        "classnames": "^2.2.6",
        "date-fns": "^2.19.0",
        "graphql": "^15.5.0",
        "html-react-parser": "^1.2.4",
        "isomorphic-unfetch": "^3.1.0",
        "js-cookie": "^2.2.1",
        "keen-slider": "^5.4.0",
        "lodash.random": "^3.2.0",
        "lodash.throttle": "^4.1.1",
        "next": "^10.0.9",
        "next-seo": "^4.20.0",
        "next-themes": "^0.0.12",
        "preact": "^10.5.13",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-intersection-observer": "^8.31.0",
        "react-markdown": "^5.0.3",
        "react-merge-refs": "^1.1.0",
        "react-tsparticles": "^1.20.1",
        "remark-gfm": "^1.0.0",
        "swr": "^0.5.3",
        "tabbable": "^5.1.6"
    },
    "devDependencies": {
        "@babel/core": "^7.13.10",
        "@graphql-codegen/cli": "^1.21.3",
        "@graphql-codegen/import-types-preset": "^1.18.1",
        "@graphql-codegen/introspection": "^1.18.1",
        "@graphql-codegen/near-operation-file-preset": "^1.17.13",
        "@graphql-codegen/schema-ast": "^1.18.1",
        "@graphql-codegen/typescript": "^1.21.1",
        "@graphql-codegen/typescript-operations": "^1.17.15",
        "@graphql-codegen/typescript-react-apollo": "2.1.1",
        "@next/bundle-analyzer": "^10.0.9",
        "@tailwindcss/aspect-ratio": "^0.2.0",
        "@tailwindcss/forms": "^0.2.1",
        "@tailwindcss/typography": "^0.4.0",
        "@testing-library/dom": "^7.30.0",
        "@testing-library/jest-dom": "^5.11.9",
        "@testing-library/react": "^11.2.5",
        "@testing-library/user-event": "^12.8.3",
        "@types/body-scroll-lock": "^2.6.1",
        "@types/classnames": "^2.2.11",
        "@types/gtag.js": "^0.0.4",
        "@types/jest": "^26.0.20",
        "@types/js-cookie": "^2.2.6",
        "@types/lodash.random": "^3.2.6",
        "@types/lodash.throttle": "^4.1.6",
        "@types/node": "^14.14.35",
        "@types/react": "^17.0.3",
        "@types/react-dom": "^17.0.2",
        "@types/react-test-renderer": "^17.0.1",
        "@types/tabbable": "^3.1.0",
        "@typescript-eslint/eslint-plugin": "^4.18.0",
        "@typescript-eslint/parser": "^4.18.0",
        "autoprefixer": "^10.2.5",
        "babel-jest": "^26.6.3",
        "cross-env": "^7.0.3",
        "dotenv": "^8.2.0",
        "dotenv-cli": "^4.0.0",
        "eslint": "^7.22.0",
        "eslint-config-prettier": "^8.1.0",
        "eslint-plugin-react": "^7.22.0",
        "globby": "^11.0.2",
        "husky": "^5.1.3",
        "identity-obj-proxy": "^3.0.0",
        "jest": "^26.6.3",
        "jest-watch-typeahead": "^0.6.1",
        "lint-staged": "^10.5.4",
        "next-page-tester": "^0.24.0",
        "next-unused": "^0.0.3",
        "postcss": "^8.2.8",
        "postcss-flexbugs-fixes": "^5.0.2",
        "postcss-import": "^14.0.0",
        "postcss-preset-env": "^6.7.0",
        "postinstall-postinstall": "^2.1.0",
        "prettier": "^2.2.1",
        "pretty-quick": "^3.1.0",
        "react-test-renderer": "^17.0.1",
        "stylelint": "^13.12.0",
        "stylelint-config-recommended": "^4.0.0",
        "tailwindcss": "^2.0.3",
        "tailwindcss-line-clamp": "^1.0.5",
        "ts-jest": "^26.5.3",
        "typescript": "^4.2.3",
        "yaml-loader": "^0.6.0"
    }
}

于 2021-03-25T10:34:43.033 回答