Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
Steadily losing confidence as I attempt to determine why my machine transpiles the code like _this_, but the Jenkins machine transpiles it like _that_.

`yarn.lock`s are identical, gulp versions are identical, code is identical. Yarn versions are not identical. Broken transpiled version (generated by the machine that has the older version of Yarn) appears to be including 3 copies of react. Thoughts? (prayers?)

Adbot
ADBOT LOVES YOU

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
Mildly different versions of yarn, one of which is smart enough to realize that multiple versions of react make for trouble.

Multiple versions of react, depended on by several internal packages.

Okay, bump up the internal package dependency versions!

Internal packages' (`npm run`-based) build process has been changed and dumps all its transpiled code into `package/dist/`, breaking all import paths.

Okay, fix the build process!

what is consistent, reproducible, good practice and why would anyone care

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

LifeLynx posted:

From context "debounce" looks like "hey don't run this script a billion times if conditions keep being true" but with this that's not a problem unless someone's somehow spinning their scroll wheel up and down, right?

Chiming in to say that scroll listeners can fire multiple times for a single user interaction, especially for momentum-y scrolling. If your scroll callback does some serious work you've already got some problems but generally speaking without debounce you have no control as to how often it will get invoked

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Doom Mathematic posted:

I would be more inclined to explicitly use window.KHORNE_GLOBAL, a property on a variable window which you already know to be global.

:yossame:

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Khorne posted:

The export syntax is a mini-horror in itself.

...

It's baffling until you read about it and their intent. Even then, it's inexplicable why anyone thought not being able to import a default through curly braces was a good idea. Or why they thought only having a single export wouldn't make it automatically the default and then require curly braces, with no default, for modules with more than one export. Or, just always or never require curly braces on imports. Instead, we have what is there now which is unintuitive and awkward.

