javascript - Alla NextJS-sidor har nästan samma storlek på JS-bunt


Så, jag har arbetat med NextJS ett tag nu och jag har aldrig riktigt tittat på byggmappen eller informationen som visas i konsolen när bygget lyckas, men jag märkte något konstigt den gången jag faktiskt tittade på det.

Jag har använt TypeScript och skrev en liten Babel-konfiguration med TS:s konfiguration för att kunna använda absoluta sökvägar. Så sättet jag importerar komponenter på är genom att ha en absolut sökväg ~/components som är en alias för ./src/components. Alla importer i hela appen använder komponenter som importeras från ~/components och det finns även andra absoluta sökvägar där. Så här är vad jag såg när jag byggde min app

Lägg märke till hur varje enskild sida nästan är av samma storlek? Även om- och 404-sidorna är JÄTTESTORA. Så min gissning var att import av moduler med absoluta importer är vad som orsakar problemet och på grund av det länkar varje sida till en JS-fil som innehåller hela appens kod. Jag är inte helt säker och jag verkar inte kunna hitta några resurser online som kan hjälpa mig att optimera dessa sidor. Ärligt talat vet jag inte ens vilken del av appen som behöver konfigureras. Om det är webpack eller babel, har jag ingen aning. Så jag hoppades få lite hjälp med detta och om det finns någon ytterligare konfiguration som jag måste lägga till så att varje sida bara använder så mycket JavaScript som den behöver.

Här är mina TypeScript- och Babel-konfigurationer:

TypeScript

{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable", "esnext"],
    "baseUrl": "./src",
    "paths": {
      "~/components": ["./components"],
      "~/styles": ["./styles"],
      "~/assets": ["./assets"],
      "~/types": ["./types"],
      "~/pages": ["./pages"],
      "~/utils": ["./utils"],
      "~/context": ["./context"],
      "~/data": ["./data"],
      "~/services": ["./services"]
    },
    "allowJs": false,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "target": "ESNext",
    "jsx": "preserve",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitAny": true
  },
  "exclude": ["node_modules"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

Babel

{
  "presets": ["next/babel"],
  "plugins": [
    ["styled-components", { "ssr": true }],
    [
      "module-resolver",
      {
        "alias": {
          "~/components": "./src/components",
          "~/styles": "./src/styles",
          "~/types": "./src/types",
          "~/pages": "./src/pages",
          "~/assets": "./src/assets",
          "~/utils": "./src/utils",
          "~/context": "./src/context",
          "~/data": "./src/data",
          "~/services": "./src/services"
        }
      }
    ],
    ["import", {
      "libraryName": "antd",
      "style": true
    }]
  ]
}

Svar #1

Så här är vad jag har kunnat ta reda på efter att ha gjort lite forskning. När du importerar saker från en fil som exporterar en massa React-komponenter är din modulbuntare inte tillräckligt intelligent (än) för att lista ut vilka komponenter du kommer att använda, så den inkluderar alla som standard och därför får du en massiv bunt.

Så oavsett om du använder komponenterna eller inte, kommer de alla fortfarande att ingå i ett stort paket. Nextjs gör koddelning som standard med Webpack, men eftersom varje enskild komponent kommer från samma sökväg, vilket i mitt fall var ~/components, kunde inte Next (eller Webpack) dela upp dem, så de inkluderades alla i ett paket som lades till på varje sida oavsett om sidan importerade en komponent eller 100 från den sökvägen.

Så det är anledningen till att jag såg enorma paketstorlekar för varje sida. Jag hade nästan 1000 komponenter som bodde i ~/components och jag hade en indexfil i den katalogen som exporterade alla dem. På detta sätt kunde jag enkelt göra

import { Component101, Component204 } from '~/components'

Men paketstorleken var MASSIV. Så för att lösa detta lade jag till Tree Shaking i min Webpack-konfiguration. Termen kommer ursprungligen från Rollup, som är en annan populär modulbundlare som Webpack. Om du använder Webpack kan mer information om Tree Shaking hittas här

Med Tree Shaking kommer alla koddelar som inte importeras någonstans att tas bort och inte inkluderas i bundeln, så du får mindre bundlar. Men håll ett öga på eventuella sidoeffekter. Här är hur min bundelstorlek för alla sidor ser ut efter att ha lagt till Tree Shaking:

Om du inte vill använda Tree Shaking, skulle ett annat sätt vara att bara använda relativa importer men jag är inte säker på om det skulle vara den rekommenderade metoden för storskaliga appar.

Relaterade artiklar