-
When using
extends
in.eslintrc
, the ordering is important. Latter rules overwrite former rules. -
Using
plugin:@typescript-eslint/recommended
handled the issues of "not using interfaces" even though we were. -
ESLint with Typescript imports
- After a series of annoying Googles and searches for how to resolve "eslint import issues with typescript", we finally found
.eslintrc
configuration that worked. There may be extraneous typescript configurations. It's hard to tell because some configurations are needed for basic typescript linting. But at this point, we'll keep everything that's present. The import/extension rules and the import/resolver settings are definitely required. The others may just be related to proper typescript linting.
- After a series of annoying Googles and searches for how to resolve "eslint import issues with typescript", we finally found
-
Creating "extensible" enums types
- This is really just a way to keep type safety and "extensibility" for "enums" in JS without trying to go too C#/type crazy. Makes perfect sense.
- You should beware of the enum conflicts example that andy-ms gives. However, currently, there isn't likely to be an issue where, for instance, A "Red Card" in Uno would be mistaken for a "Red Card" in Codenames. This is analogous to GoodMusic.RockAndRoll being mistaken for BadMusic.Rap in andy's example, since both of them evaluate to 0. But we aren't doing things like switch case scenarios at the moment. And our decks will likely be isolated during gameplay anyway. If the decks are brought together, the cards may still be of "the same type" anyway so it still may not matter. In any case, for now things appear to be safe. But we should consider these potential problems in the future.
- Also be aware that this is probably one of the few areas that is "more TS than JS" as a warning. We want to be as much JS as possible. But this is only a slight deviation that really just focuses on expressing types, which are already a part of TS anyway.
-
eslint
doesn't understand exporting types. It thinks you're exporting undefined. Nonetheless, the code still compiles. It seems eslint has a bug. -
For
export * as namespace from module
, you'll need the babel plugin, which we have installed. Notice that this was a proposal that has been merged...butES2020
is not out yet... See this tc39 proposal -
For some reason,
Nullish Coalescing
andOptional Chaining
are already in the babel preset that we're using. (It should be in ES2020 anyway.) We'll just take advantage of this.- Optional chaining looks more powerful in JS than you'd think. It's not just some simple C# syntax. It goes even further, like being able to use
obj?.[key]
(which makes for stuff like asking for dynamic properties).
- Optional chaining looks more powerful in JS than you'd think. It's not just some simple C# syntax. It goes even further, like being able to use
-
Shuffling arrays in JS. This uses the
Fisher-Yates
algorithm, which is worth getting acquainted with...especially since it's simple. -
Reservoir Sampling is a way to sample
k
items from a population of sizen
without replacement. We used the "optimal" algorithm (assuming it's truly optimal), though we had to properly interpret the algorithm for a 0-indexed array. -
Common convention for functions in JavaScript like
forEach
is to name unused variables as_
. For instance,array.forEach((_, index => ...))
. If multiple unused variables are involved, then the common convention is to precede the variable name with an underscore (eg._item
instead of just_
). -
It seems adding TypeScript can screw up some of the normal intellisense. For instance, in our React Retro project (at least currently), we didn't have to install any explicit types for
express
. But now (likley because we have TypeScript and a TS config), we have to specify theexpress
types by installing them. Similar things will probably need to happen for webpack if you want good typing.- Types are very important when working with TypeScript. It can impact whether or not TypeScript even knows which overload you're using (and allows you to compile that overload). This makes us have to do some work with
process.env.PORT
.
- Types are very important when working with TypeScript. It can impact whether or not TypeScript even knows which overload you're using (and allows you to compile that overload). This makes us have to do some work with
-
Warning about declarations in JavaScript switch/case. Use blocks!
-
TC39 Private fields. Note that private fields are different from private methods. It doesn't seem like TypeScript supports those yet.
- If you use these, you'll need to update Babel, though. (At least until the new stuff gets merged.)
-
Thoughts on ordering parts of a class. Note that some people prefer grouping public, private, protected methods, etc. But that may not always be helpful (if it's helpful at all.)
-
Partial
can be used to make all the properties of an interface optional. -
JSDocs
will be worth understanding at some point. We started implementing some very lightly inCodenames.ts
. -
String enums are not so easy in TypeScript. Is it worth converting to numbers in certain circumstances in order to centralize things and avoid some "duplication"? Perhaps not... That might only work in certain circumstances...like with colors and numbers. It's hard to say.
Deck
- A quick way to test that your deck is working properly is simply to generate a new deck. Then, immediately shuffle it, and log it in the console. You'll find the size of the deck, as well as the array of cards particularly helpful to look at.
Codenames Game
- Testing a Codenames game may require a few runarounds. The simple way to do it is to use the
readline
built-in npm package. You can create an interface with the I/O streams using thecreateInterface
method. Then, you can listen for events on the returned object. Userl.on("line", function(input))
. You can use it to force in your own cheaty actions as a player outside of the existing game. It should be quick enough, and you should easily be able to test win conditions. To observe other things like current player, you'll want to observe thegameState
.
- Testing a Codenames game may require a few runarounds. The simple way to do it is to use the
- Remember that ideally, we'd want real, robust tests. At least right now, card games can be treated like a
Redux Reducer
to some extent.
- Helping ESLint resolve aliased imports
- TSconfig, among other things, can be used to help Visual Studio Code resolve aliased imports.
- We pulled our typescript config from Vue's. (We excluded the webpack-env type though.)
- Webpack vs. Webpack Dev Server vs. Webpack Hot Server vs. ...
- Using Typescript with Vue via webpack
- Using Typescript in Single File Components (SFC's)
- Adding Hot Module Reloading
- Add Vue without CLI
- Note that the ESLint config seems very brittle when it comes to Vue. So be extremely careful with it.
- Using ESLint with Vue. (Includes the complications of handling parsers.)
- Vue Component tags order
- Vue Break on single line elements. (No reasoning was given, this adds to lines of code, and it seems dumb...so no.)
- Vue recommendations for ordering of component options
- Understanding the default options in VueLoaderPlugin. This also reveals why you need to install
vue-template-compiler
, even though it seems like you're not using it anywhere. (Really it's being used by default behind the scenes.) - The order of your express routes matters, especially when using
app.use
. - How to use JSON stringify with getters in a simple way.
JSON.stringify
doesn't do anything with functions. So getters and setters don't give you anything. The first solution is a quick and simple work around. Perhaps there are more options too?- Note that with this simple solution, there's no way to guarantee that players won't manipulate their own data on the client side (because getters won't be properly hidden behind getters anymore), though the server data will certainly stay pure. This is why a more robust solution would be useful.
- A more robust version of the simple solution (doesn't resolve the getter no longer being a getter)
- MDN
toJSON
method.- It seems that raw objects with getters don't have a problem with JSON serialization. However, instances of classes will often lose any getter (and setter) info during JSON serialization.
- Animating box shadow.
- Using v-model on components
- Custom events with components (example includes v-model)
- Apparently,
select
elements and their correspondingoption
elements are very complex and difficult to style. For now, we're forgoing complex styles to proceed with development. - Understanding the
aria-label
textContent
vs.innerText
- Server-sent events allow a server to send information to the client. (Eg. the person in theh browser) It's only one way.
- Web Sockets allow both the client and the server to send messages back and forth.
- We found some good information on these topics that will be useful to know. Also remember that you have your own notes on Node for Networking.
Server-sent Events
- Excellent simple example of implementing server-sent events. There are some places where the grammar is a little off. But the explanations are pretty solid.
- MDN Server-sent Events
- MDN Using Server-sent Events
- Event Source. (Used by JS client for handling server sent events.)
Web Sockets
- MDN Web Sockets API
- MDN Web Socket (JS object)
- Wikipedia on Web Sockets
- Useful example of Web Sockets compared to Server-sent Events
- Simple example of using Web Sockets with Express. (This one may be over simplified. We had to test stuff out on our own.)
- Web Socket NPM Package (
ws
). (This was the package used by the 2 previously listed examples. It seems to make things simpler than using Node's built in capabilities.)
Cross Origin Resource Sharing (CORS)
- MDN on CORS. (This will just be good to read up on in general.)
- JSDocs. This is good for keeping helpful documentation. This helps Visual Studio Code's intellisense too.
- The JSDoc tags that TypeScript supports. This is important to help you understand what JSDoc tags will and won't work with Typescript. Note that even if some things don't work, they could still be worth learning and using. (This is especially helpful if you convert back to JS for any reason.)
- Prettier overrides
- Using
require.context
(webpack-specific) with Typescript - Vue's "Automatic Global Registration"
- Useful random string generation discussion
- Using
process.env
withwebpack
- Handling situations where ESLint conflicts with TypeScript
- An official maintainer's views on the "don't use object" rule... It's good to think for yourself like this guy.
- Fixing Vue's incompatibility with the new css-loader (not officially fixed yet)
- Setting up Vue for testing with Jest
- Configuring Jest for file transforms
- Note: It seems that installing
babel-jest
is unnecessary. Jest automatically knows whatbabel-jest
means even if you haven't personally installed it locally. (Perhaps it's a part of Jest's dependencies?)
- Note: It seems that installing
- Configuring Jest's expected module extensions
- Note that the complexities with
vue-jest
are the reason we had to install the extra weird"babel-core": "^7.0.0-bridge.0"
package. Whenevervue-jest
properly gets updated/fixed, you should remove this extra dependency as soon as possible.
- Configuring Jest for file transforms
- See our github repo for more info on why some parts of Vue testing require
async/await
and other parts don't. Note that we should try to keep things as synchronous as possible from now on for Vue tests. - Configuring prettier for making the Vue
template
s nicer - Apparently, to make the store update the URL, you can just import your Vue Router