How to use with Next.js webpack config?
I would like to list/graph dependencies for a Next.js project. Next.js comes with Webpack and Babel. You can also extend their configurations.
Webpack is extended with a next.config.js file and Babel with a .babelrc file.
Here is my next.config.js with irrelevant bits removed:
const withCSS = require('@zeit/next-css');
const webpack = require('webpack');
module.exports = withCSS({
webpack: function(config) {
// Load static files
config.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
name: '[name].[ext]',
},
},
});
return config;
},
});
Here's the relevant parts of my .babelrc:
{
"presets": ["next/babel"],
"plugins": [
[
"module-resolver",
{
"root": ["./"],
"alias": {
"api": "./api",
"components": "./components",
"elements": "./components/elements",
"layout": "./components/layout",
}
}
]
]
}
Problem
There is no central "app.js" but rather pages (located in pages/). Running madge on a page results in lots of warnings for ignored files or directories. Here's a debug for one of my pages that has dependencies in components/ (with filepaths removed):
- Finding files madge using src paths [ 'filepath\\pages\\login.js' ] +7ms
madge using config { baseDir: null, excludeRegExp: false, fileExtensions: [ 'js' ], includeNpm: false, requireConfig: null, webpackConfig: null, tsConfig: null, rankdir: 'LR', layout: 'dot', fontName: 'Arial', fontSize: '14px', backgroundColor: '#111111', nodeColor: '#c6c5fe', nodeShape: 'box', nodeStyle: 'rounded', noDependencyColor: '#cfffac', cyclicNodeColor: '#ff6c60', edgeColor: '#757575', graphVizOptions: false, graphVizPath: false, dependencyFilter: [Function], debug: true, version: [Function], color: true, spinner: true } +2ms
madge using base directory filepath/pages +2ms
tree given filename: filepath\pages\login.js +0ms
tree resolved filename: filepath\pages\login.js +0ms
tree visited: {} +1ms
tree traversing filepath\pages\login.js +0ms
precinct paperwork: invoking precinct +0ms
precinct options given: { includeCore: false } +0ms
precinct we assume this is JS +0ms
precinct parsed the file content into an ast +27ms
precinct module type: es6 +2ms
tree extracted 8 dependencies: [ 'react',
'classnames',
'next/head',
'formik',
'style/main.css',
'api/auth',
'components',
'api/validations' ] +34ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +1ms
cabinet found a resolver for .js +0ms
cabinet reusing the given ast +1ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +6ms
cabinet resolved path: filepath\node_modules\react\index.js +4ms
cabinet resolved path for react: filepath\node_modules\react\index.js +1ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +0ms
cabinet reusing the given ast +1ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +0ms
cabinet resolved path: filepath\node_modules\classnames\index.js +9ms
cabinet resolved path for classnames: filepath\node_modules\classnames\index.js +0ms
cabinet Given filename: filepath\pages\login.js +1ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +0ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +1ms
cabinet resolved path: filepath\node_modules\next\head.js +2ms
cabinet resolved path for next/head: filepath\node_modules\next\head.js +0ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +1ms
cabinet found a resolver for .js +0ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +0ms
cabinet resolved path: filepath\node_modules\formik\dist\index.js +5ms
cabinet resolved path for formik: filepath\node_modules\formik\dist\index.js +2ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +1ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +1ms
cabinet could not resolve style/main.css +5ms
cabinet resolved path for style/main.css: +0ms
tree skipping an empty filepath resolution for partial: style/main.css +43ms
cabinet Given filename: filepath\pages\login.js +1ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +1ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +0ms
cabinet could not resolve api/auth +5ms
cabinet resolved path for api/auth: +2ms
tree skipping an empty filepath resolution for partial: api/auth +8ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +1ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +0ms
cabinet could not resolve components +5ms
cabinet resolved path for components: +0ms
tree skipping an empty filepath resolution for partial: components +6ms
cabinet Given filename: filepath\pages\login.js +0ms
cabinet which has the extension: .js +0ms
cabinet found a resolver for .js +1ms
cabinet reusing the given ast +0ms
cabinet using commonjs resolver for es6 +0ms
cabinet adding filepath\pages\node_modules to the require resolution paths +1ms
cabinet could not resolve api/validations +6ms
cabinet resolved path for api/validations: +1ms
tree skipping an empty filepath resolution for partial: api/validations +10ms
tree cabinet-resolved all dependencies: [ 'filepath\\node_modules\\react\\index.js',
'filepath\\node_modules\\classnames\\index.js',
'filepath\\node_modules\\next\\head.js',
'filepath\\node_modules\\formik\\dist\\index.js' ] +0ms
tree using filter function to filter out dependencies +0ms
tree unfiltered number of dependencies: 4 +1ms
\ ./login.js tree filtered number of dependencies: 0 +3ms
tree traversal complete {} +0ms
tree deduped list of nonExistent partials: [ 'style/main.css', 'api/auth', 'components', 'api/validations' ] +0ms
tree object form of results requested +0ms
tree final tree { 'filepath\\pages\\login.js': {} } +1ms
Processed 1 file (519ms) (4 warnings)
login.js
✖ Skipped 4 files
style/main.css
api/auth
components
api/validations
I think the relevant part is "cabinet could not resolve components". Why does this happen and how can I use Madge for Next.js pages/apps?
Were you able to solve this? I haven't tried what I'm about to suggest but..
There seems to be a config option in madge called webpackConfig. This should point to a webpack config. I would try extracting the webpack config that is in the next.config.js into its own file. And then import that config in next.config.js and also point to that config in madge so you can use madge to detect circular references
Were you able to solve this?
I'm no longer working on a Next.js project and, no, I never solved this. I suspect you're right about using webpackConfig with the next.config.js, though.
I know this is an old thread, but in case anyone else comes across this, doing the suggestions from the previous comments seems to work as expected for me:
next.config.js:
const nextConfig = {
webpack: config => {
madge("src", {
tsConfig: "./tsconfig.json",
webpackConfig: config,
fileExtensions: ["js", "tsx", "ts"],
}).then(res => console.log(res.circular()));
return config;
}
}