UNPKG

next-video

Version:

A React component for adding video to your Next.js application. It extends both the video element and your Next app with features for automatic video optimization.

118 lines (117 loc) 4.57 kB
import symlinkDir from "symlink-dir"; import { join, dirname } from "node:path"; import fs from "node:fs"; import { env } from "node:process"; import { fileURLToPath } from "node:url"; import logger from "./utils/logger.js"; import { getPackageVersion } from "./utils/utils.js"; import { setVideoConfig } from "./config.js"; let hasWarned = false; function withNextVideo(nextConfig, videoConfig) { const videoConfigComplete = setVideoConfig(videoConfig); const { path, folder, provider } = videoConfigComplete; env["NEXT_PUBLIC_VIDEO_OPTS"] = JSON.stringify({ path, folder, provider }); if (process.argv[2] === "dev") { env["NEXT_PUBLIC_DEV_VIDEO_OPTS"] = JSON.stringify({ path, folder, provider }); } if (typeof nextConfig === "function") { return async (...args) => { const nextConfigResult = await nextConfig(...args); return withNextVideo(nextConfigResult, videoConfig); }; } if (process.argv[2] === "dev") { const VIDEOS_PATH = join(process.cwd(), folder); const TMP_PUBLIC_VIDEOS_PATH = join(process.cwd(), "public", `_next-video`); symlinkDir(VIDEOS_PATH, TMP_PUBLIC_VIDEOS_PATH); process.on("exit", async () => { fs.unlinkSync(TMP_PUBLIC_VIDEOS_PATH); }); } const nextVersion = getPackageVersion("next"); if (nextVersion && nextVersion.startsWith("15.")) { nextConfig.outputFileTracingIncludes = { ...nextConfig.outputFileTracingIncludes, [path]: [`./${folder}/**/*.json`] }; } else { const experimental = { ...nextConfig.experimental }; experimental.outputFileTracingIncludes = { ...experimental.outputFileTracingIncludes, [path]: [`./${folder}/**/*.json`] }; nextConfig.experimental = experimental; } if (!hasWarned && process.env.TURBOPACK && !process.env.NEXT_VIDEO_SUPPRESS_TURBOPACK_WARNING) { hasWarned = true; const nextVideoVersion = getPackageVersion("next-video"); logger.space(logger.label(`\u25B6\uFE0E next-video ${nextVideoVersion} `)); logger.warning( `You are using next-video with \`next ${true ? "dev" : "build"} --turbo\`. next-video doesn't yet fully support Turbopack. We recommend temporarily removing the \`--turbo\` flag for use with next-video. ` ); logger.warning( `Follow this issue for progress on next-video + Turbopack: https://github.com/muxinc/next-video/issues/266. (You can suppress this warning by setting NEXT_VIDEO_SUPPRESS_TURBOPACK_WARNING=1 as environment variable) ` ); } return Object.assign({}, nextConfig, { webpack(config, options) { if (!options.defaultLoaders) { throw new Error( "This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade" ); } config.infrastructureLogging = { ...config.infrastructureLogging, // Silence warning about dynamic import of next.config file. // > [webpack.cache.PackFileCacheStrategy/webpack.FileSystemInfo] Parsing of /next-video/dist/config.js for build dependencies failed at 'import(fileUrl. // > Build dependencies behind this expression are ignored and might cause incorrect cache invalidation. level: "error" }; config.experiments.buildHttp = { allowedUris: [ /https?:\/\/.*\.(mp4|webm|mkv|ogg|ogv|wmv|avi|mov|flv|m4v|3gp)\??(?:&?[^=&]*=[^=&]*)*$/, ...config.experiments.buildHttp?.allowedUris ?? [] ], ...config.experiments.buildHttp || {}, // Disable cache to prevent Webpack from downloading the remote sources. cacheLocation: false }; const scriptDir = typeof __dirname === "string" ? __dirname : dirname(fileURLToPath(import.meta.url)); config.module.rules.push( { test: /\.(mp4|webm|mkv|ogg|ogv|wmv|avi|mov|flv|m4v|3gp)\??(?:&?[^=&]*=[^=&]*)*$/, use: [ { loader: join(scriptDir, "webpack/video-json-loader.js") }, { loader: join(scriptDir, "webpack/video-raw-loader.js") } ], type: "json" }, { test: /\.(mp4|webm|mkv|ogg|ogv|wmv|avi|mov|flv|m4v|3gp)\.json\??(?:&?[^=&]*=[^=&]*)*$/, use: [ { loader: join(scriptDir, "webpack/video-json-loader.js") } ], type: "json" } ); if (typeof nextConfig.webpack === "function") { return nextConfig.webpack(config, options); } return config; } }); } export { withNextVideo };