javascript
dat.GUI#
dat.GUI lets you quickly add an interface to your javascript app/game that allows you to tweak options and modify values in real time. Very handy when balancing games instead of the traditional
- change value
- reload.
Here’s a cool demo of dat.GUI’s features.
should i use react or vue#
https://should-i-use-react-or-vue.now.sh/
debug jest on windows#
css
node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand
then click Inspect on the target in chrome://inspect
intercepting fetch and XHR#
Intercept fetch, log the request and the response. Adapted from this.
javascript
const mockFetch = window.fetch;
window.fetch = function() {
console.log('request', arguments);
return new Promise((resolve, reject) => {
mockFetch.apply(this, arguments)
.then((response) => {
resolve(response);
return response.clone().json();
})
.then(data => console.log('data', data))
.catch((error) => {
console.log('error', error);
reject(error);
})
});
}
Intercept XHR
javascript
const oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// do something with the request
this.addEventListener('load', function() {
// do something with the response
});
}
browser file access#
typescript
import { saveAs } from 'file-saver';
export default () => {
const fileUpload = useRef<HTMLInputElement>(null);
const exportQuestions = () => {
const fileName = 'questions.json';
const fileToSave = new Blob([JSON.stringify(questions, null, 4)], {
type: 'application/json',
});
saveAs(fileToSave, fileName);
}
const importQuestions = () => {
if (null !== fileUpload.current) {
const file = fileUpload.current.files![0];
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = (evt: ProgressEvent<FileReader>) => {
if (evt.target && typeof evt.target.result === "string") {
console.log(JSON.parse(evt.target.result));
}
}
}
}
}
return (
<input
ref={fileUpload}
type="file"
id="file-upload"
accept="application/json"
className={classes.file}
onChange={() => importQuestions()}
style={{ display: 'none' }}
/>
);
}
remote console.log#
Access your console.log
output remotely
datetime libraries#
- tempo
- date-fns
- typescript
- luxon
- javascript / types via
@types/luxon
- adds a
DateTime
object - 4.48mb unpacked
- javascript / types via
- dayjs
- typescript
- extended functionality via plugins
- Broken for daylight savings
- moment.js
- dead
- mutable
- js-joda
- a port from java, including the api 🤢
timezones#
dayjs#
typescript
import dayjs from "dayjs";
import tz from "dayjs/plugin/timezone";
dayjs.extend(tz);
const now = dayjs();
const sydneyDate = dayjs("2025-03-03").tz("Australia/Sydney");
const isToday = now.isSame(sydneyDate, "day");
Intl.DateTimeFormat
#
typescript
const date = new Date("2025-03-03");
const asSydneyTime = date.toLocaleDateString("en-AU", {
timeZone: "Australia/Sydney",
});
vitest#
Running tests in multiple time zones#
typescript
// vitest.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
workspace: [
{
extends: true,
test: {
name: "GMT",
env: {
TZ: "UTC",
},
},
},
{
extends: true,
test: {
name: "GMT+13",
env: {
TZ: "America/Auckland",
},
},
},
],
},
});
Mocking now & timezones in tests#
typescript
export const mockNow = (now: string, timeZone?: string) => {
beforeEach(() => {
vi.useFakeTimers();
const date = new Date(now);
vi.setSystemTime(date);
if (timeZone) {
vi.spyOn(globalThis.Intl, "DateTimeFormat").mockImplementation(() => ({
resolvedOptions: () => ({
timeZone, // Your timezone, rest is irrelevant
calendar: "gregory",
locale: "en-AU",
numberingSystem: "latin",
}),
format: () => "1/1/2022",
formatRange: () => "1/1/2022 – 1/1/2023",
formatRangeToParts: () => [],
formatToParts: () => [],
}));
}
});
afterEach(() => {
vi.useRealTimers();
});
};
chrome#
Simulate different time zones in Chrome DevTools:
- Open DevTools
- Open Console Drawer (Esc)
- Click on the three dots in the left corner
- Select Sensors
- Enter a Timezone ID like
UTC
orAustralia/Sydney