Giter VIP home page Giter VIP logo

styleguide-javascript's People

Contributors

dependabot[bot] avatar svengreb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

styleguide-javascript's Issues

Monorepo with ESLint packages

Current Project State

Currently this repository only contains the actual styleguide documentation while specific projects that implement the guidelines for linters and code style analyzer live in separate repositories. This is the best approach for modularity and a small and clear code base, but it increases the maintenance overhead by 1(n) since changes to the development workflow or toolbox, general project documentations as well as dependency management requires changes in every repository with dedicated tickets/issues and PRs. In particular, Node packages require frequent dependency management due to their fast development cycles to keep up-to-date with the latest package changes like (security) bug fixes.

This styleguide is currently implemented by the eslint-config-arcticicestudio-base and eslint-config-arcticicestudio Node packages living in their own repositories. The development workflow is clean using most of GitHub's awesome features like project boards, codeowner assignments, issue & PR automation and so on, but changes to one of them often requires actions for the other package too since they are based on each other and they are using the same development tooling and documentation standards.

Monorepo Comparison

Monorepos are a fantastic way to manage such a project structure, but there are also some points that must be taken into account:

  • No more scoped code — the developer experience with Git is slightly worse because commits can contains changes to multiple scopes of the code. Since there is only a “transparent separation” of code, that was previously located in a dedicated repository but is not aggregated into a parent (e.g. packages) with other modules, commits can now contain changes to multiple code scopes spread over the entire code base.
  • No more assignment of commits to single modules — like described in the bullet point above, commit can contain changes to multiple modules, it is harder to detect which commit targeted a specific module.
  • Steeper learning curve for new contributors — in a dedicated repository that only hosts a specific module it is easier for new developers to contribute to the project, but in a monorepo they might need to change code in multiple places within other modules or the root code/documentation of the entire project.
  • Uniform version number — in order to keep conform to SemVer, the entire project must use a uniform version number. This means that a module that has not been changed since the last version must also be incremented in order to keep compatible with the other modules.
    Using different version numbers prefixed/suffixed with an individual version number is a not an option, increases the maintenance overhead and and drastically reduces the project overview and quality! This would result in multiple Git tags on the main branch as well as “empty” changelogs and release notes with placeholder logs that only refer to changes of other modules.

Project Future

Even though a monorepo requires some special thoughts, it also comes with a lot of benefits and makes sense for specific project modules that are slightly coupled and where using dedicated repositories only increases the maintenance overhead when changes must be reflected in multiple modules anyway.

In order to reduce the maintenance overhead both Node packages, eslint-config-arcticicestudio-base and eslint-config-arcticicestudio, will be migrated into this repository by adapting to Yarn workspaces. This simplifies the development tooling setup and allows to use a unified documentation base as well as a smoother development and testing workflow.

This change also implies that the root of the repository will be the main package for the entire project setup including shared development dependencies, tools and documentations while the packages will only contain specific configurations and (dev)dependencies.

Scoped Packages

Currently eslint-config-arcticicestudio-base and eslint-config-arcticicestudio are no scoped packages but suffixed with -arcticicestudio*. To simplify the naming and improving the usage of user/organization specific packages both packages will be scoped to @arcticicestudio resulting in the new names @arcticicestudio/eslint-config-base and @arcticicestudio/eslint-config. They can be used through ESLint's support for shared configuration with scoped packages.
The currently released public versions will be deprecated using the npm deprecate command where the provided message will point out to migrate to the new scoped packages.

Versioning

The style guide itself and all packages will use a shared/fixed/locked version. This helps all packages to keep in sync and ensure the compatibility with the latest style guide version.

Standard Setup

In order to keep up-to-date with the latest project setup for all Arctic Ice Studio projects, the tools and documentations will be integrated and updated through the following tickets:

  • #9 (⊶ 8e99240) „Git ignore and attribute pattern“ — completed ✓
  • #10 (⊶ db2a43b) „Git mail mapping“ — completed ✓
  • #11 (⊶ 1025324) „Prettier“ — completed ✓
  • #12 (⊶ c21a58a) „lint-staged“ — completed ✓
  • #13 (⊶ b4cac34) „Husky“ — completed ✓
  • #14 (⊶ be122b1) „General repository and package documentations and metadata“ — completed ✓
  • #15 (⊶ c25d1ef) „GitHub issue and pull request templates“ — completed ✓

Loop on TypeScript configuration override

In #32 the @arcticicestudio/eslint-config-typescript package migrated to the latest plugin versions and added the override field to its index to simplify the usage for consumers by removing the need to explicitly define it per project. Unfortunately this results in a crash loop when doing so and also blocks users from overriding single rules based on the project needs.

To fix this problem, the override field will be removed again, leaving it up to the user to define and customize the ESLint configuration for TypeScript to fit the project needs.

Git mail mapping

Epic: #8

Add a Git mailmap file to link to in documentations to allow contributors to send mails regarding security issues. This prevents unnecessary overhead of updating all documents when new core team and members and contributors are added and additionally adds the main functionality of the file: Mapping commits when someone uses a different email address.

Migrate to `@arcticicestudio/remark-preset-lint`

The currently used remark-preset-lint-arcticicestudio package has been deprecated during the migration into a monorepo and replaced by the new @arcticicestudio/remark-preset-lint package. This package also introduces support for remark 13.0.0 which comes with some new features and great improvements.

To migrate to the new package the currently remark-preset-lint-arcticicestudio preset will be replaced by the new @arcticicestudio/remark-preset-lint preset in the .remarkrc.js file.

Base Rules

Design and write the base rule set.

Chapters

  • Accessors
  • Arrays
  • Arrow Functions
  • Blocks
  • Classes & Constructors
  • Commas
  • Comments
  • Comparison Operators & Equality
  • Control Statements
  • Destructuring
  • ECMAscript 5 Compatibility
  • ECMAscript 6+ Styles
  • Events
  • Functions
  • Hoisting
  • Iterators & Generators
  • Modules
  • Naming Conventions
  • Objects
  • Properties
  • References
  • Semicolons
  • Standard Library
  • Strings
  • Testing
  • Type Casting & Coercion
  • Types
  • Variables
  • Whitespace

From CircleCI to GitHub Actions

Project State

The current project setup uses CircleCI with API version 2.x as CI/CD service. This works great, but also comes with the disadvantage of being decoupled from the repository.

The GitHub Actions CI/CD UI

During GitHub Universe 2018, the awesome new GitHub Actions feature was introduced and launched as closed beta. Luckily Arctic Ice Studio was given access in order to test all the great possibilities. During the GitHub Actions stream „Now with built-in CI/CD!“ (live from GitHub HQ) the Actions update was announced and previewed showing the expansion to use GitHub Actions as CI/CD service described as „fast CI/CD for any OS, any language, and any cloud“.

Live logs showing real-time feedback

See the official GitHub Actions documentation for details about setups, features, the configuration API and many more!

Project Integration

The switch from CircleCI to GitHub Actions brings many advantages like a „close-to-the-source“ development pipeline. Having the code and automated pipelines/workflows in one place is worth a lot. This also comes along with the perfect and smooth integrations into GitHub platform and page itself like status reports on PRs and many more possibilities like the customization and triggering of workflows through webhooks for almost every event that can occur in a repository/issue/PR etc.

To integrate GitHub Actions the current CircleCI build configuration will be adapted and adjusted. The official starter-workflows can be used as inspiration as well as showcase projects like Yarn Berry (Yarn v2) also presented during the announcement livestream.

Next to the starter-workflows repository the official GitHub Actions documentation will be the main source of information to set up the project workflows.

GitHub Actions starter workflows based on the epository languages

