Skip to content

Instantly share code, notes, and snippets.

@glemiere
Last active June 28, 2018 17:30
Show Gist options
  • Save glemiere/ef9c4e691c09c1897d26d4d999210b4b to your computer and use it in GitHub Desktop.
Save glemiere/ef9c4e691c09c1897d26d4d999210b4b to your computer and use it in GitHub Desktop.
/**********
next.config.js
---------------
NextJS custom webpack configuration file.
Preprocessing of images and styling with environment conditions.
---------------
Requires a NextJS project. Get started at :
https://github.com/glemiere/nextjs-starter
**********/
// Dependencies
const path = require('path');
const glob = require('glob');
// See : https://github.com/glemiere/nextjs-starter/tree/master/config
const config = require('./config');
// Function to inject a plugin in webpack configuration.
const pushPlugins = (nextConfig = {}, plugins = {}) => {
return Object.assign({}, nextConfig, {
webpack(config, options) {
if (!options.defaultLoaders) {
throw new Error(
'You need to upgrade to NextJS 5.0.0 or above.'
)
}
config.plugins.push(plugins);
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options)
}
return config
}
});
};
// Function to inject module rules in webpack configuration.
const pushRules = (nextConfig = {}, rules = {}) => {
return Object.assign({}, nextConfig, {
webpack(config, options) {
if (!options.defaultLoaders) {
throw new Error(
'You need to upgrade to NextJS 5.0.0 or above.'
)
}
config.module.rules.push(rules);
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options)
}
return config
}
});
};
// Pictures rules
const withImages = (nextConfig = {}) => {
var loaders = new Array();
if (process.env.NODE_ENV == 'production') {
loaders.push({
loader: "image-trace-loader",
options: {
color:'#27AE9D',
}
});
loaders.push({
loader: 'sqip-loader',
options: {
numberOfPrimitives: 20
}
});
loaders.push({
loader: "url-loader",
options: {
limit: 1 * 1024,
noquotes: true,
fallback: "file-loader",
publicPath: "/_next/static/images/",
outputPath: "static/images/",
name: "[hash].[ext]"
}
});
loaders.push({
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: true
},
webp: {
enabled: false
}
}
});
}
if (process.env.NODE_ENV == 'development') {
loaders.push({
loader: "url-loader",
options: {
limit: 10 * 1024,
noquotes: true,
fallback: "file-loader",
useRelativePath: true,
name: "[name].[ext]"
}
});
}
return pushRules(nextConfig, {
test: /\.(jpe?g|png|svg|gif)$/,
use: loaders
});
};
// Styling rules
const withStyle = (nextConfig = {}) => {
let cssRule = {
test: /\.css$/,
use: ['babel-loader', 'raw-loader', 'postcss-loader']
};
let scssRule = {
test: /\.(css|scss)/,
loader: 'emit-file-loader',
options: {
name: '[path][name].[ext]'
}
}
let sassRule = {
test: /\.s(a|c)ss$/,
use: ['babel-loader', 'raw-loader', '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), [])
}
}
]
}
nextConfig = pushRules(nextConfig, cssRule);
nextConfig = pushRules(nextConfig, scssRule);
nextConfig = pushRules(nextConfig, sassRule);
return nextConfig;
};
// Import rules following webpack configuration instruction file (config.webpack)
// See : https://github.com/glemiere/nextjs-starter/blob/master/config/webpack.js
const loadWith = (options) => {
let nextConfig = {
webpack(config, options) {
return config
}
}
switch(true) {
case options.style: nextConfig = withStyle(nextConfig);
case options.images: nextConfig = withImages(nextConfig); break;
}
return nextConfig;
};
// Exports final configuration
module.exports = loadWith(config.webpack);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment