Skip to content

Commit 2f68f10

Browse files
committed
chore: Rollup & Vitest
* Use Rollup instead of Babel to generate CJS and ESM bundles * Convert implementation to ESM * Use Vitest instead of Jest for tests * Use memfs instead of mocking specific node:fs functions * Update nps calls to use CJS config
1 parent 39a7744 commit 2f68f10

25 files changed

+964
-771
lines changed

.eslintrc.js renamed to .eslintrc.cjs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ const config = {
22
extends: [
33
'kentcdodds',
44
'kentcdodds/jest',
5-
'plugin:node-dependencies/recommended'
5+
'plugin:node-dependencies/recommended',
66
],
77
parserOptions: {
8-
ecmaVersion: 2021
8+
ecmaVersion: 2021,
99
},
1010
rules: {
1111
'valid-jsdoc': 'off',
@@ -15,16 +15,16 @@ const config = {
1515
{
1616
anonymous: 'never',
1717
named: 'never',
18-
asyncArrow: 'always'
19-
}
18+
asyncArrow: 'always',
19+
},
2020
],
2121
'import/no-import-module-exports': 'off',
2222
'arrow-parens': ['error', 'as-needed'],
2323
quotes: ['error', 'single', { avoidEscape: true }],
2424
},
2525
settings: {
26-
'import/ignore': ['node_modules', 'src'] // Using CommonJS in src
27-
}
26+
'import/ignore': ['node_modules', 'src'], // Using CommonJS in src
27+
},
2828
};
2929

3030
module.exports = config;

.github/dependabot.yml

+27-6
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,41 @@ updates:
5959
- 17.3.9
6060
- 17.4.0
6161
- 17.4.1
62+
- dependency-name: '@rollup/plugin-commonjs'
63+
versions:
64+
- 28.0.1
65+
- dependency-name: '@rollup/plugin-json'
66+
versions:
67+
- 6.1.0
68+
- dependency-name: '@rollup/plugin-node-resolve'
69+
versions:
70+
- 15.3.0
71+
- dependency-name: rollup
72+
versions:
73+
- 4.28.0
74+
- dependency-name: rollup-plugin-auto-external
75+
versions:
76+
- 2.0.0
77+
- dependency-name: memfs
78+
versions:
79+
- 4.14.1
6280
- dependency-name: vue-eslint-parser
6381
versions:
6482
- 7.4.1
6583
- 7.5.0
6684
- 7.6.0
67-
- dependency-name: jest-cli
85+
- dependency-name: vite
86+
versions:
87+
- 6.0.3
88+
- dependency-name: vitest
6889
versions:
69-
- 26.6.3
70-
- dependency-name: babel-jest
90+
- 2.1.8
91+
- dependency-name: '@vitest/coverage-v8'
7192
versions:
72-
- 26.6.3
73-
- dependency-name: jest
93+
- 2.1.8
94+
- dependency-name: '@vitest/ui'
7495
versions:
75-
- 26.6.3
96+
- 2.1.8
7697
- dependency-name: pretty-format
7798
versions:
7899
- 26.6.2

.prettierrc.js

-4
This file was deleted.

babel.config.js

-14
This file was deleted.

jest.config.js

-14
This file was deleted.

package-scripts.js renamed to package-scripts.cjs