Since GitHub Actions are still in closed/limited public beta, there is no support for SVG badges through shields.io. Anyway, there are (currently undocumented) official badges provided by the GitHub API that'll be used until Actions goes GA_ and shields.io implements support for it: https://github.com/{owner}/{repo}/workflows/{workflow_name}/badge.svg

Migrate to ESLint major version `8`

The currently supported ESLint major version for all npm packages of this styleguide is still 7 which has been updated to 8, released on 2021-10-09.
To update all packages, the official ESLint 8 migration guide will be used to adapt the breaking changes for users, but none of them affects this project so there are no further steps required other than updating the corresponding package (dev/peer)dependencies.

The following plugins will be updated to their latest major & minor versions to match the supported ESLint version:

  • eslint^7.32.0major version 8 · currently latest version is ^8.39.0 which will be used as minimal requirement.
  • eslint-plugin-prettier^3.4.1major version 4 · currently latest version is 4.2.1 which will be used as minimal requirement.
    • Dropped support for older versions of ESLint, Prettier and Node. It now requires at least ESLint >=7.28.0 <8.0.0, Prettier >=2.0.0 <3.0.0 and Node >=12.0.0.
  • eslint-find-rules3.6.1major version 4 · currently latest version is 4.1.0 which will be used as minimal requirement.
    • Comes with support for ESLint 8.
  • @typescript-eslint/eslint-plugin^4.33.0major version 5 · currently latest version is 5.59.1 which will be used as minimal requirement.
    • Comes with support for ESLint 8.
    • Dropped support for Node <=10.
    • Dropped support for ESLint <=5.
  • @typescript-eslint/parser^4.33.0major version 5 · currently latest version is 5.59.1 which will be used as minimal requirement.
    • Comes with support for ESLint 8.
    • Dropped support for Node <=10.
    • Dropped support for ESLint <=5.
  • typescript^4.9.5major version 5 · currently latest version is 5.0.4 which will be used as minimal requirement.
    • Dropped support for Node <=12.

Allow `void` operator as a statement for React Hooks

To run async code in a React useEffect Hook the official React Hook FAQ section about how to fetch data recommends and shows in a demo how to define a scoped fat arrow function and run it immediately. Unfortunately this collides with the @typescript/no-floating-promises rule because the returned Promise of the called function must not be handled anymore.

useEffect(() => {
  const init = async () => {
    try {
      const data = await fetchData();
      setInitialized(isInit);
      if (data) initStores(data);
    } catch (err) {
      handleError(err);
    }
  };
  // This will trigger the "@typescript/no-floating-promises" rule because the returned "Promise" is not handled.
  init();
}, [fetchData, handleError, initStores, setInitialized]);

Explicitly disabling the rule for these specific code lines would be an option, but it is recommended to use the void operator instead.

// ...
// This will trigger the "no-void" rule because the "void" operator is currently not allowed as a statement.
void init();
// ...

However, the no-void rule currently does not allow the void operator to be used as statement which will result in this rule to also throw an error.
To resolve both problems, the allowAsStatement option of the no-void rule will be enabled.

Also see typescript-eslint/typescript-eslint#1184 where this solution is also recommended by one of the @typescript-eslint package maintainers.

General repository and package documentations and metadata

Epic: #8

The current project repository documentations are not designed for a monorepo layout and will be updated including various badges provided by the great shields.io project.

Further documentations about the project architecture and technologies as well as guides for contributions to develop, run and maintain the project will stay within the packages itself. Minimal instructions might be added later on within a “Getting Started” / “Quick Start” section.

There are also various places that contain outdated documentations and metadata that need to be updated too.

Tasks

  • Update outdated documentations and metadata like copyright comment headers.
  • Add a new .yarnrc configuration file to set the save-prefix option in order to resolve always install and resolve exact dependency versions.
  • Add @svengreb as core team contributor to the CODEOWNERS file.
  • Update project repository SVG assets using GitHub's new sanitize=true query parameter to allow rendering SVG's hosted within the repository and served via the raw.githubusercontent subdomain.
  • Add shields.io badges for
    • latest GitHub release version and changelog
    • deployed ESLint package versions and statistics (downloads)
    • GitHub Actions CI/CD status

