Skip to content

Commit d28a0bd

Browse files
ThewBearGatsbyJS Botwardpeet
authored
feat(gatsby-plugin-typescript): Supports linting (gatsbyjs#18721)
Co-authored-by: GatsbyJS Bot <[email protected]> Co-authored-by: Ward Peeters <[email protected]>
1 parent faec9c8 commit d28a0bd

File tree

4 files changed

+172
-4
lines changed

4 files changed

+172
-4
lines changed

packages/gatsby-plugin-typescript/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,9 @@ Visual Studio Code is very good in this regard.
7777

7878
In addition, you can see the instructions in [TypeScript-Babel-Starter](https://github.com/Microsoft/TypeScript-Babel-Starter)
7979
for setting up a `type-check` task.
80+
81+
## ESLint
82+
83+
This plugin supports linting TSX with [typescript-eslint](https://typescript-eslint.io) using [Gatsby's default ESLint config](https://www.gatsbyjs.org/docs/eslint/). To enable linting TSX, install `typescript`.
84+
85+
`npm install typescript`

packages/gatsby-plugin-typescript/package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@
3333
"license": "MIT",
3434
"main": "index.js",
3535
"peerDependencies": {
36-
"gatsby": "^2.0.0"
36+
"gatsby": "^2.0.0",
37+
"typescript": "^3.2.1"
38+
},
39+
"peerDependenciesMeta": {
40+
"typescript": {
41+
"optional": true
42+
}
3743
},
3844
"repository": {
3945
"type": "git",

packages/gatsby-plugin-typescript/src/__tests__/gatsby-node.js

+120-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,22 @@ describe(`gatsby-plugin-typescript`, () => {
4949
const actions = { setWebpackConfig: jest.fn() }
5050
const jsLoader = {}
5151
const loaders = { js: jest.fn(() => jsLoader) }
52-
onCreateWebpackConfig({ actions, loaders })
52+
const stage = `develop`
53+
const eslintLoader = { loader: `eslint-loader` }
54+
const webpackConfig = {
55+
module: {
56+
rules: [
57+
{
58+
enforce: `pre`,
59+
test: /\.jsx?$/,
60+
exclude: /(node_modules|bower_components)/,
61+
use: [eslintLoader],
62+
},
63+
],
64+
},
65+
}
66+
const getConfig = jest.fn(() => webpackConfig)
67+
onCreateWebpackConfig({ actions, getConfig, loaders, stage })
5368
expect(actions.setWebpackConfig).toHaveBeenCalledWith({
5469
module: {
5570
rules: [
@@ -60,13 +75,116 @@ describe(`gatsby-plugin-typescript`, () => {
6075
],
6176
},
6277
})
78+
expect(actions.setWebpackConfig).toHaveBeenCalledWith({
79+
module: {
80+
rules: [
81+
{
82+
enforce: `pre`,
83+
test: /\.tsx?$/,
84+
exclude: /(node_modules|bower_components)/,
85+
use: [eslintLoader],
86+
},
87+
],
88+
},
89+
})
6390
})
6491

6592
it(`does not set the webpack config if there isn't a js loader`, () => {
6693
const actions = { setWebpackConfig: jest.fn() }
6794
const loaders = { js: jest.fn() }
68-
onCreateWebpackConfig({ actions, loaders })
95+
const stage = `develop`
96+
const getConfig = jest.fn()
97+
onCreateWebpackConfig({ actions, getConfig, loaders, stage })
6998
expect(actions.setWebpackConfig).not.toHaveBeenCalled()
7099
})
100+
101+
it(`does not set the typescript-eslint webpack config if the built-in eslint-loader isn't set`, () => {
102+
const actions = { setWebpackConfig: jest.fn() }
103+
const jsLoader = {}
104+
const loaders = {
105+
js: jest.fn(() => jsLoader),
106+
}
107+
const stage = `develop`
108+
const webpackConfig = {
109+
module: {
110+
rules: [
111+
{
112+
enforce: `pre`,
113+
test: /\.jsx?$/,
114+
exclude: /(node_modules|bower_components)/,
115+
use: [],
116+
},
117+
],
118+
},
119+
}
120+
const getConfig = jest.fn(() => webpackConfig)
121+
onCreateWebpackConfig({ actions, getConfig, loaders, stage })
122+
expect(actions.setWebpackConfig).toHaveBeenCalledWith({
123+
module: {
124+
rules: [
125+
{
126+
test: /\.tsx?$/,
127+
use: jsLoader,
128+
},
129+
],
130+
},
131+
})
132+
expect(actions.setWebpackConfig).not.toHaveBeenCalledWith({
133+
module: {
134+
rules: [
135+
{
136+
enforce: `pre`,
137+
test: /\.tsx?$/,
138+
exclude: /(node_modules|bower_components)/,
139+
use: [],
140+
},
141+
],
142+
},
143+
})
144+
})
145+
146+
it(`set the typescript-eslint webpack config only if in develop stage`, () => {
147+
const actions = { setWebpackConfig: jest.fn() }
148+
const jsLoader = {}
149+
const loaders = { js: jest.fn(() => jsLoader) }
150+
const stage = `build-html`
151+
const eslintLoader = { loader: `eslint-loader` }
152+
const webpackConfig = {
153+
module: {
154+
rules: [
155+
{
156+
enforce: `pre`,
157+
test: /\.jsx?$/,
158+
exclude: /(node_modules|bower_components)/,
159+
use: [eslintLoader],
160+
},
161+
],
162+
},
163+
}
164+
const getConfig = jest.fn(() => webpackConfig)
165+
onCreateWebpackConfig({ actions, getConfig, loaders, stage })
166+
expect(actions.setWebpackConfig).toHaveBeenCalledWith({
167+
module: {
168+
rules: [
169+
{
170+
test: /\.tsx?$/,
171+
use: jsLoader,
172+
},
173+
],
174+
},
175+
})
176+
expect(actions.setWebpackConfig).not.toHaveBeenCalledWith({
177+
module: {
178+
rules: [
179+
{
180+
enforce: `pre`,
181+
test: /\.tsx?$/,
182+
exclude: /(node_modules|bower_components)/,
183+
use: [eslintLoader],
184+
},
185+
],
186+
},
187+
})
188+
})
71189
})
72190
})

packages/gatsby-plugin-typescript/src/gatsby-node.js

+39-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ function onCreateBabelConfig({ actions }, options) {
1616
})
1717
}
1818