+11-15
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,15 @@ module.exports = {
2222
// with ESM. ESM support is needed due to prettier v3’s use of a dynamic
2323
// `import()` in its `.cjs` file. The flag can be removed when node
2424
// supports modules in the VM API or the import is removed from prettier.
25-
default: crossEnv(
26-
'NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --coverage'
27-
),
28-
update: crossEnv(
29-
'NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --coverage --updateSnapshot'
30-
),
31-
watch: crossEnv(
32-
'NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --watch'
33-
),
25+
default: crossEnv('vitest --coverage run'),
26+
update: crossEnv('vitest --coverage --updateSnapshot'),
27+
watch: crossEnv('vitest'),
3428
openCoverage: 'open coverage/lcov-report/index.html',
3529
},
3630
build: {
37-
description: 'delete the dist directory and run babel to build the files',
38-
script: series(
39-
rimraf('dist'),
40-
'babel --out-dir dist --ignore "src/__tests__/**/*","src/__mocks__/**/*" src'
41-
),
31+
description:
32+
'delete the dist directory and run Rollup to build the files',
33+
script: series(rimraf('dist'), 'rollup -c'),
4234
},
4335
lint: {
4436
description: 'lint the entire project',
@@ -57,7 +49,11 @@ module.exports = {
5749
validate: {
5850
description:
5951
'This runs several scripts to make sure things look good before committing or on clean install',
60-
script: concurrent.nps('lint', 'build', 'test'),
52+
script: concurrent([
53+
'nps -c ./package-scripts.cjs lint',
54+
'nps -c ./package-scripts.cjs build',
55+
'nps -c ./package-scripts.cjs test',
56+
]),
6157
},
6258
format: {
6359
description: 'Formats everything with prettier-eslint',

package.json

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
"name": "prettier-eslint",
33
"version": "16.3.0",
44
"description": "Formats your JavaScript using prettier followed by eslint --fix",
5-
"main": "dist/index.js",
5+
"main": "dist/index.cjs.js",
6+
"module": "dist/index.esm.js",
67
"types": "types/index.d.ts",
8+
"type": "module",
79
"scripts": {
810
"prepare": "husky install",
9-
"start": "nps",
10-
"test": "nps test"
11+
"start": "nps -c ./package-scripts.cjs",
12+
"test": "nps -c ./package-scripts.cjs test"
1113
},
1214
"files": [
1315
"dist",
@@ -52,20 +54,29 @@
5254
"@babel/preset-env": "^7.22.9",
5355
"@changesets/changelog-github": "^0.4.8",
5456
"@changesets/cli": "^2.26.2",
57+
"@rollup/plugin-commonjs": "^28.0.1",
58+
"@rollup/plugin-json": "^6.1.0",
59+
"@rollup/plugin-node-resolve": "^15.3.0",
5560
"@types/eslint": "^8.4.2",
61+
"@vitest/coverage-v8": "^2.1.8",
62+
"@vitest/ui": "^2.1.8",
5663
"all-contributors-cli": "^6.7.0",
5764
"eslint-config-kentcdodds": "^20.5.0",
5865
"eslint-plugin-node-dependencies": "^0.11.0",
5966
"husky": "^8.0.1",
6067
"jest": "^29.6.2",
68+
"memfs": "^4.14.1",
6169
"nps": "^5.7.1",
6270
"nps-utils": "^1.3.0",
6371
"prettier-eslint-cli": "^8.0.0",
6472
"prettier-plugin-svelte": "^3.1.2",
6573
"rimraf": "^5.0.5",
74+
"rollup": "^4.28.0",
75+
"rollup-plugin-auto-external": "^2.0.0",
6676
"strip-indent": "^3.0.0",
6777
"svelte": "^4.2.9",
68-
"svelte-eslint-parser": "^0.33.1"
78+
"svelte-eslint-parser": "^0.33.1",
79+
"vitest": "^2.1.8"
6980
},
7081
"engines": {
7182
"node": ">=16.10.0"

prettier.config.mjs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default {
2+
arrowParens: 'avoid',
3+
singleQuote: true,
4+
};

rollup.config.mjs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import autoExternal from 'rollup-plugin-auto-external';
2+
import commonjs from '@rollup/plugin-commonjs';
3+
import json from '@rollup/plugin-json';
4+
import { nodeResolve } from '@rollup/plugin-node-resolve';
5+
6+
export default {
7+
input: 'src/index.mjs',
8+
output: [
9+
{
10+
file: 'dist/cjs/index.js',
11+
format: 'cjs',
12+
name: 'cjs-bundle',
13+
},
14+
{
15+
file: 'dist/esm/index.js',
16+
format: 'esm',
17+
name: 'esm-bundle',
18+
},
19+
],
20+
external: ['fs', 'node:path'],
21+
plugins: [
22+
autoExternal(),
23+
commonjs({
24+
include: /node_modules/,
25+
requireReturnsDefault: 'auto',
26+
strictRequires: 'debug',
27+
}),
28+
nodeResolve({ preferBuiltins: true }),
29+
json(),
30+
],
31+
};
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,16 @@
1+
import { vi } from 'vitest';
2+
13
// this mock file is so eslint doesn't attempt to actually
24
// search around the file system for stuff
35

4-
const eslint = jest.requireActual('eslint');
5-
const { ESLint } = eslint;
6-
7-
const mockCalculateConfigForFileSpy = jest.fn(mockCalculateConfigForFile);
8-
mockCalculateConfigForFileSpy.overrides = {};
9-
const mockLintTextSpy = jest.fn(mockLintText);
10-
11-
module.exports = Object.assign(eslint, {
12-
ESLint: jest.fn(MockESLint),
13-
mock: {
14-
calculateConfigForFile: mockCalculateConfigForFileSpy,
15-
lintText: mockLintTextSpy
16-
}
17-
});
18-
19-
function MockESLint(...args) {
20-
global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename;
21-
const eslintInstance = new ESLint(...args);
22-
eslintInstance.calculateConfigForFile = mockCalculateConfigForFileSpy;
23-
eslintInstance._originalLintText = eslintInstance.lintText;
24-
eslintInstance.lintText = mockLintTextSpy;
25-
return eslintInstance;
26-
}
27-
28-
MockESLint.prototype = Object.create(ESLint.prototype);
6+
const eslintActual = await vi.importActual('eslint');
7+
const { ESLint } = eslintActual;
298

309
// eslint-disable-next-line complexity
3110
function mockCalculateConfigForFile(filePath) {
32-
if (mockCalculateConfigForFileSpy.throwError) {
33-
throw mockCalculateConfigForFileSpy.throwError;
34-
}
3511
if (!filePath) {
3612
return {
37-
rules: {}
13+
rules: {},
3814
};
3915
}
4016
if (filePath.includes('default-config')) {
@@ -46,7 +22,7 @@ function mockCalculateConfigForFile(filePath) {
4622
quotes: [
4723
2,
4824
'single',
49-
{ avoidEscape: true, allowTemplateLiterals: true }
25+
{ avoidEscape: true, allowTemplateLiterals: true },
5026
],
5127
'comma-dangle': [
5228
2,
@@ -55,26 +31,44 @@ function mockCalculateConfigForFile(filePath) {
5531
objects: 'always-multiline',
5632
imports: 'always-multiline',
5733
exports: 'always-multiline',
58-
functions: 'always-multiline'
59-
}
34+
functions: 'always-multiline',
35+
},
6036
],
61-
'arrow-parens': [2, 'as-needed']
62-
}
37+
'arrow-parens': [2, 'as-needed'],
38+
},
6339
};
6440
} else if (filePath.includes('fixtures/paths')) {
6541
return { rules: {} };
6642
} else {
6743
throw new Error(
6844
`Your mock filePath (${filePath})` +
69-
' does not have a handler for finding the config'
45+
' does not have a handler for finding the config',
7046
);
7147
}
7248
}
7349

74-
function mockLintText(...args) {
50+
const mockLintTextSpy = vi.fn(function mockLintText(...args) {
7551
/* eslint no-invalid-this:0 */
7652
if (mockLintTextSpy.throwError) {
7753
throw mockLintTextSpy.throwError;
7854
}
7955
return this._originalLintText(...args);
56+
});
57+
58+
const calculateConfigForFileSpy = vi.spyOn(ESLint.prototype, 'calculateConfigForFile').mockImplementation(mockCalculateConfigForFile);
59+
const lintTextSpy = vi.spyOn(ESLint.prototype, 'lintText');
60+
61+
function MockESLint(...args) {
62+
global.__PRETTIER_ESLINT_TEST_STATE__.eslintPath = __filename;
63+
return new ESLint(...args);
8064
}
65+
66+
export default {
67+
...eslintActual.default,
68+
ESLint: vi.fn(MockESLint),
69+
};
70+
71+
export const helpers = {
72+
getCalculateConfigForFileSpy: () => calculateConfigForFileSpy,
73+
getLintTextSpy: () => lintTextSpy,
74+
};

src/__mocks__/fs.js

-13
This file was deleted.

src/__mocks__/fs.mjs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This follows the advice of the Vitest Mocking guide, and mocks the full
2+
// filesystem with an in-memory replacement.
3+
// https://vitest.dev/guide/mocking#file-system
4+
const { createFsFromVolume, memfs, Volume } = require('memfs');
5+
import path from 'node:path';
6+
7+
const files = [
8+
'foo.js',
9+
'package.json',
10+
'node_modules/eslint/index.js',
11+
'node_modules/prettier/index.js',
12+
];
13+
14+
const volume = new Volume();
15+
16+
volume.fromJSON(
17+
Object.fromEntries(
18+
files.map(file => {
19+
return [`./${file}`, `.tests/fixtures/paths/${file}`];
20+
}),
21+
),
22+
`${path.dirname(__filename)}/../../tests/fixtures/paths`,
23+
);
24+
25+
export default createFsFromVolume(volume);

0 commit comments

Comments
 (0)