Node support and entry point

In ESLint v7 many rules related to Node have been deprecated and moved into eslint-plugin-node.

The @arcticicestudio/eslint-config-base package already includes support for Node, but enabling eslint-plugin-node by default is not an option. Instead it will be available through a shareable configuration entry point that

The new entry point will be available as @arcticicestudio/eslint-config/node and can be composed with all other available entry points to inherit their rules.
This feature will add the eslint-plugin-node package as new peer dependency for @arcticicestudio/eslint-config.

Update ESLint and plugins

ESLint and most of the used plugins already released new major versions. Trying to use later versions of these plugins as well as ESLint itself causes error when using npm v7 because peer dependencies are installed automatically now, which is a fantastic change, but also breaks and blocks the usage of the configuration packages due to outdated peerDependencies like eslint@^6.

Core

The latest version 7 comes with great features and improvements.
See the official v7 migration guide for all details.

Plugins & Dependencies

@arcticicestudio/eslint-config

@arcticicestudio/eslint-config-base

@arcticicestudio/eslint-config-typescript

React Rules

Design and write the rule set for React.

Chapters

  • Accessibility A11Y
  • Blocks
  • Classes & Constructors
  • Higher-Order Components
  • Methods
  • Naming Conventions
  • Ordering
  • Props
  • Strings
  • Tags
  • Whitespace

ESLint TypeScript Configuration Package

To support projects build with TypeScript, a new @arcticicestudio/eslint-config-typescript package will be implemented using the awesome @typescript-eslint project. It will mainly extend @typescript-eslint/eslint-plugin's already provided and recommended configurations in order to adapt best practices:

  1. plugin:@typescript-eslint/eslint-recommended
  2. plugin:@typescript-eslint/recommended
  3. plugin:@typescript-eslint/recommended-requiring-type-checking

