Skip to content

Commit 8573066

Browse files
authored
feat(dev-tools): Add typescript build support (#372)
1 parent 18e1995 commit 8573066

22 files changed

+271
-140
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
modules/dev-tools/test/ts-smoosh/

.eslintrc.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ const defaultConfig = getESLintConfig({react: '16.8.2'});
66

77
// We are importing ourselves
88
const config = deepMerge(defaultConfig, {
9+
parserOptions: {
10+
project: ['./tsconfig.json']
11+
},
12+
913
rules: {
1014
'import/no-extraneous-dependencies': 0,
1115
'no-console': 0,
@@ -17,10 +21,10 @@ const config = deepMerge(defaultConfig, {
1721
node: true
1822
},
1923

20-
ignorePatterns: ['modules/gatsby-theme-ocular', 'modules/dev-tools/test/ts-smoosh/fixtures']
24+
ignorePatterns: ['modules/gatsby-theme-ocular']
2125
});
2226

2327
// Uncomment to log the eslint config
24-
// console.debug(config);
28+
// console.debug(JSON.stringify(config, null, 2));
2529

2630
module.exports = config;

.markdownlintrc

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"default": true,
3+
"colors": true,
4+
"line-length": false,
5+
"ul-style": {"style": "sublist"},
6+
"no-duplicate-header": false,
7+
"no-inline-html": false,
8+
"no-hard-tabs": false,
9+
"whitespace": false
10+
}

.ocularrc.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ let ocularConfig = {
88
},
99

1010
lint: {
11-
paths: ['modules'],
12-
extensions: ['js', 'jsx']
11+
paths: ['modules']
1312
},
1413

1514
aliases: {

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
Ocular is a monorepo for development tools primarily designed for building github-based javascript frameworks.
44

55
It currently contains:
6+
67
- `gatsby-theme-ocular` - A documentation generator packaged as a pluggable theme for gatsbyjs documentation generation system.
78
- `ocular-dev-tools` - A set tools that packages up extensive installation and configuration of babel, webpack, lint, prettier and other state-of-the art JS build tools.
8-

.babelrc.js babel.config.js

File renamed without changes.

modules/dev-tools/package.json

+23-19
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,34 @@
4444
"test": "echo Please help add tests"
4545
},
4646
"dependencies": {
47-
"@babel/cli": "^7.8.7",
48-
"@babel/core": "^7.8.7",
49-
"@babel/plugin-transform-runtime": "^7.8.7",
50-
"@babel/preset-env": "^7.8.7",
51-
"@babel/preset-react": "^7.12.13",
52-
"@babel/preset-typescript": "^7.13.0",
53-
"@babel/runtime": "7.12.0",
54-
"@typescript-eslint/eslint-plugin": "^4.14.1",
55-
"@typescript-eslint/parser": "^4.14.1",
56-
"babel-eslint": "^10.1.0",
47+
"@babel/cli": "^7.14.5",
48+
"@babel/core": "^7.14.5",
49+
"@babel/eslint-parser": "^7.14.5",
50+
"@babel/plugin-proposal-class-properties": "^7.14.5",
51+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2",
52+
"@babel/plugin-proposal-optional-chaining": "^7.14.2",
53+
"@babel/preset-env": "^7.14.5",
54+
"@babel/preset-react": "^7.14.5",
55+
"@babel/preset-typescript": "^7.14.5",
56+
"@babel/register": "^7.14.5",
57+
"@babel/runtime": "7.14.5",
58+
"@typescript-eslint/eslint-plugin": "^4.26.1",
59+
"@typescript-eslint/parser": "^4.26.1",
5760
"babel-loader": "8.2.2",
58-
"babel-plugin-istanbul": "^5.0.0",
61+
"babel-plugin-istanbul": "^6.0.0",
5962
"babel-plugin-version-inline": "^1.0.0",
63+
"core-js": "^3.2.1",
6064
"deepmerge": "^4.2.2",
61-
"eslint-plugin-babel": "^5.3.1",
62-
"eslint-plugin-import": "^2.22.1",
63-
"eslint-plugin-react": "^7.22.0",
64-
"eslint": "^7.24.0",
65-
"eslint-plugin-jsx-a11y": "^6.1.2",
65+
"eslint": "^7.28.0",
6666
"eslint-config-airbnb": "^18.0.1",
6767
"eslint-config-prettier": "^6.7.0",
6868
"eslint-config-uber-es2015": "^3.0.0",
6969
"eslint-config-uber-jsx": "^3.3.3",
70-
"eslint-plugin-markdown": "^1.0.2",
70+
"eslint-plugin-babel": "^5.3.1",
71+
"eslint-plugin-import": "^2.22.1",
72+
"eslint-plugin-jsx-a11y": "^6.1.2",
73+
"eslint-plugin-markdown": "^2.2.0",
74+
"eslint-plugin-react": "^7.22.0",
7175
"glob": "^7.1.4",
7276
"handlebars": "^4.1.2",
7377
"html-webpack-plugin": "^3.2.0",
@@ -83,10 +87,10 @@
8387
"tape-catch": "^1.0.4",
8488
"tape-promise": "^4.0.0",
8589
"typescript": "^4.2.3",
90+
"webpack": "^4.28.4",
8691
"webpack-bundle-analyzer": "^3.0.3",
8792
"webpack-cli": "^3.2.1",
88-
"webpack-dev-server": "^3.1.14",
89-
"webpack": "^4.28.4"
93+
"webpack-dev-server": "^3.1.14"
9094
},
9195
"dependencies-webpack4-comment": {
9296
"webpack-bundle-analyzer": "^4.4.1",

modules/dev-tools/scripts/bootstrap.sh

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ yarn global add puppeteer
88
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true yarn
99

1010
# update browserlist database
11+
echo "Updating browserlist"
1112
npx browserslist@latest --update-db
1213

1314
# prepare module directories

modules/dev-tools/src/configuration/get-babel-config.js

+28-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,26 @@ const DEFAULT_CONFIG = {
99
comments: false
1010
};
1111

12+
const COMMON_PRESETS = [
13+
// Accepts typescript syntax
14+
// Note that this still has limits (requires typescript isolated modules)
15+
'@babel/preset-typescript'
16+
];
17+
18+
const COMMON_PLUGINS = [
19+
// webpack 4 cannot parse the most recent JS syntax
20+
'@babel/plugin-proposal-optional-chaining',
21+
'@babel/plugin-proposal-nullish-coalescing-operator',
22+
// typescript syntax supports the class properties proposal,
23+
// but we also need to let babel know how to transpile these
24+
'@babel/plugin-proposal-class-properties'
25+
];
26+
1227
const ENV_CONFIG = {
28+
// fully transpiled build
1329
es5: {
1430
presets: [
31+
...COMMON_PRESETS,
1532
[
1633
'@babel/env',
1734
{
@@ -20,10 +37,12 @@ const ENV_CONFIG = {
2037
}
2138
]
2239
],
23-
plugins: ['@babel/transform-runtime']
40+
plugins: [...COMMON_PLUGINS, '@babel/transform-runtime']
2441
},
42+
// es module style build
2543
esm: {
2644
presets: [
45+
...COMMON_PRESETS,
2746
[
2847
'@babel/env',
2948
{
@@ -32,18 +51,24 @@ const ENV_CONFIG = {
3251
}
3352
]
3453
],
35-
plugins: [['@babel/transform-runtime', {useESModules: true}]]
54+
plugins: [
55+
...COMMON_PLUGINS,
56+
// TODO - we likely do not need runtime transforms for the esm setting
57+
['@babel/transform-runtime', {useESModules: true}]
58+
]
3659
},
60+
// coverage build (node only)
3761
test: {
3862
presets: [
63+
...COMMON_PRESETS,
3964
[
4065
'@babel/preset-env',
4166
{
4267
targets: 'maintained node versions'
4368
}
4469
]
4570
],
46-
plugins: ['istanbul']
71+
plugins: [...COMMON_PLUGINS, 'istanbul']
4772
}
4873
};
4974

@@ -58,7 +83,5 @@ module.exports.getBabelConfig = function getBabelConfig(api, options = {}) {
5883
if (options.react) {
5984
config.presets.push('@babel/preset-react');
6085
}
61-
// TODO add flag?
62-
config.presets.push('@babel/preset-typescript');
6386
return config;
6487
};

modules/dev-tools/src/configuration/get-eslint-config.d.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@
22
* Returns a default eslint config
33
* @param options.react - to enable React linting, supply a string specifying your React version, e.g. "16.8.2"
44
*/
5-
export function getESLintConfig(options?: {
6-
react?: string;
7-
}): {[key: string]: any};
5+
export function getESLintConfig(options?: {react?: string}): {[key: string]: any};

modules/dev-tools/src/configuration/get-eslint-config.js

+67-13
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ const DEFAULT_OPTIONS = {
77
const DEFAULT_CONFIG = {
88
extends: ['uber-es2015', 'prettier', 'prettier/react', 'plugin:import/errors'],
99
plugins: ['import'],
10-
parser: 'babel-eslint',
10+
parser: '@babel/eslint-parser',
1111
parserOptions: {
12-
ecmaVersion: 2020
12+
ecmaVersion: 2020,
13+
// @babel/eslint-parser issues https://github.com/babel/babel/issues/11975
14+
requireConfigFile: false,
15+
babelOptions: {
16+
configFile: './babel.config.js'
17+
}
1318
},
1419
env: {
1520
// Note: also sets ecmaVersion
@@ -30,44 +35,93 @@ const DEFAULT_CONFIG = {
3035
'import/no-unresolved': ['error'],
3136
'import/no-extraneous-dependencies': ['error', {devDependencies: false, peerDependencies: true}]
3237
},
38+
settings: {
39+
// Ensure eslint finds typescript files
40+
'import/resolver': {
41+
node: {
42+
extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts']
43+
}
44+
}
45+
},
3346
ignorePatterns: ['node_modules', '**/dist*/**/*.js'],
3447
overrides: [
3548
{
3649
// babel-eslint can process TS files, but it doesn't understand types
3750
// typescript-eslint has some more advanced rules with type checking
38-
files: ['**/*.ts', '**/*.tsx'],
51+
files: ['**/*.ts', '**/*.tsx', '**/*.d.ts'],
3952
parser: '@typescript-eslint/parser',
4053
parserOptions: {
4154
sourceType: 'module', // we want to use ES modules
4255
project: './tsconfig.json'
4356
},
4457
plugins: ['@typescript-eslint'],
4558
rules: {
46-
...typescriptConfigs['eslint-recommended'].rules,
47-
...typescriptConfigs.recommended.rules,
48-
...typescriptConfigs['recommended-requiring-type-checking'].rules,
59+
// Standard rules
60+
61+
// We still have some issues with import resolution
62+
'import/named': 0,
63+
'import/no-extraneous-dependencies': ['warn'],
64+
// Warn instead of error
65+
'max-params': ['warn'],
66+
'no-undef': ['warn'],
67+
camelcase: ['warn'],
4968
indent: ['warn', 2, {SwitchCase: 1}],
5069
quotes: ['warn', 'single'],
5170
'no-process-env': 'off',
52-
'@typescript-eslint/no-unused-vars': ['warn'],
53-
'@typescript-eslint/no-explicit-any': 0,
54-
'@typescript-eslint/switch-exhaustiveness-check': ['error'],
71+
72+
// typescript rules
73+
74+
...typescriptConfigs['eslint-recommended'].rules,
75+
...typescriptConfigs.recommended.rules,
76+
...typescriptConfigs['recommended-requiring-type-checking'].rules,
77+
5578
// Some of JS rules don't always work correctly in TS and
5679
// hence need to be reimported as TS rules
5780
'no-redeclare': 'off',
58-
'@typescript-eslint/no-redeclare': ['warn'],
5981
'no-shadow': 'off',
60-
'@typescript-eslint/no-shadow': ['warn'],
6182
'no-use-before-define': 'off',
62-
'@typescript-eslint/no-use-before-define': ['error'],
6383
'no-dupe-class-members': 'off',
64-
'@typescript-eslint/no-dupe-class-members': ['error']
84+
85+
// TODO - These rules are sometimes not found?
86+
// '@typescript-eslint/no-shadow': ['warn'],
87+
// '@typescript-eslint/no-redeclare': ['warn'],
88+
89+
// We use function hoisting to put exports at top of file
90+
'@typescript-eslint/no-use-before-define': 'off',
91+
'@typescript-eslint/no-dupe-class-members': ['error'],
92+
93+
// We encourage explicit typing, e.g `field: string = ''`
94+
'@typescript-eslint/no-inferrable-types': 'off',
95+
96+
'@typescript-eslint/no-empty-interface': ['warn'],
97+
'@typescript-eslint/restrict-template-expressions': ['warn'],
98+
'@typescript-eslint/explicit-module-boundary-types': ['warn'],
99+
'@typescript-eslint/require-await': ['warn'],
100+
'@typescript-eslint/no-unsafe-return': ['warn'],
101+
'@typescript-eslint/no-unsafe-call': ['warn'],
102+
103+
// some day we will hopefully be able to enable this rule
104+
'@typescript-eslint/no-explicit-any': 'off',
105+
'@typescript-eslint/ban-ts-comment': ['warn'],
106+
'@typescript-eslint/ban-types': ['warn'],
107+
'@typescript-eslint/no-unsafe-member-access': ['warn'],
108+
'@typescript-eslint/no-unsafe-assignment': ['warn'],
109+
'@typescript-eslint/no-var-requires': ['warn'],
110+
'@typescript-eslint/no-unused-vars': ['warn'],
111+
'@typescript-eslint/switch-exhaustiveness-check': ['error'],
112+
'@typescript-eslint/no-floating-promises': ['warn'],
113+
'@typescript-eslint/await-thenable': ['warn'],
114+
'@typescript-eslint/no-misused-promises': ['warn'],
115+
'@typescript-eslint/restrict-plus-operands': ['warn'],
116+
'@typescript-eslint/no-empty-function': ['warn']
65117
}
66118
},
67119
{
68120
// We can lint through code examples in Markdown as well,
69121
// but we don't need to enable all of the rules there
70122
files: ['**/*.md'],
123+
plugins: ['markdown'],
124+
// extends: 'plugin:markdown/recommended',
71125
rules: {
72126
'no-undef': 'off',
73127
'no-unused-vars': 'off',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Returns a default NYC config
3+
*/
4+
export function getNYCConfig(): {[key: string]: any};
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
// export type WebpackConfigOptions = {
2+
// webpackVersion?: number;
3+
// }
4+
15
/**
26
* Returns a default webpack configuration object
37
* @param env this is a webpack parameter that should just be passed through
48
* @param options application options controlling the generated configuration
5-
*/
9+
*/
610
export function getWebpackConfig(env?: {[key: string]: any}, options?: {}): {[key: string]: any};

0 commit comments

Comments
 (0)