diff --git a/.eslintignore b/.eslintignore index c41556f6aae102aeb5504dac63764862b9c9eaf4..73e11dfd9744ae6f34ff03254bdb76de1ed1ddcc 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,15 +1,9 @@ /app/assets/javascripts/locale/**/app.js -/config/ /builds/ /coverage/ /coverage-frontend/ /coverage-javascript/ /node_modules/ /public/ -/scripts/ /tmp/ /vendor/ -jest.config.js -jest.config.*.js -karma.config.js -webpack.config.js diff --git a/.eslintrc.yml b/.eslintrc.yml index 75c52ac1319a353a38c96f77662ed94d1d8ac47f..678750c085b296aba8ef72cdf88ac10e4b7da8cd 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -89,3 +89,15 @@ overrides: rules: '@gitlab/require-i18n-strings': off '@gitlab/no-runtime-template-compiler': off + - files: + - 'config/**/*' + - 'scripts/**/*' + - '*.config.js' + - 'jest.*.js' + rules: + '@gitlab/require-i18n-strings': off + import/no-extraneous-dependencies: off + import/no-commonjs: off + import/no-nodejs-modules: off + filenames/match-regex: off + no-console: off diff --git a/babel.config.js b/babel.config.js index 6c9d46405355875d5c0ee1e039e4510af10b8e78..4dfca8f61448c280e48e89d7e35f36a87db182c4 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,5 +1,3 @@ -/* eslint-disable import/no-commonjs, filenames/match-regex */ - const BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV || null; let presets = [ diff --git a/config/helpers/incremental_webpack_compiler.js b/config/helpers/incremental_webpack_compiler.js index 786bb6071fa3b966f4885707877329672df92413..5d4f9bd040d164fe76a47bafd3d701cf546840ac 100644 --- a/config/helpers/incremental_webpack_compiler.js +++ b/config/helpers/incremental_webpack_compiler.js @@ -1,3 +1,4 @@ +/* eslint-disable max-classes-per-file, no-underscore-dangle */ const fs = require('fs'); const path = require('path'); @@ -7,6 +8,7 @@ const log = (msg, ...rest) => console.log(`IncrementalWebpackCompiler: ${msg}`, // Five seconds seem to work fine and the user can read the message const TIMEOUT = 5000; +/* eslint-disable class-methods-use-this */ class NoopCompiler { constructor() { this.enabled = false; @@ -20,6 +22,7 @@ class NoopCompiler { setupMiddleware() {} } +/* eslint-enable class-methods-use-this */ class IncrementalWebpackCompiler { constructor(historyFilePath) { diff --git a/config/helpers/is_eslint.js b/config/helpers/is_eslint.js index 60528796962ec3519baa8a1fb72e9f6314aed72a..9a3a9bfca12fc33cd6b885cacc0d1a412f4a57d1 100644 --- a/config/helpers/is_eslint.js +++ b/config/helpers/is_eslint.js @@ -2,7 +2,7 @@ * Returns true if the given module is required from eslint */ const isESLint = (mod) => { - let parent = mod.parent; + let { parent } = mod; while (parent) { if (parent.filename && parent.filename.includes('/eslint')) { diff --git a/config/helpers/vendor_dll_hash.js b/config/helpers/vendor_dll_hash.js index 2df97e7b95d609b6eee217ee36af537075c171e4..cdbaebc9789b480b3becedfd0d52053534c49d81 100644 --- a/config/helpers/vendor_dll_hash.js +++ b/config/helpers/vendor_dll_hash.js @@ -1,6 +1,6 @@ const fs = require('fs'); -const path = require('path'); const crypto = require('crypto'); +const path = require('path'); const CACHE_PATHS = [ './config/webpack.config.js', diff --git a/config/karma.config.js b/config/karma.config.js index 1d65e65ce2ac6383f4dc346396c9b7c7c96bdfc9..1c2dd21c1890c54afa3466ea32ee5563fbd6054f 100644 --- a/config/karma.config.js +++ b/config/karma.config.js @@ -1,13 +1,14 @@ -const path = require('path'); -const glob = require('glob'); +/* eslint-disable no-inner-declarations, no-param-reassign */ const chalk = require('chalk'); -const webpack = require('webpack'); const argumentsParser = require('commander'); -const webpackConfig = require('./webpack.config.js'); +const glob = require('glob'); +const path = require('path'); +const webpack = require('webpack'); const IS_EE = require('./helpers/is_ee_env'); +const webpackConfig = require('./webpack.config.js'); const ROOT_PATH = path.resolve(__dirname, '..'); -const SPECS_PATH = /^(?:\.[\\\/])?(ee[\\\/])?spec[\\\/]javascripts[\\\/]/; +const SPECS_PATH = /^(?:\.[\\/])?(ee[\\/])?spec[\\/]javascripts[\\/]/; function exitError(message) { console.error(chalk.red(`\nError: ${message}\n`)); @@ -77,7 +78,7 @@ if (specFilters.length) { root: ROOT_PATH, matchBase: true, }) - .filter((path) => path.endsWith('spec.js')), + .filter((filePath) => filePath.endsWith('spec.js')), ); // flatten @@ -97,14 +98,14 @@ if (specFilters.length) { } const CE_FILES = filteredSpecFiles.filter((file) => !file.startsWith('ee')); - createContext(CE_FILES, /[^e]{2}[\\\/]spec[\\\/]javascripts$/, 'spec/javascripts'); + createContext(CE_FILES, /[^e]{2}[\\/]spec[\\/]javascripts$/, 'spec/javascripts'); const EE_FILES = filteredSpecFiles.filter((file) => file.startsWith('ee')); - createContext(EE_FILES, /ee[\\\/]spec[\\\/]javascripts$/, 'ee/spec/javascripts'); + createContext(EE_FILES, /ee[\\/]spec[\\/]javascripts$/, 'ee/spec/javascripts'); } // Karma configuration -module.exports = function (config) { +module.exports = (config) => { process.env.TZ = 'Etc/UTC'; const fixturesPath = `tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`; diff --git a/config/webpack.config.js b/config/webpack.config.js index e43fc3ed21c337c3644b381cec48935ff56ef066..e02141acc590996e0ddd3ea03b75ad4d162d32e2 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -1,25 +1,34 @@ const fs = require('fs'); -const path = require('path'); -const glob = require('glob'); -const webpack = require('webpack'); -const VueLoaderPlugin = require('vue-loader/lib/plugin'); -const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; + +const SOURCEGRAPH_VERSION = require('@sourcegraph/code-host-integration/package.json').version; + const CompressionPlugin = require('compression-webpack-plugin'); -const MonacoWebpackPlugin = require('./plugins/monaco_webpack'); -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const CopyWebpackPlugin = require('copy-webpack-plugin'); -const vendorDllHash = require('./helpers/vendor_dll_hash'); +const glob = require('glob'); +const path = require('path'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const VUE_LOADER_VERSION = require('vue-loader/package.json').version; +const VUE_VERSION = require('vue/package.json').version; +const webpack = require('webpack'); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { StatsWriterPlugin } = require('webpack-stats-plugin'); +const WEBPACK_VERSION = require('webpack/package.json').version; + const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler'); +const IS_EE = require('./helpers/is_ee_env'); +const vendorDllHash = require('./helpers/vendor_dll_hash'); + +const MonacoWebpackPlugin = require('./plugins/monaco_webpack'); const ROOT_PATH = path.resolve(__dirname, '..'); const VENDOR_DLL = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_DLL !== 'false'; const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache'); const IS_PRODUCTION = process.env.NODE_ENV === 'production'; const IS_DEV_SERVER = process.env.WEBPACK_DEV_SERVER === 'true'; -const IS_EE = require('./helpers/is_ee_env'); + const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost'; const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808; -const DEV_SERVER_PUBLIC_ADDR = process.env.DEV_SERVER_PUBLIC_ADDR; +const { DEV_SERVER_PUBLIC_ADDR } = process.env; const DEV_SERVER_ALLOWED_HOSTS = process.env.DEV_SERVER_ALLOWED_HOSTS && process.env.DEV_SERVER_ALLOWED_HOSTS.split(','); const DEV_SERVER_HTTPS = process.env.DEV_SERVER_HTTPS && process.env.DEV_SERVER_HTTPS !== 'false'; @@ -38,11 +47,6 @@ const WEBPACK_OUTPUT_PATH = path.join(ROOT_PATH, 'public/assets/webpack'); const WEBPACK_PUBLIC_PATH = '/assets/webpack/'; const SOURCEGRAPH_PACKAGE = '@sourcegraph/code-host-integration'; -const VUE_VERSION = require('vue/package.json').version; -const VUE_LOADER_VERSION = require('vue-loader/package.json').version; -const WEBPACK_VERSION = require('webpack/package.json').version; -const SOURCEGRAPH_VERSION = require(path.join(SOURCEGRAPH_PACKAGE, 'package.json')).version; - const SOURCEGRAPH_PATH = path.join('sourcegraph', SOURCEGRAPH_VERSION, '/'); const SOURCEGRAPH_OUTPUT_PATH = path.join(WEBPACK_OUTPUT_PATH, SOURCEGRAPH_PATH); const SOURCEGRAPH_PUBLIC_PATH = path.join(WEBPACK_PUBLIC_PATH, SOURCEGRAPH_PATH); @@ -67,19 +71,19 @@ function generateEntries() { }); watchAutoEntries = [path.join(ROOT_PATH, 'app/assets/javascripts/pages/')]; - function generateAutoEntries(path, prefix = '.') { - const chunkPath = path.replace(/\/index\.js$/, ''); + function generateAutoEntries(entryPath, prefix = '.') { + const chunkPath = entryPath.replace(/\/index\.js$/, ''); const chunkName = chunkPath.replace(/\//g, '.'); - autoEntriesMap[chunkName] = `${prefix}/${path}`; + autoEntriesMap[chunkName] = `${prefix}/${entryPath}`; } - pageEntries.forEach((path) => generateAutoEntries(path)); + pageEntries.forEach((entryPath) => generateAutoEntries(entryPath)); if (IS_EE) { const eePageEntries = glob.sync('pages/**/index.js', { cwd: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), }); - eePageEntries.forEach((path) => generateAutoEntries(path, 'ee')); + eePageEntries.forEach((entryPath) => generateAutoEntries(entryPath, 'ee')); watchAutoEntries.push(path.join(ROOT_PATH, 'ee/app/assets/javascripts/pages/')); } @@ -198,9 +202,9 @@ module.exports = { }, { test: /\.js$/, - exclude: (path) => - /node_modules\/(?!tributejs)|node_modules|vendor[\\/]assets/.test(path) && - !/\.vue\.js/.test(path), + exclude: (modulePath) => + /node_modules\/(?!tributejs)|node_modules|vendor[\\/]assets/.test(modulePath) && + !/\.vue\.js/.test(modulePath), loader: 'babel-loader', options: { cacheDirectory: path.join(CACHE_PATH, 'babel-loader'), @@ -354,7 +358,7 @@ module.exports = { // webpack-rails only needs assetsByChunkName to function properly new StatsWriterPlugin({ filename: 'manifest.json', - transform: function (data, opts) { + transform(data, opts) { const stats = opts.compiler.getStats().toJson({ chunkModules: false, source: false, @@ -412,6 +416,7 @@ module.exports = { `Warning: No vendor DLL found at: ${dll.cacheFrom}. Compiling DLL automatically.`, ); + // eslint-disable-next-line global-require const dllConfig = require('./webpack.vendor.config.js'); const dllCompiler = webpack(dllConfig); @@ -435,7 +440,7 @@ module.exports = { } dll.exists = true; - callback(); + return callback(); }); } }); @@ -459,6 +464,7 @@ module.exports = { !IS_EE && new webpack.NormalModuleReplacementPlugin(/^ee_component\/(.*)\.vue/, (resource) => { + // eslint-disable-next-line no-param-reassign resource.request = path.join( ROOT_PATH, 'app/assets/javascripts/vue_shared/components/empty_component.js', @@ -521,7 +527,7 @@ module.exports = { // output the in-memory heap size upon compilation and exit WEBPACK_MEMORY_TEST && { apply(compiler) { - compiler.hooks.emit.tapAsync('ReportMemoryConsumptionPlugin', (compilation, callback) => { + compiler.hooks.emit.tapAsync('ReportMemoryConsumptionPlugin', () => { console.log('Assets compiled...'); if (global.gc) { console.log('Running garbage collection...'); @@ -552,7 +558,9 @@ module.exports = { ); // exit in case we're running webpack-dev-server - IS_DEV_SERVER && process.exit(); + if (IS_DEV_SERVER) { + process.exit(); + } }); }, }, diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js index 29c4c33314e7481950972d696df941838f57db53..7e5365987eeca9d3fa8ea8de893016e8e39db729 100644 --- a/config/webpack.vendor.config.js +++ b/config/webpack.vendor.config.js @@ -1,7 +1,7 @@ const path = require('path'); const webpack = require('webpack'); -const vendorDllHash = require('./helpers/vendor_dll_hash'); const { YarnCheck } = require('yarn-check-webpack-plugin'); +const vendorDllHash = require('./helpers/vendor_dll_hash'); const ROOT_PATH = path.resolve(__dirname, '..'); diff --git a/jest.config.base.js b/jest.config.base.js index 98c70735d92f4cca201ae342d700ce88962f7b43..4e9b84d1d34f89034cf7b28438d89f412712b050 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -27,7 +27,7 @@ module.exports = (path) => { // workaround for eslint-import-resolver-jest only resolving in test files // see https://github.com/JoinColony/eslint-import-resolver-jest#note if (isESLint(module)) { - testMatch = testMatch.map((path) => path.replace('_spec.js', '')); + testMatch = testMatch.map((modulePath) => modulePath.replace('_spec.js', '')); } const TEST_FIXTURES_PATTERN = 'test_fixtures(/.*)$'; diff --git a/scripts/frontend/block_dependencies.js b/scripts/frontend/block_dependencies.js index a1ff8d5ee3612bfb56ac07e5ef28c0516792eda8..f229f317cbb6d6ee91093f1e7bcce5178ff4184f 100644 --- a/scripts/frontend/block_dependencies.js +++ b/scripts/frontend/block_dependencies.js @@ -1,8 +1,8 @@ -const path = require('path'); -const packageJson = require(path.join(process.cwd(), 'package.json')); +const packageJson = require('../../package.json'); + const blockedDependencies = packageJson.blockedDependencies || {}; -const dependencies = packageJson.dependencies; -const devDependencies = packageJson.devDependencies; +const { dependencies } = packageJson; +const { devDependencies } = packageJson; const blockedDependenciesNames = Object.keys(blockedDependencies); const blockedDependenciesFound = blockedDependenciesNames.filter( (blockedDependency) => dependencies[blockedDependency] || devDependencies[blockedDependency], diff --git a/scripts/frontend/check_page_bundle_mixins_css_for_sideeffects.js b/scripts/frontend/check_page_bundle_mixins_css_for_sideeffects.js index 34e939e3cebe8c9b4d34c34256a781387ffa4ca7..22a4aac762b53c9c1a162622d9f8530dfa452bba 100755 --- a/scripts/frontend/check_page_bundle_mixins_css_for_sideeffects.js +++ b/scripts/frontend/check_page_bundle_mixins_css_for_sideeffects.js @@ -7,9 +7,9 @@ if (process.env.RAILS_ENV !== 'production') { process.exit(0); } -const path = require('path'); const fs = require('fs'); const glob = require('glob'); +const path = require('path'); const pjs = require('postcss'); const paths = glob.sync('public/assets/page_bundles/_mixins_and_variables_and_functions*.css', { diff --git a/scripts/frontend/extract_gettext_all.js b/scripts/frontend/extract_gettext_all.js index 67163a601bcac1bee02c65de1f5f0070a70d350b..896790a73bb9a24ff04f706dbe259ba9bec461f1 100644 --- a/scripts/frontend/extract_gettext_all.js +++ b/scripts/frontend/extract_gettext_all.js @@ -5,6 +5,7 @@ const { decorateJSParserWithVueSupport, decorateExtractorWithHelpers, } = require('gettext-extractor-vue'); +const vue2TemplateCompiler = require('vue-template-compiler'); const ensureSingleLine = require('../../app/assets/javascripts/locale/ensure_single_line.js'); const args = argumentsParser @@ -37,12 +38,12 @@ const jsParser = extractor.createJsParser([ ]); const vueParser = decorateJSParserWithVueSupport(jsParser, { - vue2TemplateCompiler: require('vue-template-compiler'), + vue2TemplateCompiler, }); function printJson() { - const messages = extractor.getMessages().reduce((result, message) => { - let text = message.text; + const messages = extractor.getMessages().reduce((acc, message) => { + let { text } = message; if (message.textPlural) { text += `\u0000${message.textPlural}`; } @@ -50,25 +51,35 @@ function printJson() { message.references.forEach((reference) => { const filename = reference.replace(/:\d+$/, ''); - if (!Array.isArray(result[filename])) { - result[filename] = []; + if (!Array.isArray(acc[filename])) { + acc[filename] = []; } - result[filename].push([text, reference]); + acc[filename].push([text, reference]); }); - return result; + return acc; }, {}); console.log(JSON.stringify(messages)); } -if (args.file) { - vueParser.parseFile(args.file).then(() => printJson()); -} else if (args.all) { - vueParser.parseFilesGlob('{ee/app,app}/assets/javascripts/**/*.{js,vue}').then(() => printJson()); -} else { - console.warn('ERROR: Please use the script correctly:'); +async function main() { + if (args.file) { + return vueParser.parseFile(args.file).then(() => printJson()); + } + + if (args.all) { + return vueParser + .parseFilesGlob('{ee/app,app}/assets/javascripts/**/*.{js,vue}') + .then(() => printJson()); + } + + throw new Error('ERROR: Please use the script correctly:'); +} + +main().catch((error) => { + console.warn(error.message); args.outputHelp(); process.exit(1); -} +}); diff --git a/scripts/frontend/file_test_coverage.js b/scripts/frontend/file_test_coverage.js index ec6ec4a1e9d071133a5105c851328a33766116ef..04a9035fce26964a4d41ba9fb0ad96e86b0e202d 100755 --- a/scripts/frontend/file_test_coverage.js +++ b/scripts/frontend/file_test_coverage.js @@ -31,28 +31,6 @@ let numTestFiles = 0; const isVerbose = process.argv.some((arg) => arg === '-v'); -const countSourceFiles = (path) => - forEachFileIn(path, (fileName) => { - if (fileName.endsWith('.vue') || fileName.endsWith('.js')) { - if (isVerbose) { - console.log(`source file: ${fileName}`); - } - - numSourceFiles += 1; - } - }); - -const countTestFiles = (path) => - forEachFileIn(path, (fileName) => { - if (fileName.endsWith('_spec.js')) { - if (isVerbose) { - console.log(`test file: ${fileName}`); - } - - numTestFiles += 1; - } - }); - function forEachFileIn(dirPath, callback) { fs.readdir(dirPath, (err, files) => { if (err) { @@ -75,6 +53,28 @@ function forEachFileIn(dirPath, callback) { }); } +const countSourceFiles = (currentPath) => + forEachFileIn(currentPath, (fileName) => { + if (fileName.endsWith('.vue') || fileName.endsWith('.js')) { + if (isVerbose) { + console.log(`source file: ${fileName}`); + } + + numSourceFiles += 1; + } + }); + +const countTestFiles = (currentPath) => + forEachFileIn(currentPath, (fileName) => { + if (fileName.endsWith('_spec.js')) { + if (isVerbose) { + console.log(`test file: ${fileName}`); + } + + numTestFiles += 1; + } + }); + console.log(`Source directories: ${sourceDirectories.join(', ')}`); console.log(`Test directories: ${testDirectories.join(', ')}`); diff --git a/scripts/frontend/merge_coverage_frontend.js b/scripts/frontend/merge_coverage_frontend.js index 0c45a38b9b51b6e904284243bb93bc463540ec7e..6b3826ddac75ff61d241597f8dcceb80b08ec16f 100644 --- a/scripts/frontend/merge_coverage_frontend.js +++ b/scripts/frontend/merge_coverage_frontend.js @@ -1,8 +1,8 @@ -const { create } = require('istanbul-reports'); +const { sync } = require('glob'); const { createCoverageMap } = require('istanbul-lib-coverage'); const { createContext } = require('istanbul-lib-report'); +const { create } = require('istanbul-reports'); const { resolve } = require('path'); -const { sync } = require('glob'); const coverageMap = createCoverageMap(); @@ -12,7 +12,7 @@ const reportFiles = sync(`${coverageDir}/*/coverage-final.json`); // Normalize coverage report generated by jest that has additional "data" key // https://github.com/facebook/jest/issues/2418#issuecomment-423806659 const normalizeReport = (report) => { - const normalizedReport = Object.assign({}, report); + const normalizedReport = { ...report }; Object.entries(normalizedReport).forEach(([k, v]) => { if (v.data) normalizedReport[k] = v.data; }); @@ -20,11 +20,14 @@ const normalizeReport = (report) => { }; reportFiles - .map((reportFile) => require(reportFile)) + .map((reportFile) => { + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(reportFile); + }) .map(normalizeReport) .forEach((report) => coverageMap.merge(report)); -const context = createContext({ coverageMap: coverageMap, dir: 'coverage-frontend' }); +const context = createContext({ coverageMap, dir: 'coverage-frontend' }); ['json', 'lcov', 'text-summary', 'clover', 'cobertura'].forEach((reporter) => { create(reporter, {}).execute(context); diff --git a/scripts/frontend/parallel_ci_sequencer.js b/scripts/frontend/parallel_ci_sequencer.js index d7a674535a68d2c1329d17520f7f5a298cad36fa..262e9e2256ecc790335c1747e50d1d63ad414a30 100644 --- a/scripts/frontend/parallel_ci_sequencer.js +++ b/scripts/frontend/parallel_ci_sequencer.js @@ -1,5 +1,15 @@ const Sequencer = require('@jest/test-sequencer').default; +const sortByPath = (test1, test2) => { + if (test1.path < test2.path) { + return -1; + } + if (test1.path > test2.path) { + return 1; + } + return 0; +}; + class ParallelCISequencer extends Sequencer { constructor() { super(); @@ -8,7 +18,7 @@ class ParallelCISequencer extends Sequencer { } sort(tests) { - const sortedTests = this.sortByPath(tests); + const sortedTests = [...tests].sort(sortByPath); const testsForThisRunner = this.distributeAcrossCINodes(sortedTests); console.log(`CI_NODE_INDEX: ${this.ciNodeIndex}`); @@ -19,18 +29,6 @@ class ParallelCISequencer extends Sequencer { return testsForThisRunner; } - sortByPath(tests) { - return tests.sort((test1, test2) => { - if (test1.path < test2.path) { - return -1; - } - if (test1.path > test2.path) { - return 1; - } - return 0; - }); - } - distributeAcrossCINodes(tests) { return tests.filter((test, index) => { return index % this.ciNodeTotal === this.ciNodeIndex - 1; diff --git a/scripts/frontend/stylelint/stylelint-duplicate-selectors.js b/scripts/frontend/stylelint/stylelint-duplicate-selectors.js index 89242158157a40cf8f1468a73bd043d23fbc7679..982ddf524a31514be4434130efb55e03a753371f 100644 --- a/scripts/frontend/stylelint/stylelint-duplicate-selectors.js +++ b/scripts/frontend/stylelint/stylelint-duplicate-selectors.js @@ -1,5 +1,6 @@ const stylelint = require('stylelint'); const utils = require('./stylelint-utils'); + const ruleName = 'stylelint-gitlab/duplicate-selectors'; const messages = stylelint.utils.ruleMessages(ruleName, { @@ -8,12 +9,13 @@ const messages = stylelint.utils.ruleMessages(ruleName, { }, }); -module.exports = stylelint.createPlugin(ruleName, function (enabled) { +module.exports = stylelint.createPlugin(ruleName, (enabled) => { if (!enabled) { return; } - return function (root, result) { + // eslint-disable-next-line consistent-return + return (root, result) => { const selectorGroups = {}; utils.createPropertiesHashmap(root, result, ruleName, messages, selectorGroups, true); }; diff --git a/scripts/frontend/stylelint/stylelint-utility-classes.js b/scripts/frontend/stylelint/stylelint-utility-classes.js index 1b266fc31c9cfdfd59d2ca879c79fccad0fba51d..420fe82d826f14b5da43dc01e48dc43ca2e05495 100644 --- a/scripts/frontend/stylelint/stylelint-utility-classes.js +++ b/scripts/frontend/stylelint/stylelint-utility-classes.js @@ -10,12 +10,13 @@ const messages = stylelint.utils.ruleMessages(ruleName, { }, }); -module.exports = stylelint.createPlugin(ruleName, function (enabled) { +module.exports = stylelint.createPlugin(ruleName, (enabled) => { if (!enabled) { return; } - return function (root, result) { + // eslint-disable-next-line consistent-return + return (root, result) => { utils.createPropertiesHashmap(root, result, ruleName, messages, utilityClasses, false); }; }); diff --git a/scripts/frontend/stylelint/stylelint-utility-map.js b/scripts/frontend/stylelint/stylelint-utility-map.js index bf8ee362740eb1edc06fee831d2fea8d81edd591..545aade9ccc00ebfb48834e28790f284004501cb 100644 --- a/scripts/frontend/stylelint/stylelint-utility-map.js +++ b/scripts/frontend/stylelint/stylelint-utility-map.js @@ -1,10 +1,11 @@ -const sass = require('node-sass'); -const postcss = require('postcss'); const fs = require('fs'); +const sass = require('node-sass'); const path = require('path'); +const postcss = require('postcss'); const prettier = require('prettier'); const utils = require('./stylelint-utils'); + const ROOT_PATH = path.resolve(__dirname, '../../..'); const hashMapPath = path.resolve(__dirname, './utility-classes-map.js'); @@ -22,19 +23,28 @@ sass.render( includePaths: [path.resolve(ROOT_PATH, 'node_modules/bootstrap/scss')], }, (err, result) => { - if (err) console.error('Error ', err); + if (err) { + return console.error('Error ', err); + } const cssResult = result.css.toString(); // We just use postcss to create a CSS tree - postcss([]) + return postcss([]) .process(cssResult, { // This suppresses a postcss warning from: undefined, }) - .then((result) => { + .then((processedResult) => { const selectorGroups = {}; - utils.createPropertiesHashmap(result.root, result, null, null, selectorGroups, true); + utils.createPropertiesHashmap( + processedResult.root, + processedResult, + null, + null, + selectorGroups, + true, + ); const prettierOptions = prettier.resolveConfig.sync(hashMapPath); const prettyHashmap = prettier.format( @@ -42,12 +52,12 @@ sass.render( prettierOptions, ); - fs.writeFile(hashMapPath, prettyHashmap, function (err) { - if (err) { - return console.log(err); + fs.writeFile(hashMapPath, prettyHashmap, (e) => { + if (e) { + return console.log(e); } - console.log('The file was saved!'); + return console.log('The file was saved!'); }); }); }, diff --git a/scripts/frontend/stylelint/stylelint-utils.js b/scripts/frontend/stylelint/stylelint-utils.js index e7452b0cdb28c4b4f74f7a349d9324a41e51ea80..c9d9c7d9aad579af9de79d1e1e41660047a8d284 100644 --- a/scripts/frontend/stylelint/stylelint-utils.js +++ b/scripts/frontend/stylelint/stylelint-utils.js @@ -1,5 +1,5 @@ -const stylelint = require('stylelint'); const md5 = require('md5'); +const stylelint = require('stylelint'); module.exports.createPropertiesHashmap = ( ruleRoot, @@ -15,7 +15,7 @@ module.exports.createPropertiesHashmap = ( if ( rule && rule.parent && - rule.parent.type != 'atrule' && + rule.parent.type !== 'atrule' && !( selector.includes('-webkit-') || selector.includes('-moz-') || @@ -25,7 +25,7 @@ module.exports.createPropertiesHashmap = ( ) ) { let cssArray = []; - rule.nodes.forEach(function (property) { + rule.nodes.forEach((property) => { const { prop, value } = property; if (property && value) { const propval = `${prop}${value}${property.important ? '!important' : ''}`; @@ -41,11 +41,11 @@ module.exports.createPropertiesHashmap = ( const selObj = selectorGroups[hashValue]; const selectorLine = `${selector} (${ - rule.source.input.file ? rule.source.input.file + ' -' : '' + rule.source.input.file ? `${rule.source.input.file} -` : '' }${rule.source.start.line}:${rule.source.start.column})`; if (selObj) { - if (selectorGroups[hashValue].selectors.indexOf(selector) == -1) { + if (selectorGroups[hashValue].selectors.indexOf(selector) === -1) { let lastSelector = selectorGroups[hashValue].selectors[selectorGroups[hashValue].selectors.length - 1]; @@ -67,6 +67,7 @@ module.exports.createPropertiesHashmap = ( } } } else if (addSelectors) { + // eslint-disable-next-line no-param-reassign selectorGroups[hashValue] = { selectors: [selectorLine], }; diff --git a/scripts/frontend/webpack_dev_server.js b/scripts/frontend/webpack_dev_server.js index fbb80c9617d094d6f1c61deaaa245b02d517e40f..a76e6dc024ac9611debb7fe39821e7459d0e1c95 100755 --- a/scripts/frontend/webpack_dev_server.js +++ b/scripts/frontend/webpack_dev_server.js @@ -2,8 +2,8 @@ const nodemon = require('nodemon'); const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost'; const DEV_SERVER_PORT = process.env.DEV_SERVER_PORT || '3808'; -const STATIC_MODE = process.env.DEV_SERVER_STATIC && process.env.DEV_SERVER_STATIC != 'false'; -const DLL_MODE = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_DLL != 'false'; +const STATIC_MODE = process.env.DEV_SERVER_STATIC && process.env.DEV_SERVER_STATIC !== 'false'; +const DLL_MODE = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_DLL !== 'false'; const baseConfig = { ignoreRoot: ['.git', 'node_modules/*/'], @@ -30,7 +30,7 @@ if (STATIC_MODE) { // run webpack through webpack-dev-server, optionally compiling a DLL to reduce memory else { - let watch = ['config/webpack.config.js']; + const watch = ['config/webpack.config.js']; // if utilizing the vendor DLL, we need to restart the process when dependency changes occur if (DLL_MODE) { @@ -51,7 +51,7 @@ else { // print useful messages for nodemon events nodemon - .on('start', function () { + .on('start', () => { console.log(`Starting webpack webserver on http://${DEV_SERVER_HOST}:${DEV_SERVER_PORT}`); if (STATIC_MODE) { console.log('You are starting webpack in compile-once mode'); @@ -59,10 +59,10 @@ nodemon console.log('If you change them often, you might want to unset DEV_SERVER_STATIC'); } }) - .on('quit', function () { + .on('quit', () => { console.log('Shutting down webpack process'); process.exit(); }) - .on('restart', function (files) { + .on('restart', (files) => { console.log('Restarting webpack process due to: ', files); });