{"id":3645,"date":"2021-04-13T15:54:58","date_gmt":"2021-04-13T15:54:58","guid":{"rendered":"https:\/\/ionicframework.com\/blog\/?p=3645"},"modified":"2021-04-13T16:54:19","modified_gmt":"2021-04-13T16:54:19","slug":"eslint-for-ionic-angular","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular","title":{"rendered":"ESLint for Ionic Angular"},"content":{"rendered":"<p>Today I&#8217;m happy to share that <a href=\"https:\/\/github.com\/ionic-team\/starters\/pull\/1675\">Ionic&#8217;s starter projects now ship<\/a> with modern linting, powered by <a href=\"https:\/\/eslint.org\">ESLint<\/a>. This gives us a consistent linting tool across all project types, but also removes a deprecated dependency. Let&#8217;s dive in and rewind the clock to 2018.<\/p>\n<h2>Sunsetting TSLint<\/h2>\n<p>If you were looking for a linting tool for a <a href=\"https:\/\/www.typescriptlang.org\">TypeScript<\/a> project, chances are you ended up using <a href=\"https:\/\/palantir.github.io\/tslint\/\">TSLint<\/a>. TSLint was a static analysis tool that would check a TypeScript code base to enforce a consistent code style and make sure the project didn&#8217;t break any rules, aka your standard linting tool. Now, TSLint isn&#8217;t the only tool in this space. Another linting tool that was the de facto standard in JavaScript projects was ESLint. ESLint and TSLint provided a similar set of features, but ESLint didn&#8217;t have support for TypeScript.<\/p>\n<p>Fast forward to 2019, and the landscape was starting to look different. The TypeScript community was looking to improve the tooling landscape and provide a more unified experience for TypeScript and JavaScript devs. The maintainers of TSLint took this opportunity to announce the deprecation of TSLint and plans to help support ESLint as <strong>the<\/strong> linter for both TypeScript and JavaScript.<\/p>\n<p>Now in 2021, the TSLint repo has been archived and the <a href=\"https:\/\/github.com\/typescript-eslint\/typescript-eslint\">TypeScript-ESLint<\/a> team, headed up by <a href=\"https:\/\/twitter.com\/MrJamesHenry\">James Henry<\/a> and others, have been working to support developers.<\/p>\n<p><!--more--><\/p>\n<h2>From one linting tool to another<\/h2>\n<p>With the history listed out of the way, let&#8217;s upgrade a project to use ESLint. This process can be done manually, but why do that when we can automate it. For most projects, the quickest way to upgrade is to use <a href=\"https:\/\/github.com\/angular-eslint\/angular-eslint\">Angular-ESLint<\/a> and run their schematics. First commit any open changes and make a new branch (just to be sure):<\/p>\n<pre><code class=\"language-bash\">git add .\ngit commit -m &quot;pre eslint&quot;\ngit checkout -b feat-eslint\n<\/code><\/pre>\n<p>Then we can add the schematics for Angular-ESLint<\/p>\n<pre><code class=\"language-bash\">ng add @angular-eslint\/schematics\n<\/code><\/pre>\n<p>From here, we can convert our existing TSLint config to ESLint with the following command:<\/p>\n<pre><code class=\"language-bash\">ng g @angular-eslint\/schematics:convert-tslint-to-eslint {{YOUR_PROJECT_NAME_GOES_HERE}}\n<\/code><\/pre>\n<p>Once this is done, you can run ESLint against your project! The schematic won\u2019t remove TSLint from your package.json or the tslint.json from your project. These can be removed:<\/p>\n<pre><code class=\"language-bash\">rm tslint.json\nnpm uninstall tslint\n<\/code><\/pre>\n<p>Commit your changes and make send one sweet pull request!<\/p>\n<h2>Where do we go now?<\/h2>\n<p>With ESLint installed and configured, projects can make use of the extensive ecosystem of plugins available, like Prettier. With new Ionic Angular projects using ESLint, you can rest assured knowing you will have stable tools for the future of your development. A huge thank you to <a href=\"https:\/\/twitter.com\/MrJamesHenry\">James Henry<\/a> and <a href=\"https:\/\/github.com\/bradzacher\">Brad Zacher<\/a> for building and maintaining TypeScript-ESLint and Angular-ESLint.<\/p>\n<ul>\n<li><a href=\"https:\/\/eslint.org\">ESLint<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/typescript-eslint\/typescript-eslint\">TypeScript-ESLint<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/angular-eslint\/angular-eslint\">Angular-ESLint<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Today I&#8217;m happy to share that Ionic&#8217;s starter projects now ship with modern linting, powered by ESLint. This gives us a consistent linting tool across all project types, but also removes a deprecated dependency. Let&#8217;s dive in and rewind the clock to 2018. Sunsetting TSLint If you were looking for a linting tool for a [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":3647,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"0","publish_post_category":"27","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"502859","discourse_permalink":"https:\/\/forum.ionicframework.com\/t\/eslint-for-ionic-angular\/208095","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[120],"tags":[60,207,7],"class_list":["post-3645","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcements","tag-angular","tag-linting","tag-tools"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>ESLint for Ionic Angular - Ionic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ESLint for Ionic Angular\" \/>\n<meta property=\"og:description\" content=\"Today I&#8217;m happy to share that Ionic&#8217;s starter projects now ship with modern linting, powered by ESLint. This gives us a consistent linting tool across all project types, but also removes a deprecated dependency. Let&#8217;s dive in and rewind the clock to 2018. Sunsetting TSLint If you were looking for a linting tool for a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-13T15:54:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-13T16:54:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"880\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Mike Hartington\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mhartington\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mike Hartington\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\"},\"author\":{\"name\":\"Mike Hartington\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b\"},\"headline\":\"ESLint for Ionic Angular\",\"datePublished\":\"2021-04-13T15:54:58+00:00\",\"dateModified\":\"2021-04-13T16:54:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\"},\"wordCount\":427,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png\",\"keywords\":[\"Angular\",\"Linting\",\"Tools\"],\"articleSection\":[\"Announcements\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\",\"url\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\",\"name\":\"ESLint for Ionic Angular - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png\",\"datePublished\":\"2021-04-13T15:54:58+00:00\",\"dateModified\":\"2021-04-13T16:54:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png\",\"width\":1600,\"height\":880},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ESLint for Ionic Angular\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b\",\"name\":\"Mike Hartington\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png\",\"caption\":\"Mike Hartington\"},\"description\":\"Director of Developer Relations\",\"sameAs\":[\"https:\/\/twitter.com\/mhartington\",\"https:\/\/x.com\/mhartington\"],\"url\":\"https:\/\/ionic.io\/blog\/author\/mike\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"ESLint for Ionic Angular - Ionic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular","og_locale":"en_US","og_type":"article","og_title":"ESLint for Ionic Angular","og_description":"Today I&#8217;m happy to share that Ionic&#8217;s starter projects now ship with modern linting, powered by ESLint. This gives us a consistent linting tool across all project types, but also removes a deprecated dependency. Let&#8217;s dive in and rewind the clock to 2018. Sunsetting TSLint If you were looking for a linting tool for a [&hellip;]","og_url":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular","og_site_name":"Ionic Blog","article_published_time":"2021-04-13T15:54:58+00:00","article_modified_time":"2021-04-13T16:54:19+00:00","og_image":[{"width":1600,"height":880,"url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","type":"image\/png"}],"author":"Mike Hartington","twitter_card":"summary_large_image","twitter_creator":"@mhartington","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Mike Hartington","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular"},"author":{"name":"Mike Hartington","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b"},"headline":"ESLint for Ionic Angular","datePublished":"2021-04-13T15:54:58+00:00","dateModified":"2021-04-13T16:54:19+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular"},"wordCount":427,"commentCount":0,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"image":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","keywords":["Angular","Linting","Tools"],"articleSection":["Announcements"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular","url":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular","name":"ESLint for Ionic Angular - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage"},"image":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","datePublished":"2021-04-13T15:54:58+00:00","dateModified":"2021-04-13T16:54:19+00:00","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/eslint-for-ionic-angular"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#primaryimage","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","width":1600,"height":880},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/eslint-for-ionic-angular#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"ESLint for Ionic Angular"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b","name":"Mike Hartington","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png","caption":"Mike Hartington"},"description":"Director of Developer Relations","sameAs":["https:\/\/twitter.com\/mhartington","https:\/\/x.com\/mhartington"],"url":"https:\/\/ionic.io\/blog\/author\/mike"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/04\/feature-image.png","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/3645","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=3645"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/3645\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media\/3647"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=3645"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=3645"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=3645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}