使用 NextJS 时如何将多个 JS 文件组合成一个包?

How to combine multiple JS files into a single bundle while using NextJS?

我正在使用 NextJS 构建一个 SSR 网络应用程序,目前只有两个虚拟页面,index 和 about。该站点加载正常,除了 NextJS 抛出一堆 JS 文件:

  1. https://www.schandillia.com/_next/341c66db-91d8-47da-97af/page/index.js
  2. https://www.schandillia.com/_next/341c66db-91d8-47da-97af/page/about.js

  3. https://www.schandillia.com/_next/341c66db-91d8-47da-97af/page/_app.js

  4. https://www.schandillia.com/_next/341c66db-91d8-47da-97af/page/_error.js

  5. https://www.schandillia.com/_next/static/commons/main-975e462d96245579782f.js

由于这些是在编译时创建并注入到 DOM 中的,因此在页面加载期间会导致多次往返,我很想避免这种情况。有什么方法可以在编译期间将它们全部连接成一个 JS 负载,然后使用某种 Webpack 中间件将连接的包注入 DOM 吗?我的 next.config.js 目前看起来像这样:

const path = require('path');
const glob = require('glob');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpack = require('webpack');
require('dotenv').config();

module.exports = {
  distDir: '.build',
  webpack: (config) => {
    config.module.rules.push(
      {
        test: /\.(css|scss)$/,
        loader: 'emit-file-loader',
        options: {
          name: path.join('dist', '[path][name].[ext]'),
        },
      },
      {
        test: /\.(css|sass|scss)$/,
        use: ExtractTextPlugin.extract([
          {
            loader: 'css-loader',
            options: {
              sourceMap: false,
              minimize: true,
            },
          },
          'postcss-loader',
          {
            loader: 'sass-loader',
            options: {
              includePaths: ['styles', 'node_modules']
                .map(d => path.join(__dirname, d))
                .map(g => glob.sync(g))
                .reduce((a, c) => a.concat(c), []),
            },
          },
        ]),
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url-loader?limit=10000&mimetype=application/font-woff&outputPath=static/',
      },
      {
        test: /\.(svg|ttf|eot)$/i,
        loader: 'file-loader?outputPath=static/',
        options: {
          name: '[path][name].[ext]',
        }
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        loaders: [
          'file-loader?outputPath=static/',
          'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false',
        ],
      },
    );
    config.plugins.push(
      new ExtractTextPlugin({
        filename: path.join('static', `${process.env.CSS}.min.css`),
      }),
      new webpack.DefinePlugin({
        'process.env.CSS': JSON.stringify(process.env.CSS),
        'process.env.NAVBAR_LOGO': JSON.stringify(process.env.NAVBAR_LOGO),
      }),
    );
    return config;
  },
};

有什么建议吗?

您的索引和关于页面已加载,因为您正在预取 link。

    <Link prefetch href="/">
      <a>Home</a>
    </Link>
    <Link prefetch href="/about">
      <a>About</a>
    </Link>

当你在 NextJS 中预取 Link 时,你所做的是告诉浏览器在用户点击它之前获取 link 后面页面的 JS 代码。如果你不想要这种行为,请不要设置 prefetch 属性。

    <Link href="/">
      <a>Home</a>
    </Link>
    <Link href="/about">
      <a>About</a>
    </Link>

其他包正是 NextJS 的工作方式,据我所知它是硬编码的 (source),但我可能是错的。