GithubHelp home page GithubHelp logo

saadq / lynt Goto Github PK

View Code? Open in Web Editor NEW
383.0 6.0 6.0 897 KB

✨ A zero config JavaScript linter with support for Typescript, Flow, and React.

License: MIT License

JavaScript 12.06% TypeScript 87.94%
linter eslint tslint javascript typescript lynt

lynt's Introduction

lynt

A zero config JavaScript linter with support for React, Flow, and Typescript.

Build Status linter: lynt style: prettier tests

Lynt has two main philosophies:

  1. Zero configuration by default. Out of the box, Lynt is a working linter and does not need any configuration. However, if you would like to add or remove rules from the default Lynt config, you have the option to do so.
  2. No style rules. Lynt is completely unopinionated when it comes to code style. It doesn't care whether or not you use semicolons, tabs or spaces, trailing commas, etc. Lynt only handles the error checking side of things and it leaves code style up to better-suited tools like prettier.

The real value of ESLint is in the non-style rules that prevent common errors.

– Nicholas C. Zakas, the creator of ESLint.


output

How It Works

Under the hood, Lynt uses ESLint and TSLint to lint your files.

It will know which linter to use as well as which rules/parsers/ignores/etc to apply based on the options you pass to it.

Installation

Make sure you have node and npm installed first.

You can install the package locally for a single project:

$ npm install lynt --save-dev

Or you can install it globally (not recommended):

$ npm install lynt --global

Usage

If you want to lint all your project files, you can just run the lynt command by itself.

Add a script to your package.json:

{
  "scripts": {
    "lint": "lynt"
  }
}

And then run the script in your terminal whenever you want to lint your code:

$ npm run lint

By default, folders like dist and node_modules are ignored.

If you only want to lint a subset of your project or individual files, you can pass globs:

{
  "scripts": {
    "lint": "lynt src/**/*.js"
  }
}

You can use flags to add support for Flow, React, or TypeScript. For example, if you were using TypeScript and React, you can set your lint script to:

{
  "scripts": {
    "lint": "lynt --typescript --react"
  }
}

You can see a full list of flags you can pass to lynt in the CLI section.

Notes on TypeScript Usage

Lynt uses TSLint to lint TypeScript files, and some TSLint rules need to get information from your project's tsconfig.json file.

If your tsconfig.json is in your root project folder, just run:

$ lynt --typescript

