Skip to content

Commit

Permalink
Adds typescript support via babel and updated configs (#25)
Browse files Browse the repository at this point in the history
Adds typescript support via babel and updated configs
  • Loading branch information
Jacob Wejendorp authored Nov 12, 2019
2 parents 1d538e5 + 9f6a5d4 commit 109dd88
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 64 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8
12
61 changes: 30 additions & 31 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,50 +30,53 @@
"author": "Kent C. Dodds <[email protected]> (http://kentcdodds.com/)",
"license": "MIT",
"dependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.4.4",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/cli": "^7.7.0",
"@babel/core": "^7.7.2",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.6.2",
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
"@babel/plugin-transform-modules-commonjs": "^7.0.0",
"@babel/plugin-transform-modules-commonjs": "^7.7.0",
"@babel/plugin-transform-runtime": "^7.6.2",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.6.3",
"@semantic-release/error": "^2.0.0",
"@babel/preset-env": "^7.7.1",
"@babel/preset-react": "^7.7.0",
"@babel/preset-typescript": "^7.7.2",
"@babel/runtime": "^7.7.2",
"@semantic-release/error": "^2.2.0",
"@typescript-eslint/eslint-plugin": "^2.6.1",
"@typescript-eslint/parser": "^2.6.1",
"arrify": "^2.0.1",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.8.0",
"babel-jest": "^24.9.0",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-plugin-macros": "^2.3.0",
"babel-plugin-minify-dead-code-elimination": "^0.5.0",
"babel-plugin-module-resolver": "^3.1.1",
"babel-plugin-macros": "^2.6.1",
"babel-plugin-minify-dead-code-elimination": "^0.5.1",
"babel-plugin-module-resolver": "^3.2.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"babel-plugin-transform-react-remove-prop-types": "^0.4.13",
"browserslist": "^4.1.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"browserslist": "^4.7.2",
"concurrently": "^5.0.0",
"cross-env": "^6.0.3",
"cross-spawn": "^7.0.1",
"doctoc": "^1.3.0",
"doctoc": "^1.4.0",
"env-ci": "^4.5.1",
"eslint": "^6.6.0",
"eslint-config-tradeshift": "^6.2.1",
"eslint-plugin-react": "^7.10.0",
"eslint-config-tradeshift": "^6.3.0",
"eslint-plugin-react": "^7.16.0",
"execa": "^3.2.0",
"glob": "^7.1.2",
"husky": "^0.14.3",
"jest": "^24.8.0",
"jest": "^24.9.0",
"jest-junit": "^6.4.0",
"lint-staged": "^9.4.2",
"lodash.camelcase": "^4.3.0",
"lodash.has": "^4.5.2",
"lodash.merge": "^4.6.0",
"lodash.merge": "^4.6.2",
"mkdirp": "^0.5.1",
"npmlog": "^4.1.2",
"prettier": "^1.12.1",
"prettier": "^1.18.2",
"read-pkg-up": "^7.0.0",
"resolve": "^1.4.0",
"resolve": "^1.12.0",
"rimraf": "^3.0.0",
"rollup": "^0.66.0",
"rollup-plugin-babel": "^4.0.3",
Expand All @@ -86,21 +89,16 @@
"rollup-watch": "^4.3.1",
"semver": "^6.3.0",
"which": "^2.0.1",
"yargs-parser": "^10.0.0"
"yargs-parser": "^10.1.0"
},
"eslintIgnored": [
"node_modules",
"coverage",
"dist"
],
"eslintConfig": {
"extends": [
"tradeshift",
"tradeshift/jest"
],
"extends": "./src/config/eslintrc",
"rules": {
"no-useless-catch": 0,
"no-prototype-builtins": 0,
"jest/no-jest-import": 0
}
},
Expand All @@ -113,6 +111,7 @@
},
"homepage": "https://github.com/wejendorp/tradeshift-scripts#readme",
"devDependencies": {
"jest-in-case": "^1.0.2"
"jest-in-case": "^1.0.2",
"typescript": "^3.7.0"
}
}
}
8 changes: 8 additions & 0 deletions src/__tests__/helpers/dummy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class IAmTypes<T> {
v: T;
value(): T {
return this.v;
}
}

