Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending eslint-plugin-svelte/recommended throws a Converting circular structure to JSON error #773

Open
GeoffreyBooth opened this issue Jan 7, 2025 · 6 comments

Comments

@GeoffreyBooth
Copy link

Using "extends": "plugin:eslint-plugin-svelte/recommended" with [email protected] throws a Converting circular structure to JSON error. Perhaps something related to legacy vs flat config?

Steps to reproduce

Create a new blank SvelteKit app and answer the prompts as shown:

npx sv create app
┌  Welcome to the Svelte CLI! (v0.6.10)
│
◇  Which template would you like?
│  SvelteKit minimal
│
◇  Add type checking with Typescript?
│  No
│
◆  Project created
│
◇  What would you like to add to your project? (use arrow keys / space bar)
│  none
│
◇  Which package manager do you want to install dependencies with?
│  npm

Now add xo:

cd app
npm install xo --save-dev
npm init xo
npx xo # Runs successfully, and reports 9 lint errors

So far so good, but we aren’t linting Svelte files yet. Let’s add eslint-plugin-svelte@next (the @next is for Svelte 5 support) and configure xo to use it:

npm install --save-dev eslint-plugin-svelte@next
touch .xo-config.json

Edit the newly created .xo-config.json to include the following, adapted from https://github.com/sveltejs/eslint-plugin-svelte#configuration:

{
	"extensions": ["svelte"],
	"plugins": ["svelte"],
	"overrides": [
		{
			"files": "**/*.svelte",
			"extends": "plugin:eslint-plugin-svelte/recommended",
			"processor": "svelte/svelte",
			"envs": ["browser"]
		}
	]
}

Now npx xo returns:

/private/tmp/app/node_modules/eslint/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2156
                const formattedValue = JSON.stringify(error.data);
                                            ^

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'plugins' -> object with constructor 'Object'
    |     property 'svelte' -> object with constructor 'Module'
    |     ...
    |     property 'base' -> object with constructor 'Array'
    --- index 0 closes the circle
Referenced from: BaseConfig

Removing the "extends": "plugin:eslint-plugin-svelte/recommended" line makes the error go away, but linting of Svelte files breaks.

@GeoffreyBooth
Copy link
Author

GeoffreyBooth commented Jan 7, 2025

As a workaround, I replaced .xo-config.json with this .xo-config.cjs:

const eslintPluginSvelte = require('eslint-plugin-svelte');

/** @type {import('xo').Options} */
const config = {
	extensions: ['svelte'],
	plugins: ['svelte'],
	overrides: [
		{
			files: ['*.svelte', '**/*.svelte', '**/*.svelte.js', '*.svelte.js'],
			processor: 'svelte/svelte',
			parser: 'svelte-eslint-parser',
			envs: ['browser'],
			rules: Object.assign({}, ...eslintPluginSvelte.configs.recommended.flatMap(({rules}) => rules)),
		},
	],
};

module.exports = config;

This works, by replacing the extends line with a programmatically generated rules object.

The above bears little resemblance to the example configuration described in eslint-plugin-svelte‘s documentation at https://github.com/sveltejs/eslint-plugin-svelte#configuration (simplified):

import eslintPluginSvelte from 'eslint-plugin-svelte';
export default [
  ...eslintPluginSvelte.configs.recommended,
];

Perhaps xo should align with the new style of eslint config files, or there should be more documentation and examples in xo’s docs of how to translate configurations such as this one into xo’s config file schema.

@GeoffreyBooth
Copy link
Author

Update: There’s an issue with the workaround, in that it doesn’t work with https://github.com/xojs/vscode-linter-xo, the xo extension for Visual Studio Code. As of today, VS Code runs Node.js 20.18.1 internally, which doesn’t support require of an ES module; and the 3.x version of eslint-plugin-svelte is ESM-only. Presumably when VS Code updates to a newer version of Node this issue will resolve itself, but in the meantime I can’t get lint hints in my editor.

The require of ESM that causes the crash is to eslint-plugin-svelte/lib/index.js from eslint/node_modules/@eslint/eslintrc/dist/eslintrc.cjs. The @eslint/eslintrc package is dual-published ESM and CommonJS, but the stack trace includes the CommonJS version because the package is being loaded as a dependency of eslint, which is CommonJS-only. I’m not sure how to resolve this, other than to wait for a VS Code update.

@spence-s
Copy link
Contributor

Thanks - this is a known issue related to the eslint 9/flat config upgrade as we are still waiting for dependents of xo to become compatible. I think the last blocker is the eslint prettier config we rely on for prettier support.

The update is a long time WIP and thanks for your patience 🙏🏻

@GeoffreyBooth
Copy link
Author

Thanks so much for your work on this library. I dug through the code to try to find a fix to propose but I came up empty.

I don’t use Prettier; is there a way to use this updated xo without Prettier support, but hopefully with support for flat config and ESM dependents?

@spence-s
Copy link
Contributor

spence-s commented Jan 10, 2025

If you want to beta test the flat-xo implementation I have been working on I went ahead and published a version. Since I made it a complete re-write I worked on it in a separate repo just for my convenience. When I started I wasn't sure I would ever get it to completion.

https://github.com/spence-s/flat-xo
https://www.npmjs.com/package/@spence-s/flat-xo

If you want to use with the xo editor extension, do this in package.json:

"xo": "npm:@spence-s/[email protected]"

The documentation is somewhat up to date, but may still need some tweaking so a few misleading things may be there. It can only be configured now with an xo.config.js or xo.config.ts.

It mostly works but there is still some bugs around tsconfig resolution, so for ts, you must have the files included in your tsconfig for the extension to work. There may be some minor API and CLI changes coming soon, I am working on getting a PR together for xo (this repo) and I expect some feedback.

If you have trouble with it, file an issue over in that repo and it will be a great help!

cc: @fregante @sindresorhus - if you have interest in beta testing and providing feedback, I will be working on opening a PR this weekend.

@spence-s
Copy link
Contributor

spence-s commented Jan 10, 2025

Also note that the editor extension accepts a path to a nodejs binary as an option so you can run xo with your node version and not the default version bundled with vscode.

"xo.runtime": "/path/to/node23"

so you should still be able to use your work around if you'd rather.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants