Last active
June 28, 2018 17:30
-
-
Save glemiere/ef9c4e691c09c1897d26d4d999210b4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********** | |
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