export default 1;
7 changes: 7 additions & 0 deletions src/__tests__/syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ describe('jest', () => {
expect(data.name).toEqual(pkg.name);
});
});

it('supports optional chaining operator', () => {
const o = { a: { b: { c: 'see' } } };
expect(o?.a?.b?.c).toEqual('see');
expect(o?.a?.z?.c).toEqual(undefined);
});

it('supports nullish-coalescing-operator', () => {
const o = { a: 'foo', c: null };
expect(o.b ?? 'default').toEqual('default');
expect(o.c ?? 'default').toEqual('default');
});

it('supports class properties', () => {
class ClassExample {
instanceProperty = 'bork';
Expand All @@ -25,4 +28,8 @@ describe('jest', () => {
expect(i.instanceProperty).toEqual('bork');
expect(ClassExample.staticProperty).toEqual('babelIsCool');
});

it('supports typescript imports', () => {
expect(require('./helpers/dummy').default).toEqual(1);
});
});
6 changes: 4 additions & 2 deletions src/config/babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const isRollup = parseEnv('BUILD_ROLLUP', false);
const isUMD = BUILD_FORMAT === 'umd';
const isCJS = BUILD_FORMAT === 'cjs';
const isWebpack = parseEnv('BUILD_WEBPACK', false);
const treeshake = parseEnv('BUILD_TREESHAKE', isRollup || isWebpack);
const isESM = parseEnv('BUILD_ESM', false);
const treeshake = parseEnv('BUILD_TREESHAKE', isESM || isRollup || isWebpack);
const alias = parseEnv('BUILD_ALIAS', isPreact ? { react: 'preact' } : null);

const hasBabelRuntimeDep = Boolean(pkg.dependencies && pkg.dependencies['@babel/runtime']);
Expand Down Expand Up @@ -44,7 +45,8 @@ module.exports = () => ({
ifAnyDep(
['react', 'preact'],
[require.resolve('@babel/preset-react'), { pragma: isPreact ? 'React.h' : undefined }]
)
),
ifAnyDep(['typescript'], require.resolve('@babel/preset-typescript'))
].filter(Boolean),
plugins: [
[require.resolve('@babel/plugin-transform-runtime'), { useESModules: treeshake && !isCJS }],
Expand Down
1 change: 1 addition & 0 deletions src/config/eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
extends: [
require.resolve('eslint-config-tradeshift'),
require.resolve('eslint-config-tradeshift/jest'),
ifAnyDep('typescript', require.resolve('eslint-config-tradeshift/typescript')),
ifAnyDep('react', 'plugin:react/recommended')
].filter(Boolean)
};
8 changes: 4 additions & 4 deletions src/config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const ignores = ['/node_modules/', '/fixtures/', '/__tests__/helpers/', '__mocks
const jestConfig = {
roots: [fromRoot('src')],
testEnvironment: ifAnyDep(['webpack', 'rollup', 'react'], 'jsdom', 'node'),
collectCoverageFrom: ['src/**/*.js'],
testMatch: ['**/__tests__/**/*.js', '**/*.spec.js'],
collectCoverageFrom: ['src/**/*.[jt]s?(x)'],
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+spec.[jt]s?(x)'],
testPathIgnorePatterns: [...ignores],
coveragePathIgnorePatterns: [...ignores, 'src/(umd|cjs|esm)-entry.js$'],
coveragePathIgnorePatterns: [...ignores, 'src/(umd|cjs|esm)-entry.[jt]s$'],
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
reporters: ['default', [require.resolve('jest-junit'), junitConfig]],
coverageThreshold: {
Expand All @@ -32,7 +32,7 @@ const jestConfig = {
};

if (useBuiltInBabelConfig) {
jestConfig.transform = { '^.+\\.js$': here('./babel-transform') };
jestConfig.transform = { '^.+\\.[jt]s$': here('./babel-transform') };
}

module.exports = jestConfig;
8 changes: 7 additions & 1 deletion src/config/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const filepath = path.join(...[filenamePrefix, 'dist', filename].filter(Boolean)

const useBuiltinConfig = !hasFile('.babelrc') && !hasFile('.babelrc.js') && !hasPkgProp('babel');
const babelPresets = useBuiltinConfig ? [here('../config/babelrc.js')] : [];
const extensions = ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts', '.tsx'];

module.exports = {
input,
Expand All @@ -70,7 +71,12 @@ module.exports = {
plugins: [
isNode ? nodeBuiltIns() : null,
isNode ? nodeGlobals() : null,
nodeResolve({ preferBuiltins: isNode, jsnext: true, main: true }),
nodeResolve({
preferBuiltins: isNode,
jsnext: true,
main: true,
extensions: [...extensions, '.json']
}),
commonjs({ include: 'node_modules/**' }),
json(),
rollupBabel({
Expand Down
20 changes: 10 additions & 10 deletions src/scripts/__tests__/__snapshots__/lint.js.snap
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`format --no-cache will disable caching 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --no-cache .`;
exports[`format --no-cache will disable caching 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --ext .js,.ts --no-cache .`;

exports[`format calls eslint CLI with default args 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --cache .`;
exports[`format calls eslint CLI with default args 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --cache --ext .js,.ts .`;

exports[`format does not use built-in config with .eslintrc file 1`] = `eslint --ignore-path ./src/config/eslintignore --cache .`;
exports[`format does not use built-in config with .eslintrc file 1`] = `eslint --ignore-path ./src/config/eslintignore --cache --ext .js,.ts .`;

exports[`format does not use built-in config with .eslintrc.js file 1`] = `eslint --ignore-path ./src/config/eslintignore --cache .`;
exports[`format does not use built-in config with .eslintrc.js file 1`] = `eslint --ignore-path ./src/config/eslintignore --cache --ext .js,.ts .`;

exports[`format does not use built-in config with --config 1`] = `eslint --ignore-path ./src/config/eslintignore --cache --config ./custom-config.js .`;
exports[`format does not use built-in config with --config 1`] = `eslint --ignore-path ./src/config/eslintignore --cache --ext .js,.ts --config ./custom-config.js .`;

exports[`format does not use built-in config with eslintConfig pkg prop 1`] = `eslint --ignore-path ./src/config/eslintignore --cache .`;
exports[`format does not use built-in config with eslintConfig pkg prop 1`] = `eslint --ignore-path ./src/config/eslintignore --cache --ext .js,.ts .`;

exports[`format does not use built-in ignore with .eslintignore file 1`] = `eslint --config ./src/config/eslintrc.js --cache .`;
exports[`format does not use built-in ignore with .eslintignore file 1`] = `eslint --config ./src/config/eslintrc.js --cache --ext .js,.ts .`;

exports[`format does not use built-in ignore with --ignore-path 1`] = `eslint --config ./src/config/eslintrc.js --cache --ignore-path ./my-ignore .`;
exports[`format does not use built-in ignore with --ignore-path 1`] = `eslint --config ./src/config/eslintrc.js --cache --ext .js,.ts --ignore-path ./my-ignore .`;

exports[`format does not use built-in ignore with eslintIgnore pkg prop 1`] = `eslint --config ./src/config/eslintrc.js --cache .`;
exports[`format does not use built-in ignore with eslintIgnore pkg prop 1`] = `eslint --config ./src/config/eslintrc.js --cache --ext .js,.ts .`;

exports[`format runs on given files, but only js files 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --cache ./src/index.js ./src/component.js`;
exports[`format runs on given files, but only js files 1`] = `eslint --config ./src/config/eslintrc.js --ignore-path ./src/config/eslintignore --cache --ext .js,.ts ./src/index.js ./src/component.js`;
2 changes: 0 additions & 2 deletions src/scripts/__tests__/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ cases(
const [firstCall] = crossSpawnSyncMock.mock.calls;
const [script, calledArgs] = firstCall;
expect([script, ...calledArgs].join(' ')).toMatchSnapshot();
} catch (error) {
throw error;
} finally {
teardown();
// afterEach
Expand Down
2 changes: 0 additions & 2 deletions src/scripts/__tests__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ cases(
const [firstCall] = jestRunMock.mock.calls;
const [jestArgs] = firstCall;
expect(jestArgs.join(' ')).toMatchSnapshot();
} catch (error) {
throw error;
} finally {
teardown();
// afterEach
Expand Down
2 changes: 0 additions & 2 deletions src/scripts/__tests__/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ cases(
const [firstCall] = crossSpawnSyncMock.mock.calls;
const [script, calledArgs] = firstCall;
expect([script, ...calledArgs].join(' ')).toMatchSnapshot();
} catch (error) {
throw error;
} finally {
teardown();
}
Expand Down
7 changes: 4 additions & 3 deletions src/scripts/build/babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ const useBuiltinConfig =
!hasPkgProp('babel');
const config = useBuiltinConfig ? ['--presets', here('../../config/babelrc.js')] : [];

const builtInIgnore = '**/__tests__/**,**/__mocks__/**';

const builtInIgnore = '__tests__,__mocks__,**/*.spec.js,**/*.spec.ts';
const ignore = args.includes('--ignore') ? [] : ['--ignore', builtInIgnore];

const extensions = args.includes('--extensions') ? [] : ['--extensions', '.js,.jsx,.ts,.tsx'];

const copyFiles = args.includes('--no-copy-files') ? [] : ['--copy-files'];

const useSpecifiedOutDir = args.includes('--out-dir');
Expand All @@ -34,7 +35,7 @@ if (!useSpecifiedOutDir && !args.includes('--no-clean')) {

const result = spawn.sync(
resolveBin('@babel/cli', { executable: 'babel' }),
[...outDir, ...copyFiles, ...ignore, ...config, 'src'].concat(args),
[...outDir, ...copyFiles, ...extensions, ...ignore, ...config, 'src'].concat(args),
{ stdio: 'inherit' }
);

Expand Down
5 changes: 3 additions & 2 deletions src/scripts/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const useBuiltinIgnore =
const ignore = useBuiltinIgnore ? ['--ignore-path', hereRelative('../config/eslintignore')] : [];

const cache = args.includes('--no-cache') ? [] : ['--cache'];
const extensions = args.includes('--ext') ? [] : ['--ext', '.js,.ts'];

const filesGiven = parsedArgs._.length > 0;

Expand All @@ -31,12 +32,12 @@ if (filesGiven) {
// we need to take all the flag-less arguments (the files that should be linted)
// and filter out the ones that aren't js files. Otherwise json or css files
// may be passed through
args = args.filter(a => !parsedArgs._.includes(a) || a.endsWith('.js'));
args = args.filter(a => !parsedArgs._.includes(a) || a.endsWith('.js') || a.endsWith('.ts'));
}

const result = spawn.sync(
resolveBin('eslint'),
[...config, ...ignore, ...cache, ...args, ...filesToApply],
[...config, ...ignore, ...cache, ...extensions, ...args, ...filesToApply],
{ stdio: 'inherit' }
);

Expand Down
7 changes: 4 additions & 3 deletions src/scripts/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ const scripts = useDefaultScripts
build: ifScript('build', 'npm run build --silent'),
lint: precommit ? null : ifScript('lint', 'npm run lint --silent'),
test: precommit ? null : ifScript('test', 'npm run test --silent -- --coverage'),
flow: ifScript('flow', 'npm run flow --silent')
}
flow: ifScript('flow', 'npm run flow --silent'),
typecheck: ifScript('typecheck', 'npm run typecheck --silent')
}
: validateScripts.split(',').reduce((scriptsToRun, name) => {
scriptsToRun[name] = `npm run ${name} --silent`;
return scriptsToRun;
}, {});
}, {});

const result = spawn.sync(resolveBin('concurrently'), getConcurrentlyArgs(scripts), {
stdio: 'inherit'
Expand Down
6 changes: 5 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ const ifAnyDep = (deps, t, f) => (hasAnyDep(deps) ? t : f);
const ifScript = ifPkgSubProp('scripts');

function parseEnv(name, def) {
if (process.env.hasOwnProperty(name) && process.env[name] && process.env[name] !== 'undefined') {
if (
Object.prototype.hasOwnProperty.call(process.env, name) &&
process.env[name] &&
process.env[name] !== 'undefined'
) {
return JSON.parse(process.env[name]);
}
return def;
Expand Down

0 comments on commit 109dd88

Please sign in to comment.