Skip to content

Commit

Permalink
chore: migrate tools to TypeScript (react-native-community#296)
Browse files Browse the repository at this point in the history
* Migrate tools package to Typescript

* Prebuild ts

* Improve yarn build-clean

* Remove unnecessary statements

* Fix linting

* Fix eslint

* Update packages/tools/src/isPackagerRunning.ts

Co-Authored-By: Michał Pierzchała <[email protected]>

* adjust package.json

* add vscode helper settings

* remove dead node-fetch references
  • Loading branch information
Esemesek authored and thymikee committed May 17, 2019
1 parent c2fb83f commit b03f741
Show file tree
Hide file tree
Showing 24 changed files with 367 additions and 70 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
'prettier/prettier': [2, 'fb'],
},
// @todo: remove once we cover whole codebase with types
plugins: ['eslint-plugin-import'],
plugins: ['import'],
settings: {
react: {
version: 'latest',
Expand All @@ -16,6 +16,8 @@ module.exports = {
alias: {
map: [['types', './types/index.js']],
},
// Use <rootDir>/tsconfig.json for typescript resolution
typescript: {},
},
},
overrides: [
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ package-lock.json
build/
.eslintcache
!packages/cli/src/commands/init/__fixtures__/editTemplate/node_modules
*.tsbuildinfo
10 changes: 10 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"dbaeumer.vscode-eslint",
"redhat.vscode-yaml",
"flowtype.flow-for-vscode",
"esbenp.prettier-vscode"
]
}
24 changes: 24 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"editor.rulers": [80],
"files.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/build": true
},
"editor.formatOnSave": true,
"flow.useNPMPackagedFlow": true,
"javascript.validate.enable": false,
"prettier.eslintIntegration": true,
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "typescript",
"autoFix": true
},
{
"language": "typescriptreact",
"autoFix": true
}
]
}
11 changes: 10 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
module.exports = {
babelrcRoots: ['packages/*'],
overrides: [
{
presets: ['@babel/preset-flow'],
test: '**/*.js',
},
{
presets: ['@babel/preset-typescript'],
test: '**/*.ts',
},
],
presets: [
[
require.resolve('@babel/preset-env'),
Expand All @@ -8,7 +18,6 @@ module.exports = {
useBuiltIns: 'entry',
},
],
require.resolve('@babel/preset-flow'),
],
plugins: [
require.resolve('@babel/plugin-transform-strict-mode'),
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module.exports = {
...common,
displayName: 'unit',
setupFiles: ['<rootDir>/jest/setupUnitTests.js'],
testMatch: ['<rootDir>/**/__tests__/*{.,-}test.js'],
testMatch: ['<rootDir>/**/__tests__/*{.,-}test.[jt]s'],
},
],
};
15 changes: 11 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"packages/*"
],
"scripts": {
"prebuild": "yarn build:ts",
"build": "node ./scripts/build.js",
"build-clean": "rm -rf ./packages/*/build",
"build:ts": "node ./scripts/buildTs.js",
"build-clean": "rm -rf ./packages/*/build ./packages/*/tsconfig.tsbuildinfo",
"watch": "node ./scripts/watch.js",
"test": "jest",
"test:ci:unit": "jest packages --ci --coverage",
"test:ci:e2e": "jest e2e --ci -i",
"lint": "eslint --ext .js,.ts . --cache --report-unused-disable-directives",
"test:ci:cocoapods": "ruby packages/platform-ios/native_modules.rb",
"lint": "eslint . --cache --report-unused-disable-directives",
"flow-check": "flow check",
"postinstall": "yarn build",
"publish": "yarn build-clean && yarn build && lerna publish"
Expand All @@ -22,12 +24,16 @@
"@babel/plugin-transform-strict-mode": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-flow": "^7.0.0",
"@react-native-community/eslint-config": "^0.0.3",
"@babel/preset-typescript": "^7.3.3",
"@react-native-community/eslint-config": "^0.0.5",
"@types/jest": "^24.0.11",
"@types/node": "^11.13.0",
"babel-jest": "^24.6.0",
"babel-plugin-module-resolver": "^3.2.0",
"chalk": "^2.4.2",
"eslint": "^5.10.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^1.1.1",
"eslint-plugin-import": "^2.17.0",
"execa": "^1.0.0",
"flow-bin": "^0.97.0",
Expand All @@ -38,6 +44,7 @@
"metro-memory-fs": "^0.53.1",
"micromatch": "^3.1.10",
"mkdirp": "^0.5.1",
"string-length": "^2.0.0"
"string-length": "^2.0.0",
"typescript": "^3.4.5"
}
}
1 change: 0 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"morgan": "^1.9.0",
"node-fetch": "^2.2.0",
"node-notifier": "^5.2.1",
"open": "^6.2.0",
"ora": "^3.4.0",
Expand Down
1 change: 0 additions & 1 deletion packages/platform-android/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"dependencies": {
"@react-native-community/cli-tools": "^2.0.0-alpha.20",
"logkitty": "^0.4.0",
"node-fetch": "^2.2.0",
"slash": "^2.0.0",
"xmldoc": "^0.4.0"
},
Expand Down
8 changes: 7 additions & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
"dependencies": {
"chalk": "^1.1.1",
"lodash": "^4.17.5",
"mime": "^1.3.4"
"mime": "^2.4.1",
"node-fetch": "^2.5.0"
},
"devDependencies": {
"@types/lodash": "^4.14.123",
"@types/mime": "^2.0.1",
"@types/node-fetch": "^2.3.3"
},
"files": [
"build"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

module.exports.out = () => jest.fn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @emails oncall+javascript_foundation
*/

import groupFilesByType from '../groupFilesByType';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export class CLIError extends Error {
this.stack =
typeof originError === 'string'
? originError
: originError.stack
: originError.stack ||
''
.split('\n')
.slice(0, 2)
.join('\n');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const getDefaultUserTerminal = (): ?string =>
const getDefaultUserTerminal = (): string | undefined =>
process.env.REACT_TERMINAL || process.env.TERM_PROGRAM;

export default getDefaultUserTerminal;
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,11 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import {groupBy} from 'lodash';
import mime from 'mime';

/**
* Since there are no officially registered MIME types
* for ttf/otf yet http://www.iana.org/assignments/media-types/media-types.xhtml,
* we define two non-standard ones for the sake of parsing
*/
mime.define({
'font/opentype': ['otf'],
'font/truetype': ['ttf'],
});

/**
* Given an array of files, it groups it by it's type.
* Type of the file is inferred from it's mimetype based on the extension
Expand All @@ -32,5 +21,5 @@ mime.define({
* the returned object will be: {font: ['fonts/a.ttf'], image: ['images/b.jpg']}
*/
export default function groupFilesByType(assets: Array<string>) {
return groupBy(assets, type => mime.lookup(type).split('/')[0]);
return groupBy(assets, type => (mime.getType(type) || '').split('/')[0]);
}
3 changes: 0 additions & 3 deletions packages/tools/src/index.js → packages/tools/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/**
* @flow
*/
export {default as logger} from './logger';
export {default as groupFilesByType} from './groupFilesByType';
export {default as isPackagerRunning} from './isPackagerRunning';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,17 @@ import fetch from 'node-fetch';
* - `not_running`: the packager nor any process is running on the expected port.
* - `unrecognized`: one other process is running on the port we expect the packager to be running.
*/
function isPackagerRunning(
async function isPackagerRunning(
packagerPort: string = process.env.RCT_METRO_PORT || '8081',
): Promise<'running' | 'not_running' | 'unrecognized'> {
return fetch(`http://localhost:${packagerPort}/status`).then(
res =>
res
.text()
.then(body =>
body === 'packager-status:running' ? 'running' : 'unrecognized',
),
() => 'not_running',
);
try {
const result = await fetch(`http://localhost:${packagerPort}/status`);
const body = await result.text();

return body === 'packager-status:running' ? 'running' : 'unrecognized';
} catch (_error) {
return 'not_running';
}
}

export default isPackagerRunning;
3 changes: 0 additions & 3 deletions packages/tools/src/logger.js → packages/tools/src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/**
* @flow
*/
import chalk from 'chalk';

const SEPARATOR = ', ';
Expand Down
7 changes: 7 additions & 0 deletions packages/tools/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build"
}
}
31 changes: 12 additions & 19 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,21 @@ const mkdirp = require('mkdirp');
const babel = require('@babel/core');
const chalk = require('chalk');
const micromatch = require('micromatch');
const stringLength = require('string-length');
const {PACKAGES_DIR, getPackages} = require('./helpers');
const {
PACKAGES_DIR,
getPackages,
OK,
adjustToTerminalWidth,
} = require('./helpers');

const OK = chalk.reset.inverse.bold.green(' DONE ');
const SRC_DIR = 'src';
const BUILD_DIR = 'build';
const JS_FILES_PATTERN = '**/*.js';
const TS_FILE_PATTERN = '**/*.ts';
const IGNORE_PATTERN = '**/__{tests,mocks,fixtures}__/**';

const transformOptions = require('../babel.config.js');

const adjustToTerminalWidth = str => {
const columns = process.stdout.columns || 80;
const WIDTH = columns - stringLength(OK) + 1;
const strs = str.match(new RegExp(`(.{1,${WIDTH}})`, 'g'));
let lastString = strs[strs.length - 1];
if (lastString.length < WIDTH) {
lastString += Array(WIDTH - lastString.length).join(chalk.dim('.'));
}
return strs
.slice(0, -1)
.concat(lastString)
.join('\n');
};

function getPackageName(file) {
return path.relative(PACKAGES_DIR, file).split(path.sep)[0];
}
Expand All @@ -59,7 +49,7 @@ function getBuildPath(file, buildFolder) {
const pkgSrcPath = path.resolve(PACKAGES_DIR, pkgName, SRC_DIR);
const pkgBuildPath = path.resolve(PACKAGES_DIR, pkgName, buildFolder);
const relativeToSrcPath = path.relative(pkgSrcPath, file);
return path.resolve(pkgBuildPath, relativeToSrcPath);
return path.resolve(pkgBuildPath, relativeToSrcPath).replace(/\.ts$/, '.js');
}

function buildNodePackage(p) {
Expand Down Expand Up @@ -89,7 +79,10 @@ function buildFile(file, silent) {

mkdirp.sync(path.dirname(destPath), '777');

if (!micromatch.isMatch(file, JS_FILES_PATTERN)) {
if (
!micromatch.isMatch(file, JS_FILES_PATTERN) &&
!micromatch.isMatch(file, TS_FILE_PATTERN)
) {
fs.createReadStream(file).pipe(fs.createWriteStream(destPath));
silent ||
process.stdout.write(
Expand Down
47 changes: 47 additions & 0 deletions scripts/buildTs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

const fs = require('fs');
const path = require('path');

const chalk = require('chalk');
const execa = require('execa');
const {getPackages, adjustToTerminalWidth, OK} = require('./helpers');

const packages = getPackages();

const packagesWithTs = packages.filter(p =>
fs.existsSync(path.resolve(p, 'tsconfig.json')),
);

const args = [
path.resolve(
require.resolve('typescript/package.json'),
'..',
require('typescript/package.json').bin.tsc,
),
'-b',
...packagesWithTs,
...process.argv.slice(2),
];

console.log(chalk.inverse('Building TypeScript definition files'));
process.stdout.write(adjustToTerminalWidth('Building\n'));

try {
execa.sync('node', args, {stdio: 'inherit'});
process.stdout.write(`${OK}\n`);
} catch (e) {
process.stdout.write('\n');
console.error(
chalk.inverse.red('Unable to build TypeScript definition files'),
);
console.error(e.stack);
process.exitCode = 1;
}
Loading

0 comments on commit b03f741

Please sign in to comment.