@moxy/next-common-files

Next.js plugins that configure webpack with loaders for common files.


Keywords
next, nextjs, loader, plugin, svg, images, raster, audio, video, fonts, config
License
MIT
Install
npm install @moxy/next-common-files@1.4.2

Documentation

next-common-files

NPM version Downloads Build Status Coverage Status Dependency status Dev Dependency status

Next.js plugins that configure webpack with loaders for common files.

Projects developed with Next.js have to manually insert rules in the configuration file for handling file types that are potentially very common across multiple projects.

These plugins quicken the initial setup of a project by removing that effort from the process, demanding less time from the developer.

Installation

$ npm install --save @moxy/next-common-files

Usage

For single usage:

// next.config.js
const { withRasterImages } = require('@moxy/next-common-files');

module.exports = withRasterImages({
    /* options */
});

For using multiple plugins, you can use next-compose-plugins. The examples in this README will follow the next-compose-plugins structure.

// next.config.js
const { withRasterImages, withPlayback, withFonts, withSVG, with3D } = require('@moxy/next-common-files');
const withPlugins = require('next-compose-plugins');

module.exports = withPlugins([
        withRasterImages(),
        withPlayback(),
        withFonts(),
        withSVG(),
        with3D(),
        withJSON5(),
    ]);

Loaders

All plugins default to using url-loader with the limit option set to 0, which forces a fallback to file-loader. This means that, in practice, developers must opt in for url-loader's base64 translation. Developers can choose to set a higher limit in conjunction with other rule options to accommodate the structure of their own project.

With the SVG plugin, svgo-loader is added to optimize the SVG files. The SVG plugin can also give an inline output, toggled using an inline option. When true, this plugin also uses svg-css-modules-loader, which uniquifies CSS classes in the SVG file.

Options

All plugins can be passed an options object that will spread to the webpack rule. With one exception, explored further below in the SVG section, you can also expect the object to spread to the url-loader configuration. You can refer to the webpack rule documentation and the url-loader documentation for more details on available options.

Below you can find some common, general examples on how to use the plugins. Please refer to the section specific to each plugin further below for detailed information about each and specifics on how to use them.

Excluding a directory:

// Exclude /images/ directory
withRasterImages({
    exclude: /images\/.*$/,
}),

Excluding a file by suffix:

// Exclude files with '.data-url' suffix
withRasterImages({
    exclude: /\.data-url\./,
}),

Setting the url-loader limit:

// Set higher limit
withRasterImages({
    options: {
        limit: 300000,
    },
}),

Using limit and exclude/include to delineate between data URL items and standard items:

// Exclude files with '.data-url' suffix
withRasterImages({
     exclude: /\.data-url\./,
}),

// Set a higher limit for files with '.data-url' suffix
withRasterImages({
    include: /\.data-url\./,
    options: {
        limit: 300000,
    },
}),

Using all plugins with options accommodated to an example project structure:

withRasterImages({
    exclude: /favicons\/.*$/,
}),
withPlayback(),
withFonts({
    options: {
        limit: 50000,
    },
}),
withSVG({
    exclude: /\.inline\./,
}),
withSVG({
    include: /\.inline\./,
    inline: true,
}),

If you want to set a top limit that would cover all file sizes, you can set the limit as Infinity. Keep in mind, using data-url or inline content will increase the size of your bundle, and defaulting to Infinity can lead to an unchecked increase in bundle size.

withRasterImages({
    options: {
        limit: Infinity, // All files will pass
    },
}),

API

raster-images

This plugin is meant to handle raster images, and tests the file types .png, .jpg, jpeg, .gif, .webp and.ico.

⚠️ This plugin disables image static imports in your next.config.js file. Check https://nextjs.org/docs/basic-features/image-optimization#disable-static-imports for more information.

playback

This plugin is meant to handle video and audio files, and tests the file types .mp3, .flac, .wav, .aac, .ogg, .oga, .mp4, .m4a, .webm and .ogv.

fonts

This plugin is meant to handle font files, and tests the file types .eot, .ttf, .woff, .woff2 and .oft.

svg

This plugin is meant to handle SVG files, and tests the file type .svg.

This plugin adds the svgo-loader to optimize the SVG files it loads.

Though it defaults to working like the previous plugins, this plugin can also output inline content. You can toggle the output by sending an inline option, which is set to false by default. Use this if you want to be returned a string with the content of the SVG file. When false the plugin will behave like the others, using url-loader together with svgo-loader. When true, the plugin will use a different set of loaders, including svg-css-modules-loader, which uniquifies the CSS classes in the file.

The available options also change in accordance with the inline value. With the inline option set to false, it will behave like the other plugins. With the inline option set to true, the options object will safely spread only to the rule, and passing the use option will override the default loaders entirely.

// If false or not sent, options can be sent like other plugins
withSVG({
    options: {
        limit: 20000,  // Will be safely passed to url-loader
    },
}),

// If sent true, 'use' value will override default loaders entirely
withSVG({
    include: /\.inline\./,  // Will be safely passed to rule
    inline: true,
    use: [{
        loader: 'url-loader',  // Only 'url-loader' will be used
    }],
}),

The following example shows how you can use the inline option in your project:

// Include SVGs with '.inline' suffix
withSVG({
    include: /\.inline\./,
    inline: true,
}),

// Exclude SVGs with '.inline' suffix
withSVG({
    exclude: /\.inline\./,
}),

Keep in mind, when you opt in for the inline output, the CSS classes in your SVG will be uniquified, and you must be careful when selecting them. For example, using an attribute selector, as shown in the following snippet:

/* Selecting an svg file with the original filename 'header-svg-inline.svg' */
[class^=header-svg-inline] {
    /* ... */
}

3D

This plugin is meant to handle 3d files, and tests the file types .obj, .mtl, .fnt, .gltf and .glb.

It's not possible to know the size of most of these files when you download them, which is useful to show some kind of progress bar. The server delivers them compressed, using gzip or brotli, meaning the response does not contain the Content-Length header. To circumvent this problem, we use an internal loader that returns the filesize as well as its url.

An example of the returned object for example.glb would be:

import example from './example.glb'

{
  src: '/somewhere/example.glb', // URL of the file
  size: 1024,                    // File size in bytes
}

JSON5

This plugin is meant to handle JSON5 files (.json5).

Tests

Any parameter passed to the test command is passed down to Jest.

$ npm t
$ npm t -- --watch  # To run watch mode

License

Released under the MIT License.