19-
function onCreateWebpackConfig({ actions, loaders }) {
19+
function onCreateWebpackConfig({
20+
actions,
21+
getConfig,
22+
loaders,
23+
stage,
24+
reporter,
25+
}) {
2026
const jsLoader = loaders.js()
2127

2228
if (!jsLoader) {
@@ -33,6 +39,38 @@ function onCreateWebpackConfig({ actions, loaders }) {
3339
],
3440
},
3541
})
42+
43+
if (stage === `develop`) {
44+
let isTypescriptDepAvailable
45+
try {
46+
isTypescriptDepAvailable = require.resolve(`typescript`)
47+
} catch (e) {
48+
reporter.warn(
49+
`"typescript" is not installed. Builtin ESLint won't be working on typescript files.`
50+
)
51+
}
52+
53+
if (isTypescriptDepAvailable) {
54+
const builtInEslintRule = getConfig().module.rules.find(rule => {
55+
if (rule.enforce === `pre`) {
56+
return rule.use.some(use => /eslint-loader/.test(use.loader))
57+
}
58+
return false
59+
})
60+
61+
if (builtInEslintRule) {
62+
const typescriptEslintRule = {
63+
...builtInEslintRule,
64+
test: /\.tsx?$/,
65+
}
66+
actions.setWebpackConfig({
67+
module: {
68+
rules: [typescriptEslintRule],
69+
},
70+
})
71+
}
72+
}
73+
}
3674
}
3775

3876
exports.resolvableExtensions = resolvableExtensions

0 commit comments

Comments
 (0)