Introduce Typescript & CSS Modules (#815)

* Adding typescript support

* Begins configuring webpack builds

* Fix lint warnings

* Updates react-router

* Fixes lint configuration

* Adds missing dependency

* Restores disabled performance hints

* Renames connectStores

* Types connectStores

* Uses correct envvars and fixes missing EOF newline

* Formats files

* Defaults props to empty object

* Ignores type definitions in eslint

* Another newline

* Adjusts script invocation

* Ignore jsdoc output

* Undoes the autoformatting of CSS module types

* Improves lint rules

* Finishes webpack config changes

* Updates deps

* Fixes lint errors and attempts to fix SVG icon generator

* Fixes SVG sprite generator

* Adds type for SVG imports

* Explicitly use babelrc in SVG loader

* Formats files

* Refactors prettier formatter, formats CSS module type defs

* Updates style types

* Uses nicer syntax in typed-css-modules-loader

* Removes unnecessary div

* optional property in package.json

* package-lock

* Fixes upstream lint errors

* Removes unused modules
This commit is contained in:
John Furrow
2019-11-22 22:47:09 -08:00
committed by GitHub
parent 459ed84ca0
commit 92404918a0
42 changed files with 3251 additions and 1228 deletions

View File

@@ -4,82 +4,105 @@ const glob = require('glob');
const path = require('path');
const prettier = require('prettier');
const filePattern = `{client,scripts,server,shared}${path.sep}!(assets){${path.sep},}{**${path.sep}*,*}.{js,json,md}`;
const SOURCE_PATTERN = `{client,scripts,server,shared}${path.sep}!(assets){${path.sep},}{**${
path.sep
}*,*}.{js,jsx,ts,tsx,json,md}`;
const iterateOverFiles = ({onFileRead}) =>
new Promise((resolve, reject) => {
glob(filePattern, (error, files) => {
if (error) {
reject(Error(error));
const readFile = filePath => {
return new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (error, fileContent) => {
if (error != null) {
reject(error);
return;
}
resolve(
Promise.all(
files.map(file => {
const filePath = path.join(process.cwd(), file);
const fileContents = fs.readFileSync(filePath, 'utf8');
return onFileRead(filePath, fileContents);
}),
),
);
resolve(fileContent);
});
});
const format = () => {
console.log(chalk.reset('Formatting files...'));
iterateOverFiles({
onFileRead: (filePath, fileContents) =>
prettier.resolveConfig(filePath).then(
options =>
new Promise((resolve, reject) => {
fs.writeFile(filePath, prettier.format(fileContents, {...options, filepath: filePath}), error => {
if (error) {
reject(error);
return;
}
resolve();
});
}),
),
})
.then(() => {
console.log(chalk.green('Done formatting files.'));
})
.catch(error => {
console.log(chalk.red('Error formatting files:\n'), chalk.reset(error));
process.exit(1);
});
};
const check = () => {
console.log(chalk.reset('Checking code formatting...'));
const writeFile = (filePath, fileContent) => {
return new Promise((resolve, reject) => {
fs.writeFile(filePath, fileContent, writeFileError => {
if (writeFileError) {
reject(writeFileError);
return;
}
iterateOverFiles({
onFileRead: (filePath, fileContents) =>
prettier.resolveConfig(filePath).then(options => {
const isCompliant = prettier.check(fileContents, {...options, filepath: filePath});
resolve(filePath);
});
});
};
const formatFile = async (inputFilePath, outputFilePath) => {
const fileContent = await readFile(inputFilePath);
const prettierConfig = await prettier.resolveConfig(inputFilePath);
const writtenFilePath = await writeFile(
outputFilePath,
prettier.format(fileContent, {...prettierConfig, filepath: inputFilePath}),
);
return writtenFilePath;
};
const getSourceFilePaths = () => {
return new Promise((resolve, reject) => {
glob(SOURCE_PATTERN, (error, files) => {
if (error) {
reject(error);
return;
}
resolve(files.map(filePath => path.join(process.cwd(), filePath)));
});
});
};
const formatSource = async () => {
console.log(chalk.reset('Formatting source files...'));
try {
const sourceFilePaths = await getSourceFilePaths();
const formattedPaths = await Promise.all(sourceFilePaths.map(filePath => formatFile(filePath, filePath)));
console.log(chalk.green(`Formatted ${formattedPaths.length} files.`));
} catch (error) {
console.log(chalk.red('Problem formatting file:\n'), chalk.reset(error));
process.exit(1);
}
};
const check = async () => {
console.log(chalk.reset('Validating source file formatting...'));
try {
const sourceFilePaths = await getSourceFilePaths();
await Promise.all(
sourceFilePaths.map(async filePath => {
const fileContent = await readFile(filePath);
const prettierConfig = await prettier.resolveConfig(filePath);
const isCompliant = prettier.check(fileContent, {...prettierConfig, filepath: filePath});
if (!isCompliant) {
throw filePath;
}
}),
})
.then(() => {
console.log(chalk.green('Done checking files.'));
})
.catch(error => {
console.log(chalk.red('Unformatted file found:\n'), chalk.reset(error));
process.exit(1);
});
);
console.log(chalk.green('Finished validating file formatting.'));
} catch (error) {
console.log(chalk.red('Unformatted file found:\n'), chalk.reset(error));
process.exit(1);
}
};
const commands = {check, format};
const commands = {check, formatSource};
const desiredCommand = process.argv.slice(2)[0];
if (commands[desiredCommand] == null) {
throw new Error(`No command ${desiredCommand}.`);
} else {
if (commands[desiredCommand] != null) {
commands[desiredCommand]();
}
module.exports = {
formatFile,
};