export behavior and import syntax are definitely annoying to me (I don't use JS for long enough at a time to internalize the rules) and I kind of assume that it is one of the several JS features that got committee'd into a design that is hard to convey concisely because it's actually a melding of disparate approaches to how the feature should work.

Suspicious Dish posted:

import * as Foo from './foo'; is what I use but they chose the ugliest import syntax for a really good idea

yep, that pattern (individual exports + import * as Modulename or import {few, things, here}) seems like a really good and flexible way to go, but definitely requires more rather than less syntax gymnastics.

I guess the strongest thing about some of the more complex import syntax is that it is like the syntax for destructuring but ugh.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

roomforthetuna posted:

I expect individual exports to just be combined into the single default exported object, and
import {a, b, c} from '...'
to be essentially interpreted as destructuring that single exported object.

:yossame:

The syntax is fiddly and not good

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
I am glad when I get to use JavaScript for my own amusement and largely write things as one big HTML file. Yes, the browser is a more fun JS environment to program for and things are simpler when you just write ES6 (+/- a little browser variation) rather than having to use a bunch of tooling

Then again this only works because it is for funsies?

e: I wonder if you can write modules-style ES 6 using inline script elements... my head says no but my heart says please be yes.

e^2: aw gently caress yeah, you can put modules in inline script elements! gj whoever put that in the standard

prisoner of waffles fucked around with this message at 15:25 on Sep 17, 2018

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Munkeymon posted:

How do you reference them?

that is a great fuckin' question and a casual googling does not reveal a direct way, looooolll

e: workarounds: https://stackoverflow.com/questions/43817297/inlining-ecmascript-modules-in-html

"use a serviceworker to auto-fake the existence of an external script from the inline module source" and "create a blob URL and then import from it" are options looooolllll

e^2: yeah, inline modules are kinda useless, whoops, hahaha

prisoner of waffles fucked around with this message at 16:38 on Sep 17, 2018

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Suspicious Dish posted:

For a while there was planned to be a "Loader" API so you could inject into the module resolution algorithm but then they punted on it. They wanted to have a longer planning time but everybody was using Babel (back then known as 6to5) and Webpack and they included and promoted the feature and invented their own semantics so the committee was stuck with it.

The lack of coordination between WHATWG and TC39, with both sides leaving the host integration to the other, is one of the big reasons that features like that are off the table now.

feature development like a game of pingpong where both players just wander off after a while

Suspicious Dish posted:

Fun fact the whole "import file paths" thing was never supposed to be a thing, it was originally planned to be a virtual hierarchy like C#.

hahaha, we could have a clean abstract system that works well and is not tied to a specific implementation but hey let's not

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Knifegrab posted:

But promise all will only resolve all of them or none of them. I want to display things as they come in, not all together at once if that makes sense?

idk, some poo poo like this?

code:
Promise.inResolutionOrder_synchronous = function*(promises) {
  let remaining = new Set(promises);
  while(remaining.size > 0) {
    let first = Promise.race(remaining);
    remaining.delete(first);
    yield first;
  }
};
code:
Promise.inResolutionOrder = async function*(promises) {
  let remaining = new Set(promises);
  while(remaining.size > 0) {
    let first = Promise.race(remaining);
    remaining.delete(first);
    yield first;
  }
};
I'll admit that it doesn't make sense that they didn't make something like this as part of promises themselves.

Munkeymon posted:

Wrap them in async functions that handle the return data as it comes in. You were probably going to have to do that to handle errors cleanly, anyway.

You're more familiar with how this stuff works, how would my utility function version of this fall down? Promise.race gives back the "first to resolve" regardless of whether it succeeded or errored and callers of my code would have to take care of that themselves...

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

If you just want to stuff the values from > 1 promise into some sink, then yeah maybe you should create all your promises and call .then(sink) on them

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Polio Vax Scene posted:

When are we getting a safe navigation operator for javascript? I'm so tired of null checking every part of a path / including a library as a dependency just for this.

dehumanize yourself and face to using a proxy object that blocks null property dereference

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
yeah, I don't think you can mix Python server-side templates and React stuff-- all the React elements only exist in javascript or JSX-land, you can't just throw them into HTML directly, right?

now if you were using custom elements it'd be a different story

People don't really talk about it a lot but React takes the holy trinity of HTML, CSS, and Javascript and says "actually Javascript is the boss" (especially if you have some `import "component.css"` poo poo in your JSX)

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
I'm not fishmech-- an anonymous hero has been running wild giving (controversial?) YOSPOSters avatars identical to posters with well known brands

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Analytic Engine posted:

My god... I'm sorry for the slander dude

nah, I'm happy that someone either

has decided to play super mischief and give lowtax some spine $$$; or
decided my posts were sPiCy and that they wanted to mess with me a bit

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
consider using

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

and if you really have to, https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Thermopyle posted:

Template literals are easier to read:

JavaScript code:
let a = `
<header>
  <p><a href="${profileUrl}">${name}</a></p>
  <img src="${pictureUrl}" style="max-height: 200px" />
</header>
`
They're the most powerful when you use tagged template literals:

JavaScript code:
> let person = {name: 'John Smith'}; 
> let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1];  
> console.log(tag `My name is ${person.name}!`)
My name is JOHN SMITH!

tagged template literals seem like they good be real good for doing internationalization.

RobertKerans posted:

Server sent events

cf https://developer.mozilla.org/en-US/docs/Web/API/EventSource and https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
i've seen okay performance out of making a big pool and making my vector objects, in effect, thin wrappers around a range of indices in the pool. i've never done anything serious with it, but this suggestion tends to come up whenever a conversation like this goes on long enough

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Dumb Lowtax posted:

I wrote a big one-off WebGL programming site for my students, and did eventually have to make all sorts of general UI stuff from scratch. It eventually settled into a design where JavaScript populates all the pieces from a couple tiny placeholder tags in a mostly blank HTML file. I think React does this as well.

Yes, and also a lot of other related stuff, and in a more complicated way, at JSX buildtime.

tbqh I really like writing UI components as actual HTML templates that get cloned and populated by a teeny tiny amount of JavaScript with no compile step... if your project is small enough that you can get away with it

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
https://twitter.com/sophiebits/status/1132366889684881409

^ this is also something I don't quite love about React: that some built-in elements have (quite nice) stateful behavior and React doesn't quite know how you should work with them.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
Javascript questions thread: perhaps asking too much of a language designed to display banner ads

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Jabor posted:

If a performance difference is too small to easily measure, it's so small that nobody gives a poo poo.