If your tsconfig.json file is somewhere else (for example, ./config/tsconfig.json, you can point to it with a --project flag.

$ lynt --typescript --project config

If you have lynt installed globally and are trying to use it with --typescript, you will need to make sure that you have typescript installed globally as well.

CLI

  Usage
    $ lynt [files] <options>

  Options
    --typescript   Add support for TypeScript.
    --flow         Add support for FlowType.
    --react        Add support for React.
    --ignore       Glob patterns for paths to ignore.
    --fix          Automatically fix linting issues.
    --global       Add support for a given global variable.
    --env          Add support for a given environment.
    --json         Get lint results in JSON format instead of default "stylish" format.
    --project      Specify your project's main directory if it isn't in the root (only use with --typescript).

  JavaScript Examples
    $ lynt
    $ lynt --react
    $ lynt --react --flow --env jest
    $ lynt src
    $ lynt src --ignore out/**/*.* --ignore tests/**/*.*
    $ lynt src --global chrome --global atom

  TypeScript Examples
    $ lynt --typescript
    $ lynt --typescript --react
    $ lynt --typescript --project .
    $ lynt src --typescript
    $ lynt src --typescript --ignore out/**/*.* --ignore tests/**/*.*

Configuration

You can specify your Lynt configuration in one of three ways:

  1. Use CLI flags:
$ lynt --typescript --react --ignore tests/**/*.* --ignore fixtures/**/*.*
  1. Have a "lynt" property in your package.json:
{
  "lynt": {
    "typescript": true,
    "react": true,
    "ignore": ["tests/**/*.*", "fixtures/**/*.*"]
  }
}
  1. Have a .lyntrc file in your root project folder:
{
  "typescript": true,
  "react": true,
  "ignore": ["tests/**/*.*", "fixtures/**/*.*"]
}

Rule Configuration

If you want to turn off any of the default lynt rules, or add your own custom rules, you can add a rules object in your configuration. Note that rule configuration cannot be done from the CLI, you must use a lynt property in package.json or use a .lyntrc file.

Disabling a default rule

You can set a value to 'off' to turn off a default rule.

{
  "rules": {
    "curly": "off",
    "no-unused-vars": "off"
  }
}

Adding a rule

If you want to add a rule, you can set it to on to use the rule's default setting, or set it to something more complicated.

{
  "rules": {
    "prefer-const": "on",
    "no-console": "on",
    "no-magic-numbers": ["error", { "ignore": [1] }]
  }
}

Note: Style rules will still be ignored.

API

import lynt, { format } from 'lynt'

or

const { default: lynt, format } = require('lynt')

lynt(files[, options]) => LyntResults

Uses ESLint or TSLint to lint a given set of files. Returns an array of LyntResult objects (see below to see its properties).

  • files – A string or array of strings of file paths to lint. Required.
  • options – A configuration object that lets you customize how lynt works. Optional

Here are the possible options you can pass:

{
  typescript?: boolean
  flow?: boolean
  react?: boolean
  ignore?: string | Array<string>
  fix?: boolean
  global?: string | Array<string>
  env?: string | Array<string>
  json?: string | Array<string>
  project?: string,
	rules?: {
		[ruleName: string]: any
	}
}

See the CLI section to see a detailed description of what each option is for.

Example (no options):

import lynt from 'lynt'

const results = lynt(['foo.js', 'bar.js'])
console.log(results)

Example (with options):

import lynt from 'lynt'

const options = {
  flow: true,
  react: true,
  rules: {
    'no-unused-vars': 'off'
  }
}

const results = lynt(['foo.js', 'bar.js'], options)
console.log(results)

LyntResult Example:

{
  filePath: string
  errors: Array<{
    ruleName: string
    message: string
    line: number
    column: number
    endLine?: number
    endColumn?: number
  }>
  errorCount: number
  fixCount: number
}

format(lintResults) => string

Formats an array of LyntResult objects (like the one returned from calling lynt()) into a nice looking table.

  • lintResults – An array of LyntResult objects.

Example:

import lynt, { format } from 'lynt'

const results = lynt(['foo.js', 'bar.js'])
const table = format(results)

console.log(table)

Badge

You can show off that your project uses Lynt with this badge:

linter: lynt

Just put the following in your README:

[![linter: lynt](https://img.shields.io/badge/linter-lynt-E81AAF.svg)](https://github.com/saadq/lynt)

FAQ

Why not standard or xo?

I think these are awesome projects, and I have been a user of both. I definitely drew a lot of inspiration from them – however, one the main philosophies of lynt was to be an error-checker, not a style guide. Both standard and xo are very opinionated when it comes to style. xo is actually configurable, so you can manually remove all the style rules, but it is still troublesome when trying to use it with TypeScript and Flow – with lynt it is seamless.

Are the current rules set in stone?

While lynt is still in v0.X, the rules are considered to be tentative – there will probably be rules being added in and removed. Once Lynt reaches a point where most are happy with the rules, v1 will be released and rules will change a lot less often. New rules will be added as ESLint and TSLint introduce them though and will be introduced to Lynt as a major version upgrade. However, at no point will any style rules be accepted as part of lynt.

How can I voice my opinion about some of the linting rules?

The best way would be to open up a GitHub issue and people will be able to chime in with their opinion.

Are there any editor plugins?

Unfortunately, I haven't gotten around to trying to make any yet. I can definitely use some help in this department, so if anyone would like to try to make a plugin for their favorite editor it would be greatly appreciated! Also, please let me know if there's anything I can improve with the API in order to make editor integration easier.

License

MIT

lynt's People

Contributors

andys8 avatar danielpza avatar saadq 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar

lynt's Issues

Editor plugins

Currently, there are no editor plugins :(

Need to look into how to create these for VSCode, Atom, Vim, etc

Add contributing.md

Just to make it easier for any newcomers to the project. Explain how to install/test the package, as well as giving a simple explanation of the current architecture.

Auto-detect if the user needs react, flow, or typescript support

Instead of the user needing to pass --react, --typescript, or --flow flags to lynt, I could detect this automatically.

  • Add React support/rules if the user has react in their package.json
  • Add TypeScript support/rules if the user has a tsconfig.json file in their root project folder
  • Add Flow support/rules if the user has a .flowconfig file in their root project folder

`await-promise` error on mongoose project

Hello, I'm trying lynt on a project that uses mongoose, and I got these errors when using await on a DocumentQuery type from mongoose that behaves like a promise

const user = await UserModel.findById(id);

Is there any way to go around this error

Allow configuration of rules in .lyntrc/package.json

I have been thinking on this for quite some time, and it isn't really a decision being made lightly. But I think with tools, features shouldn't be taken away unless you provide something in return. I don't think this is being done in this case.

I wanted lynt to be a zero config, easy to use tool. However, I think it can remain this way while still allowing some customization on top of it. It should work similar to Webpack v4 – Zero config by default, but the user can still customize if they want to.

This won't make it the same thing as xo though - it will still have the additional benefit of having both TSLint and ESLint support. Also, to further encourage the use of Prettier, style-only rules would not be allowed.

Curious to hear the thoughts of others on this.

ESLint compromise

There was a virus found in version 3.7.2 eslint-scope which is a dependency of babel-eslint (a package used by lynt).

However, the version of babel-eslint that lynt uses was using version 3.7.1 of eslint-scope. So, the bottom line is there was no security concern with Lynt in regards to this compromise. I just wanted to make an issue here in case anyone was concerned. I'll leave this up for a few days and then close it.

ESLint 5 Breaking Change: Globs to lint MUST be valid

I recently migrated Lynt to ESLint v5, but there was one breaking change I forgot to take account of: Linting nonexistant files from the command line is now a fatal error. If globs were not being passed to lynt (e.g. you were just doing lynt --react without specifying files to lint), I was passing in the following globs for you: ['**/*.js', '**/*.jsx']. However, this will now cause an issue with ESLint if you don't have any .jsx files because the globs that you pass in MUST exist now.

To fix this, I will need to "deglob" these default glob patterns and pass in a valid list of files to ESLint.

Vue support

Would be nice to have a --vue flag. This shouldn't be problematic on the ESLint side of things due to eslint-plugin-vue. Unfortunately, I'm not sure if this can be handled on the TSLint side of things though due to single-file components. More info about that here: palantir/tslint#2099

Due to my limited (basically zero) knowledge of Vue, I could definitely use help in this department.

Invalid "is defined but never used" errors

Example file:

import React from 'react'

class Hero extends React.PureComponent {
  render () {
    return (
      <section className='hero is-large has-bg-gray-10'>
      </section>
    )
  }
}

class Brokers extends React.PureComponent {
  render () {
    return (
      <div className='page brokers'>
        <Hero />
      </div>
    )
  }
}

export default Brokers

Lyft returns:

  3:7  'Hero' is defined but never used.  no-unused-vars

Avoid installing extra packages

In a typescript project the eslint dependencies are not needed and vice versa. I mostly use lynt for typescript and don't want to have extra dependencies even on development, the eslint configurations files are not that bad, but it also includes babel-eslint wich includes its own packages like babel-parser.
Would you consider adding an option to prevent adding eslint packages for typescript project.

I was thinking of making two extra package, lynt-ts and lynt-js, so you can opt out of using eslint in typescript projects, like

# for typescript
$ npm i lynt lynt-ts

# for js
$ npm i lynt lynt-js

I know this is an extra step but it is a short one

lynt removed all typecast type assertions

When I ran npm run lynt --typescript --fix lynt removed type assertions from across the app.

For example:
const abc: HTMLFormElement = <HTMLFormElement>nativeElement.querySelector('.xyz');
became
const abc: HTMLFormElement = nativeElement.querySelector('.xyz');

I couldn't find any rule in my tslint.json that requested this change.

I suspect some rule did this, but I couldn't find it in my tslint.json. Please comment if you know 🙇

Relax oppressive rules

Using this issue to keep a track of rules that should be removed because they are overly oppressive.

ESLint:

  • prefer-const

TSLint:

  • prefer-const
  • jsx-no-lambda
  • only-arrow-functions
  • jsx-no-multiline-js
  • no-shadowed-variable

Add a --format flag which uses Prettier

One of the main goals of lynt was to not include any style rules. To enforce consistent styling, the project highly recommends to use prettier alongside lynt. Because of this, it might be a good idea to include prettier as a dependency (or peerDependency) so that a user can just do something like:

$ lynt --format

Which will lint + run prettier on files. And doing this:

$ lynt --fix --format

will fix any lint errors and then format the output with Prettier.

I'll wait for comments from other people before I try implementing this though.

Logo

I think the current logo looks fine (font-wise), but the colors/gradient looks off to me (prob cause I suck at gfx). Could be improved.

The README badge would need to be updated with any color changes as well:

linter:lynt

Lynt v1

A Lynt v1 milestone exists so you can see which issues need to be resolved before releasing v1.

The main priority right now:

  1. Use ESLint instead of TSLint for TypeScript files
  2. Auto-detect necessary features instead of needing to pass in --react or --flow or --typescript flags
  3. Vue support
  4. Create editor plugins (VSCode to start off with)

Tslint with exportedConfig and lynt have different output

Using tslint with the generated configuration with --exportConfig doesn't show all errors lynt shows

$ npx lynt --exportConfig

✔ tslint.json generated

$ npx lynt

/home/daniel/Documents/projects/ledd/scroll-utility/test/automate/index.ts
  43:15  Invalid 'await' of a non-Promise value.  await-promise

✖ 1 lynt error

$ npx tslint -p .
{ no output }
$ 

My lynt config in package.json:

  "lynt": {
    "typescript": true,
    "react": true,
    "rules": {
      "no-console": "on"
    }
  },

Improve LyntResult example

The "LyntResult example" in the API docs currently just shows this:

{
  filePath: string
  errors: Array<{
    ruleName: string
    message: string
    line: number
    column: number
    endLine?: number
    endColumn?: number
  }>
  errorCount: number
  fixCount: number
}

Instead of just having the type, it would be nice to show an actual example of what a LyntResult object might look like.

Add jest config

React folks often use Jest. I think it would be good to add it's config by default.

I get lots of errors like:

  3:1  'describe' is not defined.  no-undef
  4:3  'test' is not defined.      no-undef

I guess better defaults would be to allow them in test files

Is this project alive?

I recently found this project and found it very appealing, I decided to add it to my dev stack right away, however then I saw that last commit is from 2019-02-23 and there is an old pull request and several pretty old open issues. So I'm wondering if this has to do with the creator not having time to maintain this or if he decided it wasn't a good idea to keep working on. I think it is BTW.

So please @saadq , could you jump in and make a tiny commit to the README.md beginning so the community can know from a glimpse if this project is a no-go or you just got stacked up with work?

I offer my help to maintain this.

Currently I'm forking it to try to make security fixes on dependencies cause npm ci spits several security issues:

$ npm ci
...
added 330 packages, and audited 331 packages in 22s

34 vulnerabilities (14 moderate, 17 high, 3 critical)

Split configs into their own packages

Split packages would be:

  • lynt
  • eslint-config-lynt
  • eslint-config-lynt-react
  • eslint-config-lynt-flow
  • tslint-config-lynt
  • tslint-config-lynt-typed
  • tslint-config-lynt-react
  • tslint-config-lynt-react-typed
  • style-rules

There are four steps to finishing this:

  • Create the ESLint related packages (with tests)
  • Rewrite the ESLint side of things to use these packages in new config and setup new tests
  • Create the TSLint related packages (with tests)
  • Rewrite the TSLint side of things to use these packages in new config and setup new tests

--strict mode

Before releasing v1, I am thinking about making lynt's rules a lot more relaxed and to truly only check for errors (this would be using @suchipi's eslint-config-unobtrusive which I had initially rejected in #1). This would mean that rules like no-var, eqeqeq, prefer-const, curly etc which aren't really checking for errors but rather check for "best practices" would be turned off. The idea is that any JS/TS codebase should be able to use lynt's default config, regardless of a person's coding style and whether they are using an ES6 codebase or not.

With the --strict flag enabled, only then are these "best practices" rules turned on. Curious to hear thoughts on this.

Add an example to api docs where typescript is used

The current API docs: https://github.com/saadq/lynt#api

There should be an example that shows how project works with the TypeScript flag. By default, if no project flag is passed and the files argument is an empty array, lynt will assume that project is in the current working directory . and will look for a tsconfig.json there.

import lynt from 'lynt'

const options = {
  typescript: true
}

const results = lynt([], options) // Will look for `./tsconfig.json` and use that to know which files to lint in the project.

A project option can be explicitly passed if tsconfig.json isn't in the current directory (like in ./config/tsconfig.json):

import lynt from 'lynt'

const options = {
  typescript: true,
  project: './config'
}

const results = lynt([], options) // Will look for `./config/tsconfig.json` and use that to know which files to lint in the project.

If files are given, a project flag should not be passed in (because it will just ignore the files and just use the tsconfig in the project to know which files to lint). However, passing files when using the typescript option will make you opt-out of some lint rules that require type information from the whole project, so passing in files is not recommended.

// Not recommended

import lynt from 'lynt'

const files = ['./foo.ts', './bar.ts']

const options = {
  typescript: true
}

const results = lynt(files, options) 

Releases and/or Change log?

Thank you for your work!
I just updated to the latest 0.3.1 from 0.2.0 and I'm sure I'm getting some goodies, but I have no idea what the changes are.

Perhaps you could add CHANGELOG.md or craft Releases -- whatever is easiest, even if you just add a single sentence per release 🙇 🙇‍♀️

Add --plugin functionality to add extra TSLint or ESLint plugins

v0.4 allows for rule overrides, however the only rules you can add on are the standard ESLint/TSLint rules as well as rules for the plugins that are shipped with lynt (eslint-plugin-flowtype, eslint-plugin-react, tslint-microsoft-contrib, and tslint-react).

What would need to be done:

  • Add a plugins field to the Options interface which would be string | Array<string>
  • Add a plugin flag to the CLI (with a plugins alias and update the help text)
  • Check if plugins exists on the options object for both ESLint and TSLint. If it exists, combine options.plugins with config.plugins.
  • Add a test in tests/config.ts (for both ESLint and TSLint) to make sure that the output config does contain options.plugins.
  • Add a test for both ESLint and TSLint in tests/api.ts that calls lynt with plugins and rules (rules from the plugin) passed to options. You can look at the other test cases as reference.

Let me know if anyone would be interested in taking this on! I'd be happy to help along the way.

Remove `no-unused-variable` in TSLint config

TSLint version >= 2.9 seems to have deprecated no-unused-variable.

...the changes in 2.9 make it much more complex for this rule to work as intended, especially with respect to the ignorePattern option.

It looks like people should now just make sure that their tsconfig.json has the noUnusedLocals option enabled which covers most of what no-unused-variable did.

Changes would need to be made here.

--watch mode

It would be nice to be able to run

lynt --watch

And to have it automatically update with lint errors whenever files change instead of needing to use a separate package such as ESLint requires with something like eslint-watch.

Some ideas from an author who is working on something similar to this project.

Hi @saadq , I'm working on a project which is similar to this project: https://github.com/g-plane/methane . So let me tell you some ideas:

  1. Use plugin-based architecture.
    As we know, both ESLint and TSLint is so large with their dependencies. When installing ESLint and TSLint at the same time, it will cost much disk space. So if this project use plugin-based architecture will bring freedom to developers. BTW, plugin-based architecture doesn't mean it needs configuration. You can still keep zero-config with plugin-based architecture, just like how my project does.

  2. Not everyone uses TypeScript and TSLint.
    Most developers use pure JavaScript so they don't use TypeScript and TSLint. When a project haven't installed TypeScript, the package manager will warn that TypeScript is a peer dependency of TSLint. It's noisy.


And, as what I said above, my project is also a linter wrapper which is similar to this project lynt, so I can provide some help as I have some experience on this. For example, we could use a better linter formatter which is used in my project:

Thanks.

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.