首页 > 解决方案 > 使用 Webpack 在开发中运行使用 `fs` 和 `sharp` 的 Next.js 脚本?

问题描述

我正在尝试创建一个简单的GIFPlayer,如果有人点击播放按钮则显示 GIF,否则显示 PNG,如:

<img className="w-full h-full" src={isPlaying ? gifPath : imgPath} alt={pic.alt} />

我只有 GIF 文件,所以我使用 Node.jssharp模块创建 PNG 文件。

脚本/gif-to-png.js

const fs = require('fs')
const path = require('path')
const sharp = require('sharp')
const fg = require('fast-glob')

const ROOT_PATH = process.cwd()
const POSTS_PATH = path.join(ROOT_PATH, 'src/_posts')

function* walkSync(dir) {
    const files = fs.readdirSync(dir, { withFileTypes: true })
    for (let i = 0; i < files.length; i++) {
        if (files[i].isDirectory()) {
            yield* walkSync(path.join(dir, files[i].name))
        } else {
            yield path.join(dir, files[i].name)
        }
    }
}

const gifToPng = async () => {
    try {
        for (let [i, file] of [...walkSync(POSTS_PATH)].entries()) {
            const extname = path.extname(file)
            if (extname === '.gif') {
                const dirname = path.dirname(file)
                const png = path.resolve(dirname, path.basename(file).replace('.gif', '.png'))
                await sharp(file).png().toFile(png)
            }
        }
    } catch (e) {
        console.error('Error thrown:', e)
    }
}

gifToPng()

next.config.js在开发中运行此脚本,例如:


module.exports = {
    webpack: (config, options) => {

        if (!options.dev && options.isServer) {
            .
            .
            .
        } else {
            const originalEntry = config.entry

            config.entry = async () => {
                const entries = { ...(await originalEntry()) }
                entries['./scripts/gif-to-png'] = './scripts/gif-to-png.js'
                return entries
            }
        }

        return config
    },
}

但是,它的抛出错误说:

找不到模块:无法解析“fs”

我在开发而不是生产中需要这个脚本的原因是我还需要查看 PNG 文件development否则,如果它仅在生产中运行,我将无法看到它。

我该如何解决这个问题?

标签: javascriptnode.jswebpacknext.js

解决方案


我在这里找到了答案。

以下内容告诉webpack不要尝试fs在客户端构建上使用(因为这将失败)。

if (!options.isServer) {
  config.resolve.fallback.fs = false
}
return config

webpack.config.js

module.exports = {
    webpack: (config, options) => {

            if (!options.dev && options.isServer) {
                    .
                    .
                    .
            } else {
                    const originalEntry = config.entry

                    config.entry = async () => {
                            const entries = { ...(await originalEntry()) }
                            entries['./scripts/gif-to-png'] = './scripts/gif-to-png.js'
                            return entries
                    }
            }

            
            if (!options.isServer) {
                config.resolve.fallback.fs = false
            }

            return config
    },
}

推荐阅读