I hope this helps you in deciding which endeavours are a worthwhile use of your time.

Yup. Finding the faster implementation through microbenchmarks is not always worth your time relative to every other part of a project

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
"string matching the regex /^-?\d+$/"

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

The Fool posted:

That does look super cool and the best that I can tell is that she is using prism+d3 to do it. Would have never occurred to me.

she's got perfectly good source maps being served up, you can go and look at it.

as an enthusiast of web technology, I really don't love JSXing all the things. the individual blog posts are React components and... I mean, it's very very nice and it works pretty darn well but...

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
the end result is nice, but the guts are rather opaque. I'm not saying that the finished result isn't nice, but that I don't care for the implementation technology.

why?
1. transpilation makes things opaque. she didn't have to serve up source maps and the input source and many (especially many companies) don't.
2. transpilation steps make it harder to reproduce a workflow and/or keep a workflow working.
3. JSX, aka "might as well be everything in JS", means that certain types of basically static information (styling, document structure) get stuck in the middle of a general purpose scripting language. usually when there's a functional division of concerns and appropriate languages per concern it's best to use the weakest language that fulfills your needs for each concern, lest The Script Get Complicated And Hairy.

I know that this is not a novel take or especially insightful.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
i am semi-unqualified to speak and a semi-hypocrite here because 1. i've never had to do real heavy lifting in CSS 2. I actually liked using google closure compiler (via plovr) 3. next time I get a chance to do a hobby project I'm probably going to use typescript (one hypocrisy strike against me for transpilation) and native web components (actually consonant with the previously-expressed values).

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
also consider looking into the summary and details elements if the compat matrix looks okay for you

https://caniuse.com/#feat=details

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
Have you ever successfully run simple tests through Github's CI? Are the tests attempting to connect to a real Firebase server? It's entirely possible that the test runner is in a system configured by Github to prevent most outbound connections.

You might prefer not to set up a replacement for the real Firebase to use for testing in Github’s CI environment but you may or may not be able to access the real Firebase when running tests in that environment.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
caniuse.com for browser support of web platform features

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

HappyHippo posted:

If they're modifying the elements within the iframe, then it isn't cross domain, no?

Yeah.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Harriet Carker posted:

We have a standard React app with a webpack bundler. I mentioned we could slowly introduce TS into new components without having to touch the old ones until we want to/have time, but he says introducing TS is all-or-nothing because:

quote:

In TS you have to import files like `import { blah } from './world.js` even though it's `world.ts` that's not allowed in TS+ESM. The filename is `world.ts` but because it's actually transpiled to JS and TS is just a lie on top, you have to import all the files as `.js`. You can'd do `./world` in Node.js ESM. It requires the file extension for node native module resolution in ES Modules.

Can anyone help me maybe understand what he means? I've never run into this issue and I'm super unclear, but I don't feel confident enough to engage in the discussion.

Hmm. It sounds to me like he's either got a specific problem with a bundler's support for Typescript that can be worked around OR he's making a mountain out of a molehill.

When and if you have time to just play around, you might see if you can disprove his contention that "introducing TS is all-or-nothing"; just see if you can take an existing bundler build and add one Typescript file and just enough config that it gets built and uses/is used by existing JavaScript code.

Adbot
ADBOT LOVES YOU

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

VagueRant posted:

Unless I'm misunderstanding even more :smith:, we all seem to be forgetting the metricScope() func from the library, and the fact I'm not explicitly defining the 'metrics' value above any of the code?

To reference their docs:
TypeScript code:
const { metricScope, Unit, StorageResolution } = require("aws-embedded-metrics");

const myFunc = metricScope(metrics =>
  async (param1: string, param2: number) => {
    metrics.putDimensions({ Service: "Aggregator" });
    metrics.putMetric("ProcessingLatency", 100, Unit.Milliseconds, StorageResolution.Standard);
    metrics.putMetric("Memory.HeapUsed", 1600424.0, Unit.Bytes, StorageResolution.High);
    metrics.setProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
    // ...
  });

await myFunc('myParam', 0);

quote:

Unless I'm misunderstanding even more :smith:, we all seem to be forgetting the metricScope() func from the library, and the fact I'm not explicitly defining the 'metrics' value above any of the code?

