-
-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor to Modern Typescript + TSLint + Prettier #34
base: master
Are you sure you want to change the base?
Conversation
7379eee
to
d0457f2
Compare
"precommit": "lint-staged", | ||
"prepush": "npm run type-check", | ||
"prettier": "npm run prettier", | ||
"type-check": "tsc --noEmit --pretty", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since webpack now handles compilation output, tsc
is only used for type-checking. Note that webpack reads in the tsconfig.json
file for its settings.
@@ -3,18 +3,50 @@ | |||
"version": "1.0.0", | |||
"description": "gtr-cof", | |||
"scripts": { | |||
"clean": "rm -rf docs/scripts", | |||
"build:dist": "NODE_ENV=production webpack", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will produce a production-ready, minified JS bundle
import * as d3 from "d3" | ||
import * as events from "./events-module" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to not change the source-code too much, I used wildcard imports throughout. If wanted tho, could refactor this and pluck out individual exports like
import { chordIntervalChange } from './events-module'
|
||
const svg = d3.select("#modes") | ||
const intervals = svg.append("g").attr("transform", "translate(0, 240)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TSLint swapped out all let
s that aren't reassigned to const
. In modern JS code this is used for safety since a const
, if attempting to be reassigned, will throw an error.
{ tuning: "GDAE", dots: guitarDots, description: "Violin" }, | ||
{ tuning: "CGDA", dots: guitarDots, description: "Viola" }, | ||
] | ||
const tunings: TuningInfo[] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another example of an automatic TSLint --fix
change: TuningInfo[]
is preferred over Array<TuningInfo>
.
"downlevelIteration": true, | ||
"lib": ["dom", "es2015", "es2016", "es2017"], | ||
"module": "es2015", | ||
"moduleResolution": "node", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes interfacing with libraries from NPM more natural.
d0457f2
to
7e165e1
Compare
tsconfig.json
Outdated
"include": ["typings/*.d.ts", "src/**/*.ts"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a typings
folder for dealing with webmidi types, which I'm not sure why are not being picked up from @types
. I'm sure this can be refactored out (perhaps by adding @types/webmidi
to the types
config item in `tsconfig) but for now was added to satisfy the type checker.
(EDIT, answered my own question -- needed to be added to types
array)
"class-name": false, | ||
"interface-name": false, | ||
"member-access": false, | ||
"object-literal-sort-keys": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These rules were added so that I didn't have to refactor code unnecessarily. I would recommend at the minimum turning on only-arrow-functions
-- function
brings with it this
and all of its baggage, and so arrow functions tend to simplify and make code more functional. The other values should also be turned on, but will require light code modifications.
typings/webmidi.d.ts
Outdated
// Project: http://www.w3.org/TR/webmidi/ | ||
// Definitions by: six a <https://github.com/lostfictions> | ||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | ||
interface Navigator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These d.ts
files were copied over from @types
to satisfy the type-checker. They can be removed at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(No longer needed; see #34 (comment))
const { NODE_ENV = "development" } = process.env | ||
|
||
module.exports = { | ||
mode: NODE_ENV, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mode
can be development
or production
. If production -- read from NODE_ENV
-- code will minify
mode: NODE_ENV, | ||
devtool: "sourcemap", | ||
entry: "./src/index.ts", | ||
stats: "errors-only", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your curious about stats around bundle sizes and what files are being compiled, comment out this line. I set it to errors-only
so that it's less verbose.
rules: [ | ||
{ | ||
test: /\.tsx?$/, | ||
use: "ts-loader", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loaders are plugins that compile different file types. ts-loader
is what handles typescript transpilation, which is then passed back to webpack which stitches everything together into a browser-friendly single file.
], | ||
}, | ||
resolve: { | ||
extensions: [".ts"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you were ever to introduce React into the project -- .tsx
files -- then this would need to be amended to include that extension.
7e165e1
to
d7db2fb
Compare
"editor.rulers": [120], | ||
"editor.tabSize": 4, | ||
"editor.formatOnSave": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hooks into Prettier
"prepush": "npm run type-check", | ||
"prettier": "npm run prettier", | ||
"type-check": "tsc --noEmit --pretty", | ||
"watch": "NODE_ENV=development webpack --watch" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start webpack in development
mode and watch for changes, automatically outputting to /docs
(per webpack.config.js
setting)
Hi Christopher, thanks for the work you've put into this, I really appreciate it. I'm pretty new to Typescript and I've really only used it for this project, so there's a lot for me to digest here. I'm also, unfortunately, super busy at the moment, so it may take me a while to look at it, I hope that's OK. |
Np! Just want to note that the actual typescript changes are very minimal (remove namespaces) and that this PR mostly has to do with general application dev workflows (linting, codeformatting, making sure that errors aren't checked in to git, configuring VSCode a bit, etc), which improves productivity. The diff is mostly Prettier (which works like Golang's go-fmt, or Scala's ScalaFmt) which you can play with on the playground. Taking out Prettier's formatting, the change count would be fairly small, but Prettier is pretty standard these days since it eliminates so much futzing with code. But yeah, no rush! |
This PR lightly refactors the app into a modern idiomatic typescript form, and adds some nice project hygiene tools that are often seen in the JS ecosystem.
Overview of changes
import
statements so that things are more modular and scalable:@types/..
definitions which are automatically read in by VSCode; no need to use /// refsextensions.json
andsettings.json
file for VSCode and included TSLint and Prettier so that as code is written it's checked and formatted on the fly after savelint-staged
, a library which connects to git precommit and push hooks so that errors aren't checked into the repo. On commit it will run TSLint and Prettier, and on push it will run the typechecker to ensure code is validwebpack.config
file for bundling up typescript for web. Typescript by default doesn't know how to bundle code that uses ES6 modules and so webpack is the tool that packages it all up for distribution.In terms of actual code changes, most of the diff is Prettier being run over the sources and TSLint being run with
--fix
(which automatically fixes common issues;let
toconst
, for example, if the variable isn't reassigned). Actual code changes only relate to swapping namespaces for imports and adding some tooling.In terms of deploying changes, the same process applies as before --
npm run dev
will watch the project and output a file in the/docs
folder. I've added an additionalnpm run build:dist
command that will minify output, but didn't connect that to anything, it's just there if you think the bundle size is too large and want to bring it down for consumers. Webpack handles minification and sourcemaps, which is determined based on whether theNODE_ENV
is set todevelopment
orproduction
.To take PR for a spin:
I've added further comments inline.