Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
module.exports = {
endOfLine: 'auto',
singleQuote: true,
trailingComma: 'all',
printWidth: 160,
};
module.exports = require('./config/prettierrc.template');
1 change: 1 addition & 0 deletions bin/commands/bundle.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { resolve } = require('path');

const { call } = require('./utils');

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion bin/commands/copy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const glob = require('glob');
const fs = require('fs-extra');
const glob = require('glob');
const path = require('path');

module.exports = {
Expand Down
34 changes: 28 additions & 6 deletions bin/commands/lint.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
const { call } = require('./utils');
const { call, isFormatSeparate } = require('./utils');

module.exports = {
command: 'lint [strings...]',
describe: 'Lint a repository using ESLint',
builder: (yargs) =>
yargs.option('cache', {
default: true,
type: 'boolean',
}),
yargs
.option('cache', {
default: true,
type: 'boolean',
})
.option('fix', {
default: false,
type: 'boolean',
})
.option('quiet', {
default: false,
type: 'boolean',
})
.option('format', {
// For now, enable format in the CI only. Otherwise, we would have to add the prettier VSCode plugin and adapt workflows for everyone.
default: isFormatSeparate(),
type: 'boolean',
}),
handler: (args) => {
if (args.format) {
// Run prettier separately as it's much faster with the oxc plugin, and the eslint-plugin-prettier doesn't use that apparently.
call(
'prettier',
`prettier ${args.fix ? '--write' : '--check'} --experimental-cli ${(args.strings || []).join(' ')} "src/**/*.ts{,x}" "tests/**/*.ts{,x}" "playwright/**/*.ts{,x}"`,
);
}

call(
'eslint',
`${args.cache ? '--cache' : ''} --no-error-on-unmatched-pattern ${(args.strings || []).join(' ')} "src/**/*.ts{,x}" "tests/**/*.ts{,x}" "playwright/**/*.ts{,x}"`,
`${args.cache ? '--cache' : ''} ${args.fix ? '--fix' : ''} ${args.quiet ? '--quiet' : ''} --cache-location node_modules/.cache/eslint --no-error-on-unmatched-pattern ${(args.strings || []).join(' ')} "src/**/*.ts{,x}" "tests/**/*.ts{,x}" "playwright/**/*.ts{,x}"`,
);
},
};
1 change: 1 addition & 0 deletions bin/commands/start.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { resolve } = require('path');

const { call } = require('./utils');

module.exports = {
Expand Down
9 changes: 8 additions & 1 deletion bin/commands/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { execSync } = require('child_process');
const { resolve, join } = require('path');
const fs = require('fs');
const { resolve, join } = require('path');

/**
* Wraps `execSync` with options and error handling.
Expand Down Expand Up @@ -33,6 +33,8 @@ const call = (command, args, options = {}) => {
NODE_PATH: nodePath,
// Increase memory limits for node all processes
NODE_OPTIONS: '--max-old-space-size=8192 --max-semi-space-size=512',
// Enable the faster prettier CLI: https://www.solberg.is/prettier-is-fast
PRETTIER_EXPERIMENTAL_CLI: 1,
...(options.env || {}),
...process.env,
},
Expand All @@ -43,6 +45,11 @@ const call = (command, args, options = {}) => {
}
};

const isFormatSeparate = () => {
return ['true', '1'].includes(process.env.VISYN_SCRIPTS_FORMAT_SEPARATE?.toLocaleLowerCase());
};

module.exports = {
call,
isFormatSeparate,
};
66 changes: 25 additions & 41 deletions config/eslint.config.template.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
const { defineConfig } = require('eslint/config');
const { includeIgnoreFile } = require('@eslint/compat');
const { rules: prettierConfigRules } = require('eslint-config-prettier');
const js = require('@eslint/js');
const { defineConfig } = require('eslint/config');
const airbnb = require('eslint-config-airbnb-extended');
const globals = require('globals');
const eslintConfigPrettier = require('eslint-config-prettier/flat');
const jest = require('eslint-plugin-jest');
const js = require('@eslint/js');
const jsxA11y = require('eslint-plugin-jsx-a11y');
const path = require('node:path');
const playwright = require('eslint-plugin-playwright');
const prettierPlugin = require('eslint-plugin-prettier');
const eslintPluginPrettier = require('eslint-plugin-prettier/recommended');
const reactCompiler = require('eslint-plugin-react-compiler');
const unusedImports = require('eslint-plugin-unused-imports');
const globals = require('globals');
const path = require('node:path');

const { isFormatSeparate } = require('../bin/commands/utils');

const jsConfig = [
{
Expand All @@ -30,34 +32,11 @@ const reactConfig = [
...airbnb.configs.react.recommended,
];

const typescriptConfig = [
// TypeScript ESLint Plugin
airbnb.plugins.typescriptEslint,
// Airbnb Base TypeScript Config
...airbnb.configs.base.typescript,
// Airbnb React TypeScript Config
...airbnb.configs.react.typescript,
];

const prettierConfig = [
{
name: 'prettier/plugin/config',
plugins: {
prettier: prettierPlugin,
},
},
{
name: 'prettier/config',
rules: {
...prettierConfigRules,
'prettier/prettier': 'error',
},
},
];
const typescriptConfig = [airbnb.plugins.typescriptEslint, ...airbnb.configs.base.typescript, ...airbnb.configs.react.typescript];

const jestConfig = [
{
files: ['{src|tests}/**/*.{test|spec}.ts'],
files: ['{src|tests}/**/*.{test|spec}.{js,ts,jsx,tsx}'],
plugins: { jest },
languageOptions: {
globals: jest.environments.globals.globals,
Expand All @@ -68,27 +47,31 @@ const jestConfig = [
const playwrightConfig = [
{
...playwright.configs['flat/recommended'],
files: ['playwright/**/*.{test|spec}.ts'],
files: ['playwright/**/*.{test|spec}.{js,ts,jsx,tsx}'],
},
];

// Helper to disable jsx-a11y rules
const jsxA11yOffRules = Object.keys(jsxA11y.rules).reduce((acc, rule) => {
acc[`jsx-a11y/${rule}`] = 'off';
return acc;
}, {});
const jsxA11yOffRules = Object.fromEntries(Object.keys(jsxA11y.rules).map((rule) => [`jsx-a11y/${rule}`, 'off']));

module.exports = ({ tsconfigRootDir }) =>
module.exports = ({
tsconfigRootDir,
includeJS,
// For now, keep the prettier plugin enabled. Otherwise, we would have to add the prettier VSCode plugin and adapt workflows for everyone.
// The visyn_scripts lint will automatically run prettier if this is enabled.
includePrettierPlugin = !isFormatSeparate(),
}) =>
defineConfig(
includeIgnoreFile(path.resolve('.', '.gitignore')),
...jsConfig,
...reactConfig,
...typescriptConfig,
...prettierConfig,
...jestConfig,
...playwrightConfig,
// The prettier plugin contains both the config and the rule to run prettier as an eslint rule, whereas the config just disables conflicting rules (i.e. if you run prettier separately).
...(includePrettierPlugin ? [eslintPluginPrettier] : [eslintConfigPrettier]),
{
files: ['**/*.{ts,tsx,cts,mts}'],
files: ['**/*.{ts,tsx,cts,mts}', ...(includeJS ? ['**/*.{js,jsx,cjs,mjs}'] : [])],
plugins: {
'unused-imports': unusedImports,
},
Expand All @@ -105,14 +88,15 @@ module.exports = ({ tsconfigRootDir }) =>
project: `./tsconfig.eslint.json`,
},
globals: {
...globals.commonjs,
...globals.jest,
...globals.node,
...globals.browser,
...globals.es6,
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
},

rules: {
...jsxA11yOffRules,
'arrow-body-style': 'off',
Expand Down Expand Up @@ -159,7 +143,7 @@ module.exports = ({ tsconfigRootDir }) =>
},
],
'prefer-arrow-callback': 'warn',
'@typescript-eslint/no-require-imports': 'warn',
'@typescript-eslint/no-require-imports': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/ban-ts-comment': 'warn',
Expand Down
1 change: 0 additions & 1 deletion config/jest_export_maps_resolver.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// temporary workaround while we wait for https://github.com/facebook/jest/issues/9771
// eslint-disable-next-line import-x/no-extraneous-dependencies
const resolver = require('enhanced-resolve').create.sync({
conditionNames: ['require', 'node', 'default', 'import'],
extensions: ['.js', '.json', '.node', '.ts', '.tsx'],
Expand Down
2 changes: 2 additions & 0 deletions config/prettierrc.template.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module.exports = {
// Use the oxc plugin for speed: https://www.solberg.is/prettier-is-fast
plugins: ['@prettier/plugin-oxc'],
endOfLine: 'auto',
singleQuote: true,
trailingComma: 'all',
Expand Down
18 changes: 9 additions & 9 deletions config/rspack.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/* eslint-disable prefer-const */
/* eslint-disable import-x/no-dynamic-require */
const path = require('path');
const fs = require('fs');
const { execSync } = require('child_process');
const { RsdoctorRspackPlugin } = require('@rsdoctor/rspack-plugin');
const { defineConfig } = require('@rspack/cli');
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
const dotenv = require('dotenv');
const DotenvPlugin = require('dotenv-webpack');
const dotenvExpand = require('dotenv-expand');
const { CopyRspackPlugin, DefinePlugin, SwcJsMinimizerRspackPlugin } = require('@rspack/core');
const ReactRefreshPlugin = require('@rspack/plugin-react-refresh');
const { execSync } = require('child_process');
const dotenv = require('dotenv');
const dotenvExpand = require('dotenv-expand');
const DotenvPlugin = require('dotenv-webpack');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { RsdoctorRspackPlugin } = require('@rsdoctor/rspack-plugin');
const path = require('path');
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');

// Load the current .env and expand it
const parsedEnv = dotenvExpand.expand(dotenv.config());
Expand Down Expand Up @@ -420,7 +420,7 @@ module.exports = (webpackEnv, argv) => {
fs.existsSync(workspaceMetaDataFile) && {
from: workspaceMetaDataFile,
to: path.join(workspacePath, 'bundles', 'phoveaMetaData.json'),
// @ts-ignore TODO: check why https://webpack.js.org/plugins/copy-webpack-plugin/#transform is not in the typing.
// @ts-expect-error TODO: check why https://webpack.js.org/plugins/copy-webpack-plugin/#transform is not in the typing.
transform: () => {
function resolveScreenshot(appDirectory) {
const f = path.join(appDirectory, './media/screenshot.png');
Expand Down
1 change: 1 addition & 0 deletions config/storybook.main.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = {
},
},
rsbuildFinal: async (config) => {
// eslint-disable-next-line @typescript-eslint/prefer-destructuring
const reactDocgenLoaderRule = config.tools.rspack[1].module.rules[0];

// eslint-disable-next-line no-param-reassign
Expand Down
59 changes: 1 addition & 58 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,58 +1 @@
const path = require('node:path');

const globals = require('globals');
const { includeIgnoreFile } = require('@eslint/compat');
const js = require('@eslint/js');
const { configs, plugins } = require('eslint-config-airbnb-extended');
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');

const gitignorePath = path.resolve('.', '.gitignore');

/**
* @type {import('eslint').Linter.Config[]}
*/
const jsConfig = [
{
languageOptions: {
globals: { ...globals.browser, ...globals.node, ...globals.jest },
},
},
// ESLint Recommended Rules
{
name: 'js/config',
...js.configs.recommended,
},
// Stylistic Plugin
plugins.stylistic,
// Import X Plugin
plugins.importX,
// Airbnb Base Recommended Config
...configs.base.recommended,
];

/**
* @type {import('eslint').Linter.Config[]}
*/
const typescriptConfig = [
// TypeScript ESLint Plugin
plugins.typescriptEslint,
// Airbnb Base TypeScript Config
...configs.base.typescript,
];

module.exports = [
// Ignore .gitignore files/folder in eslint
includeIgnoreFile(gitignorePath),
// Javascript Config
...jsConfig,
// TypeScript Config
...typescriptConfig,
// Prettier Config
eslintPluginPrettierRecommended,
{
rules: {
'no-console': 'off',
'max-len': 'off',
},
},
];
module.exports = require('./config/eslint.config.template')({ tsconfigRootDir: __dirname, includeJS: true });
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "visyn_scripts",
"description": "",
"version": "15.1.2",
"version": "15.1.3",
"author": {
"name": "datavisyn GmbH",
"email": "contact@datavisyn.io",
Expand All @@ -28,8 +28,9 @@
"node": ">=24"
},
"scripts": {
"lint": "eslint bin/**/*.js config/**/*.js tests/**/*.js *.js",
"lint:fix": "eslint --fix bin/**/*.js config/**/*.js tests/**/*.js *.js",
"all": "yarn run lint:fix && yarn run test",
"lint": "visyn_scripts lint bin/**/*.js config/**/*.js tests/**/*.js *.js",
"lint:fix": "visyn_scripts lint --fix bin/**/*.js config/**/*.js tests/**/*.js *.js",
"test": "jest -w 1",
"test:watch": "jest -w 1 --watch",
"build": "echo 'No build script defined'",
Expand All @@ -39,6 +40,7 @@
"@eslint/compat": "^1.4.1",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.38.0",
"@prettier/plugin-oxc": "^0.0.4",
"@rsbuild/core": "1.5.13",
"@rsbuild/plugin-node-polyfill": "^1.4.2",
"@rsbuild/plugin-react": "^1.4.1",
Expand Down
4 changes: 2 additions & 2 deletions tests/standalone.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const fs = require('fs');
const { resolve } = require('path');
const { execSync } = require('child_process');
const fs = require('fs');
const fse = require('fs-extra');
const { resolve } = require('path');

// Mock setup of yargs inspired by https://www.kgajera.com/blog/how-to-test-yargs-cli-with-jest/
describe('standalone', () => {
Expand Down
1 change: 1 addition & 0 deletions tests/visyn_scripts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('cli', () => {

// After resetting the modules, we need to reinitialize the mocks
jest.mock('../bin/commands/utils');
// eslint-disable-next-line prefer-destructuring, @typescript-eslint/prefer-destructuring
call = require('../bin/commands/utils').call;

// Each test overwrites process arguments so store the original arguments
Expand Down
Loading