Nextjs Build 后,我想重命名块文件

问题描述 投票:0回答:3

在Nextjs Build之后,我想重命名块文件并使用新数据而不是缓存数据,但manifest.json引用了现有的块文件。 我该如何解决这个问题?

我更改了 next.config.js 选项中的generateBuildId,但它无法正常工作,即使我关闭了缓存,它也会加载现有的块文件。

caching next.js webview chunks
3个回答
0
投票

不是最干净的解决方案,但这对我有用。

/* the trick is to build unique build ID on every build and add it to static files on build time.
 * This way the name and URL of static files will change on every build.
 */

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');

// Used to set folders as alias to directly use in nextjs
const nextConfiguration = ({
    webpack: (config, { dev }) => {
        const newConfig = config;

        if (!dev && newConfig.output.filename.startsWith('static')) {
            newConfig.output.filename = newConfig.output.filename.replace('[name]', `[name]-${ Math.floor(Date.now() / 1000)}`);
            newConfig.output.chunkFilename = newConfig.output.chunkFilename.replace('[name]', `[name]-${ Math.floor(Date.now() / 1000)}`);
        }

        return newConfig;
    },
});

module.exports = nextConfiguration;

每次编译项目时,代码都会向创建的文件的名称添加时间戳。这样,当更改部署到实时站点时,浏览器会收到“新”文件并丢弃缓存的文件。

来源:https://gist.github.com/amit08255/a4eb51d5302e71ba3ecb267bc2a6a5e5


0
投票

将其添加到您的 next.config.js 文件中。 “generateBuildId”函数已配置为通过创建带有日期的唯一构建 ID 来确保缓存清除。此外,webpack 配置挂钩用于在生产构建期间更改输出文件的名称,向块文件名添加日期。使用时间戳有助于避免缓存问题,确保您获得文件的最新版本。

const path = require('path');

module.exports = {
  // Function for cache-busting
  generateBuildId: async () => {
    // Create a unique build ID with a combination of timestamp and a random string
    const timestamp = new Date().getTime(); // Get the current timestamp
    const randomString = Math.random().toString(36).substring(2, 8); // Generate a random string
    const buildId = `${timestamp}-${randomString}`; // Combine timestamp and random string
    
    return buildId;
  },

  // Webpack configuration
  webpack: (config, { dev }) => {
    // Add a timestamp to filenames during production build for cache-busting
    if (!dev && config.output.filename.startsWith('static')) {
      const timestamp = new Date().getTime(); // Get the current timestamp
      // Modify output filenames to include the timestamp
      config.output.filename = config.output.filename.replace('[name]', `[name]-${timestamp}`);
      config.output.chunkFilename = config.output.chunkFilename.replace('[name]', `[name]-${timestamp}`);
    }

    // Add other webpack configurations here

    return config;
  },

  // Other configurations...
};

0
投票

创建一个自定义 Webpack 插件,不仅可以重命名块文件,还可以使用新文件名更新 manifest.json。

import path from 'path';
import fs from 'fs';

class RenameChunksAndUpdateManifestPlugin {
  apply(compiler) {
    compiler.hooks.afterEmit.tap('RenameChunksAndUpdateManifestPlugin', (compilation) => {
      const outputPath = compilation.outputOptions.path;
      const chunkFiles = fs.readdirSync(path.join(outputPath, 'static', 'chunks'));
      const manifestPath = path.join(outputPath, 'static', 'chunks', 'manifest.json');

      let manifest = {};

      // Read and parse the existing manifest.json
      if (fs.existsSync(manifestPath)) {
        manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
      }

      // Generate a unique hash based on the current timestamp
      const hash = Date.now();

      // Rename files and update manifest.json
      chunkFiles.forEach((file) => {
        const ext = path.extname(file); // Get file extension
        const oldFilePath = path.join(outputPath, 'static', 'chunks', file);
        const newFilename = `${path.basename(file, ext)}-${hash}${ext}`;
        const newFilePath = path.join(outputPath, 'static', 'chunks', newFilename);

        // Rename the chunk file
        fs.renameSync(oldFilePath, newFilePath);

        // Update manifest references
        for (let key in manifest) {
          if (manifest[key] === `static/chunks/${file}`) {
            manifest[key] = `static/chunks/${newFilename}`;
          }
        }
      });

      // Write the updated manifest.json back to the filesystem
      fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));

      console.log('Chunks renamed and manifest.json updated.');
    });
  }
}

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.plugins.push(new RenameChunksAndUpdateManifestPlugin());
    }
    return config;
  }
};

export default nextConfig;

© www.soinside.com 2019 - 2024. All rights reserved.