The @typescript-eslint/parser will be set as ESLint parser. As of @typescript-eslint/parser version 2.0.0 (also see typescript-eslint/typescript-eslint#890), the parser will panic when parsing files that are not included within the provided tsconfig(s).
The documentation of the new package will contain instructions and a quick setup and usage guide to inform about the required tsconfig configurations and the corresponding eslintrc changes.

Next to the support for TypeScript, the package will also modify some React and import related rules in order to prevent conflicts, like the adaption of the .ts and .tsx extensions for all JS and JSX files as well as removing .jsx to force the usage of .tsx. There are other rules that'll be disabled like the check for valid React prop-types since these and not necessary anymore when working with TypeScript.

The new package will provide two entry points, available as @arcticicestudio/eslint-config-typescript (main) and @arcticicestudio/eslint-config-typescript/prettier that can both be composed with all other available entry points to inherit their rules.

This package will mainly depend on the @typescript-eslint/eslint-plugin@^2.0.0 and @typescript-eslint/parser@^2.0.0 packages as peer dependencies.

Invalid usage of `prettier/@typescript-eslint` configuration

As of eslint-config-prettier version 8.0.0 all configurations have been merged into the prettier configuration that now includes not just ESLint core rules, but also rules from all plugins.
In #32 the eslint-config-prettier version was bumped from version v6.0.0 to v8.1.0, but the @arcticicestudio/eslint-config-typescript package still explicitly extends the prettier/@typescript-eslint configuration which results in an error when consuming the package.

To fix this problem, the prettier/@typescript-eslint will be removed entirely from the extend field, leaving only the all-in-one prettier configuration.

Support TypeScript triple-slash directives

TypeScript uses triple-slash directives (single-line comments containing a single XML tag) to define compiler directives. The @arcticicestudio/eslint-config-base configures the ESLint core rule spaced-comment and already defines exceptions and comment markers for special use cases, but does not support triple-slash directives yet. When running eslint --fix these comments in *.d.ts files get malformed (///// /) which results in invalid TypeScript syntax.

To support triple-slash directives, the / marker will be added to the line field.

Prettier

Epic: #8

Integrate Prettier, the opinionated code formatter with support for many languages and integrations with most editors. It ensures that all outputted code conforms to a consistent style.

Configuration

This is one of the main features of Prettier: It already provides the best and recommended style configurations of-out-the-box™.
The only option we will change is the print width. It is set to 80 by default which not up-to-date for modern screens (might only be relevant when working in terminals only like e.g. with Vim). It'll be changed to 120 used by all of Arctic Ice Studio's style guides.
The prettier.config.js configuration file will be placed in the project root as well as the .prettierignore file to also define ignore pattern.

NPM script/task

To allow to format all sources a format:pretty npm script/task will be added to be included in the main format script flow.

False-Positives

To ensure incorrect examples of the style guide won't be fixed by Prettier, the affected lines must be excluded from Prettier by adding the <!-- prettier-ignore --> handle for HTML.
Note that this might trigger remark-lint when added right above a code block (no-missing-blank-lines). This can also be fixed by adding the <!--lint disable no-missing-blank-lines--> handle as well.

Tasks

  • Install prettier packages.
  • Implement prettier.config.js configuration file.
  • Implement .prettierignore ignore pattern file.
  • Implement NPM format:pretty script/task.
  • Format current code base for the first time and fix possible style guide violations using the configured linters of the project.
  • Ensure compatibility with Prettier (#11) by adding required ignore/disable handles for Prettier and remark-lint.

Markdown style guide and linter

Integrate remark-lint which is built on remark, the powerful Markdown processor powered by plugins such as remark-lint.

Ensuring the markdown you (and contributors) write is of great quality will provide better rendering in all the different markdown parsers, and makes sure less refactoring is needed afterwards.

remark-lint can be used through remark-cli through a preset. This preset will be remark-preset-lint-arcticicestudio, the custom preset that implements the Arctic ice Studio Markdown Style Guide.

Since the custom preset is still in major version 0 note that the version range should be >=0.x.x <1.0.0 to avoid NPM's “SemVer Major Zero Caveat”. When defining package versions with the the carat ^ or tilde ~ range selector it won't affect packages with a major version of 0. NPM will resolve these packages to their exact version until the major version is greater or equal to 1.
To avoid this caveat the more detailed version range >=0.x.x <1.0.0 should be used to resolve all versions greater or equal to 0.x.x but less than 1.0.0. This will always use the latest 0.x.x version and removes the need to increment the version manually on each new release.

Configuration

The .remarkrc.js configuration file will be placed in the project root as well as the .remarkignore file to also define ignore pattern.

NPM script/task

To allow to run the Markdown linting separately a lint:md npm script/task will be added to be included in the main lint script flow.

Tasks

  • Install remark-cli and remark-preset-lint-arcticicestudio packages to devDependencies.
  • Implement .remarkrc.js configuration file.
  • Implement .remarkignore ignore pattern file.
  • Implement npm lint:md script/task.
  • Lint current code base for the first time and fix possible Markdown style guide violations.

Update Node package dependencies & GitHub Action versions

In #32 all ESLint packages and dependencies have been updated to the latest version.
This issue updates all repository development packages and GitHub Actions to the latest versions and adapts to the changes:

GitHub issue and pull request templates

GitHub provides a feature to define multiple issue templates.

The initial template file that has been used when the feature was introduced can now be used as a fallback/generic template.

The UI helps users to open a new issue in projects by prompting them to choose from multiple issue types.

See the GitHub Help for more details about issue and pull request templates. Also check out how to manually create issue templates and a pull request template. There's also a guide on how to create the (deprecated) fallback/generic issue template.

Husky

Epic: #8
Must be resolved after #12

Integrate Husky, the tool that make Git hooks easy and can prevent bad Git commits, pushes and more 🐶 woof!

Configuration

The configuration file .huskyrc.js will be placed in the project root and includes the command to run for any supported Git hook. It will at least contain configs for the following hooks:

  • pre-commit - Run lint-staged (#12) before each commit (via lint-staged command) to ensure all staged files are compliant to all style guides.

Tasks

  • Install husky package.
  • Implement .huskyrc.js configuration file.

React Hooks support and entry point

All React based Arctic Ice Studio projects using at least React version 16.8 that introduced the awesome Hooks. Since this comes with a entire new API that follows new design/usage pattern, the React team created an official „Hooks“ ESLint plugin to help to adhere to the „Rules of Hooks“.

Since the @arcticicestudio/eslint-config package already includes support for React and „JSX A11Y“, support for Hooks will also be added through a new shareable configuration entry point that

  • enables the react-hooks plugin.
  • configures both currently available rules react-hooks/rules-of-hooks and react-hooks/exhaustive-deps rule to error level.

Because Hooks make more use of arrow functions the react/jsx-no-bind will be adjusted to prevent compatibility problems by allowing setting the ignoreDOMComponents and allowArrowFunctions options to true.
The react/display-name rule will also be disabled in order to prevent problems due to missing display names for functional components that make use of Hooks instead of being created through a class component.

The new entry point will be available as @arcticicestudio/eslint-config/react-hooks and can be composed with all other available entry points to inherit their rules.

This feature will add the eslint-plugin-react-hooks package as new peer dependency for @arcticicestudio/eslint-config.

lint-staged

Epic: #8
Must be resolved after #11

Integrate lint-staged to run linters against staged Git files to prevent to add code that violates any style guide into the code base.

Configuration

The configuration file lint-staged.config.js will be placed in the project root and includes the command that should be run for matching file extensions (globs). It will include at least the three following entries with the same order as listed here:

  1. prettier --list-different - Run Prettier (#11) against *.{js,json,yml} to ensure all files are formatted correctly. The --list-different prints the found files that are not conform to the Prettier configuration.
  2. eslint - Run ESLint against *.{js} to ensure all JavaScript files are compliant to the style guide after being formatted with Prettier.
  3. remark --no-stdout - Run remark-lint against *.md to ensure all Markdown files are compliant to the style guide. The --no-stdout flag suppresses the output of the parsed file content.

Tasks

  • Install lint-staged package.
  • Implement lint-staged.config.js configuration file.

Move ESLint Prettier support into base package

Currently eslint-plugin-prettier and its corresponding eslint-config-prettier package are supported by the @arcticicestudio/eslint-config rule preset package. This works fine for most projects, but also pulls in React specific dependencies like eslint-plugin-react and eslint-plugin-jsx-a11y.
To allow to use Prettier without @arcticicestudio/eslint-config, the support will be moved into the @arcticicestudio/eslint-config-base package, including the optional entry point.

`svengreb` GitHub account and `@svengreb` npm package scope migration

With the retirement of the Arctic Ice Studio personal & Nord project brand this project will also move to the real-in-person identity “Sven Greb“ both in the context of the repository to the svengreb GitHub account and the @svengreb npm package scope.
During this migration the current npm packages @arcticicestudio/eslint-config-base, @arcticicestudio/eslint-config and @arcticicestudio/eslint-config-typescript will be deprecated in favor of the new and upcoming @svengreb/eslint-config-base, @svengreb/eslint-config and @svengreb/eslint-config-typescript packages that will be published afterwards.

Also the current visual representation of this style guide through the way too outdated and deprecated GitBook major version 2 will be unpublished and removed. The documentations and references will be updated to use the GitHub repository with the Markdown rendering instead for now until a custom website has been implemented using a modern TechStack like Next.js.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.