`metrics` is not a variable, it's an argument to a function. `metricScope` takes a function as its argument and `metrics` is the argument of that function.

Here comes the "this sounds like scolding but it's actually meant to make you more effective at asking for help in the future": if aws-embedded-metrics has types in its documentation, you should read them; if you want people in a forum to pay attention to the specifics of a library, you should 1. read the docs yourself 2. indicate in your post that you read them and what you didn't understand 3. post a link to the docs, like this one. Because I'm an idiot, I'm going to guess how all this works before I read the docs, which are here.

Now, here's your free help.

TypeScript code:
// Purely based on working backwards from the code you posted, I've pulled out of my rear end one implementation of what metricScope might be doing.
// This type signature I also pulled out of my rear end, but it's probably right though who knows that they called MetricsRecorder.
function metricScope(metricsCb: (metrics: MetricsRecorder) => async (name: string, value: number) => void) => async (name: string, value: number) {
	// Get a metrics recorder from somewhere
	const metrics = pullMetricsOutOfMyAss();
	return async function(name: string, value: number) {
		return metricsCb(metrics); // <-- this return value is an async function that takes `name` and `value` and returns nothing.
	}
	// Or it might have a different implementation where it gets a fresh metrics recorder every time you call the return value:
/*
	return async function(name: string, value: number) {
		const metrics = pullMetricsOutOfMyAss();
		return metricsCb(metrics); // <-- this return value is an async function that takes `name` and `value` and returns nothing.
	}
*/
}
// So how would you write myFunc as a plain function?
function myFunc(m: MetricsRecorder): async (name: string, value: number) => void {
	// inside the body of this function, we already have a `MetricsRecorder` value in `m`, so!
	// functions returned from in here can use that value of `m`.
	return async function functionThatDoesStuff(name: string, value: number) {
		metrics.putDimensions({ Service: "Aggregator" });
		metrics.putMetric("ProcessingLatency", 100, Unit.Milliseconds, StorageResolution.Standard);
		metrics.putMetric("Memory.HeapUsed", 1600424.0, Unit.Bytes, StorageResolution.High);
		metrics.setProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
		// etc.
		// presumably you'll actually want to use those two parameters.
	}
}

const myFuncReadyToUse: async(name: string, value: number) = metricScope(myFunc);
So, perusing the docs rapidly I see:

- the type of `metrics` is actually `MetricsLogger`
- `metricScope` is a decorator function to which you pass a function that expects a `MetricsLogger` and returns any async function; as a decorator, it wraps the inner function so that it has a freshly created `MetricsLogger` and so that when the inner function is done, the `.flush()` method will be called on that `MetricsLogger`.

Basically, `metricScope` looks confusing, but it's there to reduce boilerplate, assuming you have lots of little chunks of code that need to get a MetricsLogger. If you don't use `metricScope`, you have to remember to get the logger and flush the logger in each one of those chunks of code.

TypeScript code:
// How to do it without `metricScope`:
const { createMetricsLogger, Unit, StorageResolution } = require("aws-embedded-metrics");

const myFunc = async (param1: string, param2: number) => {
  const metrics = createMetricsLogger();
  metrics.putDimensions({ Service: "Aggregator" });
  metrics.putMetric("ProcessingLatency", 100, Unit.Milliseconds, StorageResolution.Standard);
  metrics.putMetric("Memory.HeapUsed", 1600424.0, Unit.Bytes, StorageResolution.High);
  metrics.setProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
  // ...
  await metrics.flush();
};

await myFunc('myParam', 0);

// How to do the exact same thing with metricScope:
const { metricScope, Unit, StorageResolution } = require("aws-embedded-metrics");

const myFunc = metricScope(metrics =>
  async (param1: string, param2: number) => {
    metrics.putDimensions({ Service: "Aggregator" });
    metrics.putMetric("ProcessingLatency", 100, Unit.Milliseconds, StorageResolution.Standard);
    metrics.putMetric("Memory.HeapUsed", 1600424.0, Unit.Bytes, StorageResolution.High);
    metrics.setProperty("RequestId", "422b1569-16f6-4a03-b8f0-fe3fd9b100f8");
    // ...
  });

await myFunc('myParam', 0);

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply