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
Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
I'm attempting to pack my web application and related Node.js based web service into an Electron app, and while it all works fine running it with "electron .", packing it up in an asar package, the module resolver starts complaining about everything and nothing.

I've been doing this for a few months on the side, but for some reason I get the feeling that nothing ever seems easy and just work with this web development poo poo.

:negative:

Now I'm sitting here at midnight trying to research and resolve this. Which is sad, because it's a work project. I guess I need tell the module loader a bunch of additional paths, if I detect running from an asar. Hope this works when attempting it tomorrow.

Also, paging this thread back a bit, I see people talking about ditching CRA for something called Vite. I'm however using react-scripts-rewired for reasons I forgot, but which I guess was wrangling some things in place (I think it was forcing Webpack 5 in CRA to use some polyfills or whatever). How screwed am I?

Adbot
ADBOT LOVES YOU

Splinter
Jul 4, 2003
Cowabunga!
With react-query, any ideas for a re-usable/maintainable way of adding a pause (presumably via setTimeout) in a mutation's onSuccess callback prior to calling queryClient.invalidateQueries() other than manually writing this timeout into any mutations that need this functionality?

The issue I'm running into is parts of this app write/fetch from a 3rd party API (through the app's backend server, the frontend isn't directly making requests to the 3rd party API) and there's a significant (on a programming scale) delay in terms of how long it takes the results of write requests to propagate to the results of GET requests. For instance, after sending a request that should remove an item from at list, it seems to take around 800ms before the GET query that fetches the list actually starts returning the updated list with the removed data. This is long enough that a typical RQ workflow of just calling invalidateQueries in onSuccess results in the queries completing their refetching before the change is reflected in the GET data.

This can be partially alleviated by using setQueryData to update expected queries immediately without relying on a refetch via invalidate, but I'd still like to setup invalidates to work as expected just so other devs on this project to run into the same problem in the future.

Only a portion of the app's queries fetch from this 3rd party API, so this isn't something that needs to be applied to all invalidates.

Roadie
Jun 30, 2013

Splinter posted:

With react-query, any ideas for a re-usable/maintainable way of adding a pause (presumably via setTimeout) in a mutation's onSuccess callback prior to calling queryClient.invalidateQueries() other than manually writing this timeout into any mutations that need this functionality?

The issue I'm running into is parts of this app write/fetch from a 3rd party API (through the app's backend server, the frontend isn't directly making requests to the 3rd party API) and there's a significant (on a programming scale) delay in terms of how long it takes the results of write requests to propagate to the results of GET requests. For instance, after sending a request that should remove an item from at list, it seems to take around 800ms before the GET query that fetches the list actually starts returning the updated list with the removed data. This is long enough that a typical RQ workflow of just calling invalidateQueries in onSuccess results in the queries completing their refetching before the change is reflected in the GET data.

This can be partially alleviated by using setQueryData to update expected queries immediately without relying on a refetch via invalidate, but I'd still like to setup invalidates to work as expected just so other devs on this project to run into the same problem in the future.

Only a portion of the app's queries fetch from this 3rd party API, so this isn't something that needs to be applied to all invalidates.

Just make another hook that wraps useMutation with a wrapped onSuccess call including the delay.

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!
Just wanted to pop in and say Typescript is the most anal retentive garbage I have ever experienced.

Trying to learn something new? Better hope whatever you're researching was written that day with that exact version of typescript, otherwise it'll throw compilation errors no one else gets, to the point you just make the linting so lax to make progress that it defeats the whole point of typescript in the first place.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

The Merkinman posted:

Just wanted to pop in and say Typescript is the most anal retentive garbage I have ever experienced.

Trying to learn something new? Better hope whatever you're researching was written that day with that exact version of typescript, otherwise it'll throw compilation errors no one else gets, to the point you just make the linting so lax to make progress that it defeats the whole point of typescript in the first place.

typescript is good, post the code

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!

teen phone cutie posted:

typescript is good, post the code

code:
ERROR: User's post does not begin with a capital letter
code:
ERROR: User's post does not end with a period
Anyway here's two examples

code:
error TS2698: Spread types may only be created from object types.

let basicsort = props.rows.map(object => ({ ...object }))
                                           ~~~~~~~~~
error TS2722: Cannot invoke an object which is possibly 'undefined'.

const tabTitles = ref(slots.default().map((tab) => tab?.props?.title));
                       ~~~~~~~~~~~~~
Doesn't matter anyway. I shut up those error with // @ts-ignore and the compiled library doesn't work anyway. It just blanks the whole page. SO I guess I should look at a fifteenth example of "how to create a library in Vue with Vite and TS" only for it to break after everyone goes "Vite? no one uses that! Write it it "newhottness" also TS updated so the Vite one no longer works anyway"

go play outside Skyler
Nov 7, 2005


That sounds more like a problem with Vite than with TypeScript.

TypeScript is really good, really stable and extremely backwards compatible.

prom candy
Dec 16, 2005

Only I may dance
If you used @ts-ignore and then the code didn't work maybe Typescript was trying to tell you something useful?

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Those look like pretty reasonable Typescript errors. I wouldn't // @ts-ignore them unless there was literally no other option to work around them.

The Merkinman posted:

code:
error TS2698: Spread types may only be created from object types.

This is saying that props.rows is not typed as an array of object types. If this type is a type you define, you should redefine it as an object type.

If not, I would try to track down what the type actually is and adjust the code accordingly. I really like this plugin (typescript explorer) which makes inspecting types in VScode a lot more ergonomic.


The Merkinman posted:

code:
error TS2722: Cannot invoke an object which is possibly 'undefined'.

This is saying that default is an optional property of slots and could be undefined.

If the types aren't lying, you probably want to optional chain it:
code:
const tabTitles = ref(slots.default?.().map((tab) => tab?.props?.title));
Or add some check to handle the undefined case before executing that line of code:
code:
if (!slots.default) {
  throw new Error('Slots default is missing!');
}
const tabTitles = ref(slots.default().map((tab) => tab?.props?.title));
I would also recommend this other VScode plugin (pretty TS errors) to make your typescript errors more readable.

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!
So I addressed all those errors and everything is all nice and happy and while it builds now. I was going to write a whole long thing about how while it compiles successfully it threw errors when trying to use it, but in writing up that long post I essentially baby-ducked my way to a solution,

for props.rows it's any Array of any, which I know any should be avoided but it really can't be helped in this place. So this was enough.
code:
rows: {
    type: Array as PropType<Array<any>>,
    required: true
  }
for the tabttitles I threw the error because the other solve still wasn't enough.

I'm sorry, I've been playing around with trying to get this done for weeks, all squeezing in time during the little free time I have because 'tech debt' is not something that gets prioritized.

EDIT: Also Thank You

The Merkinman fucked around with this message at 22:50 on Aug 2, 2023

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

You can substitute the any for Record<string, unknown> (a record of unknown values) and get a spreadable type.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!

The Merkinman posted:

Trying to learn something new? Better hope whatever you're researching was written that day with that exact version of ...
This seems to be a general web development thing and it's driving me nuts in my part-time dev duties. So much lost time chasing my tail when trying to resolve an issue and then having to comb through tons of outdated GitHub issues and Stack Exchange posts. And fighting Google itself, due to all these gently caress poo poo content mirroring sites ranking higher than the original pages.

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!

Ima Computer posted:

You can substitute the any for Record<string, unknown> (a record of unknown values) and get a spreadable type.

What's the benefit of that vs Array<any>?

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.

The Merkinman posted:

What's the benefit of that vs Array<any>?

An array of objects with unspecified shape:
code:
Array<Record<string, unknown>>
Versus an array of anything (numbers, strings, objects, nulls, undefineds, :iiam:):

code:
Array<any>
The former is a more constrained (but still pretty loose) type which wouldn’t trigger a complaint about the spread operator being used on it.

Golden Bee
Dec 24, 2009

I came here to chew bubblegum and quote 'They Live', and I'm... at an impasse.
I used to use redpen.io to annotate up drafts, but it’s defunct. What do you use? I’m looking for something where I can easily import a webpage visually and have other people see my spot-notes.

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!
EDIT: Sure deleting node_modules and redoing npm install worked??

The Merkinman fucked around with this message at 19:37 on Aug 15, 2023

MrMoo
Sep 14, 2000

Try an older version of Vue, they probably broke something.

WSL supports links fine, NTFS supports hard and soft links since Vista.

duck monster
Dec 15, 2004

Typescript is unequivocably a Good Thing. The problem with TS really is that because it needs to be compatible with JS its all optional mechanism which leads to that weird limbo of "I want to use TS here, but it invokes the exploding chaos if I include this old library so I might just dumb down the linter to cope with it.". When *everything* is static explicit types like C or whatever, theres really no ambiguity and thus everything works.

duck monster fucked around with this message at 03:26 on Aug 16, 2023

fsif
Jul 18, 2003

TS can be overkill on some projects IMO and it can be particularly burdensome in a lot of creative tech-y and WebGL stuff.

duck monster
Dec 15, 2004

Considering that 95% of what we're making here are fucken web pages, this is an entire industry built on overengineering the poo poo out of everything.

I mean gently caress, we have compiler chains and not only that but they are usually more complicated than C compiler chains. I repeat, we have compiler chains, for an interpreted language for web pages that might just work just as well with a bit of footerJS to automate the forms. EVERYTHING is overkill in 2023 web development.

Impermanent
Apr 1, 2010
Static types aren't overkill they just reduce the problem of everything else being overkill

fsif
Jul 18, 2003

I use TypeScript in most of my projects and generally like it but I work for an agency and we have to get things out quickly and most of our sites/apps don't need to be maintained for more than the duration of an advertising campaign. Obviously it's a different calculation if you work on a product team.

But like, here's the code I have to write to pass a simple ref into Zustand. The code's hideous and I never needed to revisit past the literal day I wrote it. You can't tell me this saved me time!

code:
type StoreState = {
  containerRef: React.MutableRefObject<HTMLDivElement | null> | null;
  setContainerRef: (ref: React.MutableRefObject<HTMLDivElement | null>) => void;
}

export const useStore = create<StoreState>()((set) => ({
    containerRef: null,
    setContainerRef: (ref: React.MutableRefObject<HTMLDivElement | null>) =>
      set({ containerRef: ref }),
})

abraham linksys
Sep 6, 2010

:darksouls:
i think static types keep me from wanting to go back to the web as it was, they're a huge boon to development. and this also leads to me being stuck with react/jsx because then you get type-safe templating for free, which is amazing (respect to vue, but vetur got me to nope out of any hopes of using typescript in that ecosystem, hopefully volar goes better). i wish the ecosystem was a little better (it's stupid that io-ts/zod/etc exist instead of typescript having a blessed standard library for parsing untrusted data), but i cannot imagine going back to writing untyped code - not just for frontend, but in any environment.

i posted about this a little while ago in this thread but i think what most websites need is like: a bunch of page templates, and then code for each of those to load data for each of those pages. next.js is pretty good at this now (at least the pages router, app router still looks like a mess but i'm kind of rooting for them since it does let them do a lot more dynamic stuff with server-side logic). i'm very happy with it; i've replaced swaths of ill-thought-out redux code with code that looks like
code:
async function getServerSideProps(ctx) {
  const post = await getBlogPost(ctx.params.slug);
  if (!post) {
    return { notFound: true };
  }
  return {
    props: { post }
  };
}

const BlogPostPage = ({ post }) => (
  <div>
    <h1>{post.title}</h1>
    <p>{post.content}</p>
  </div>
);
and it all just kinda works as you want.

there's exceptions to my rule of "just load data for a page" - like, a big super-dynamic dashboard UI that doesn't care about server-side rendering and needs lots of live updating, ok, sure, build a big huge react app and get that going. but i think this is, like, 5% of web applications. and i think that the whole reason we wound up saying frontend is too complicated isn't really react's fault, or typescript's fault, it's that people try to apply the architecture they'd use for that 5% of web applications to the other 95%, and then they conflate "my lovely giant home-rolled framework on top of redux is too complicated" with "react is too complicated"

abraham linksys
Sep 6, 2010

:darksouls:

fsif posted:

But like, here's the code I have to write to pass a simple ref into Zustand. The code's hideous and I never needed to revisit past the literal day I wrote it. You can't tell me this saved me time!

this looks like Zustand falling into the not-designed-for-TypeScript trap which is kinda where Redux ended up (even with Redux Toolkit). some patterns just aren't made for static typing. if y'all are using TS on new projects, maybe try using a different state library? i've been rolling with useContext but i think jotai is like a slightly nicer version of that

Vesi
Jan 12, 2005

pikachu looking at?
yeah when types start to look like haskell I just switch to any, no shame in that

then if that section needs further development or if there's mysterious bugs then it's time for more exact types

hey mom its 420
May 12, 2007

Throwing in my 2 cents, TS is great for pretty much everything. If you're doing stuff that's one-off and very much not critical and you're rubbing against the rough edges of React's types, just use any, no problem.

when people say they like dynamic languages for moving fast during the early phases of a project, I think that's mainly a holdover from the olde times when your choice was something like python 2 vs. java 7 or whatever (where you had to type annotate everything and instantiate 3 classes with really long names just to read a file). nowadays, you can move incredibly fast with typescript. and imo it makes prototyping even faster, because you can easily refactor stuff or change how your data is structured and TS will let you know what you need to fix and where so that your solution remains structurally sound. Later on, you can take even more advantage of the type system so that it keeps the more tricky parts of your business logic in check too.

anyway, just jurious: what kind of problem did you face that led you to store refs to html div elements in a global store? I can't think of where I'd want that, maybe something to do with modal overlays?

Roadie
Jun 30, 2013

fsif posted:

I use TypeScript in most of my projects and generally like it but I work for an agency and we have to get things out quickly and most of our sites/apps don't need to be maintained for more than the duration of an advertising campaign. Obviously it's a different calculation if you work on a product team.

But like, here's the code I have to write to pass a simple ref into Zustand. The code's hideous and I never needed to revisit past the literal day I wrote it. You can't tell me this saved me time!

TypeScript code:
type StoreState = {
  containerRef: React.MutableRefObject<HTMLDivElement | null> | null;
  setContainerRef: (ref: React.MutableRefObject<HTMLDivElement | null>) => void;
}

export const useStore = create<StoreState>()((set) => ({
    containerRef: null,
    setContainerRef: (ref: React.MutableRefObject<HTMLDivElement | null>) =>
      set({ containerRef: ref }),
})

Here's the version with a bit less boilerplate:

TypeScript code:
import { RefObject } from 'react';
import { create } from 'zustand';

export const useStore = create<{
  containerRef: RefObject<HTMLDivElement>;
  setContainerRef: (ref: RefObject<HTMLDivElement>) => void;
}>((set) => ({
  containerRef: null,
  setContainerRef: (containerRef) => set({ containerRef }),
}));
Pointlessly making separate type declarations is one of those things I see people do over and over with TS and I don't understand why.

fsif
Jul 18, 2003

Roadie posted:

Here's the version with a bit less boilerplate:

TypeScript code:
import { RefObject } from 'react';
import { create } from 'zustand';

export const useStore = create<{
  containerRef: RefObject<HTMLDivElement>;
  setContainerRef: (ref: RefObject<HTMLDivElement>) => void;
}>((set) => ({
  containerRef: null,
  setContainerRef: (containerRef) => set({ containerRef }),
}));
Pointlessly making separate type declarations is one of those things I see people do over and over with TS and I don't understand why.

TIL I learned about RefObject (thanks!) but this is still the baseline for comparison:

JavaScript code:
import create from 'zustand';

export const useStore = create((set) => ({
  containerRef: null,
  setContainerRef: (containerRef) => set({ containerRef }),
}));

prom candy
Dec 16, 2005

Only I may dance

fsif posted:

TIL I learned about RefObject (thanks!) but this is still the baseline for comparison:

JavaScript code:
import create from 'zustand';

export const useStore = create((set) => ({
  containerRef: null,
  setContainerRef: (containerRef) => set({ containerRef }),
}));

imo I prefer the 3 extra lines to get editor hints and a compile error if I or someone else fucks it up

fsif
Jul 18, 2003

Guess that's where we disagree. 3 extra lines of code for something that is ordinarily only 4 lines of code is, like, 75% more lines of code, heh. In this instance, I don't think the editor hints and pre-runtime errors are worth it.

kedo
Nov 27, 2007

duck monster posted:

EVERYTHING is overkill in 2023 web development.

What are you talking about?! To render HTML on a page I need 500 dependencies and a compiler that only works when you compliment it nicely before it runs.

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
Not using types or putting any in your types equivalent to putting /* eslint-disabled */ on those sections of code.

It kinda defeats the purpose of having Typescript there.

prom candy
Dec 16, 2005

Only I may dance
There's nothing stopping anyone from making websites the old fashioned way. All that stuff still works.

Edit: also just use HTMX if you hate all this stuff

prom candy fucked around with this message at 14:50 on Aug 16, 2023

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

prom candy posted:

There's nothing stopping anyone from making websites the old fashioned way. All that stuff still works.

yeah but i'm at the point where i can crank out a website way faster using crap (create-react-app) than using the old tools and all the complexity of the build chain is job security. obviously the people who came up with this poo poo never had to debug their code in an operating room next to a surgeon wearing bloody scrubs but we're entering an era where people trust computers to steer cars so i can't complain about the ceremony too much.

abraham linksys
Sep 6, 2010

:darksouls:
tbh i don't really understand the hand-wringing over library count and build tooling when your backend is probably way more complicated under the hood, just probably better abstracted. you think your react app has a lot of complexity behind the scenes, wait until you hear about this "jvm" thing

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
My backend doesn't have a thousand bullshit one-developer libraries that are one dev meltdown away from automatically sticking malware in my build process.

YMMV if your backend is in node or dotnet or similar though

abraham linksys
Sep 6, 2010

:darksouls:

Jabor posted:

My backend doesn't have a thousand bullshit one-developer libraries that are one dev meltdown away from automatically sticking malware in my build process.

YMMV if your backend is in node or dotnet or similar though

unless you're using a backend stack that is entirely provided by one trusted vendor you probably are just as susceptible to that kind of attack as anyone else

hey mom its 420
May 12, 2007

where i work we use python for the backend and it's the same poo poo, if not worse. at least js doesn't have xkcd comics about its horrendous package management

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.
just use java and spring for your backend

Adbot
ADBOT LOVES YOU

smackfu
Jun 7, 2004

Jabor posted:

My backend doesn't have a thousand bullshit one-developer libraries that are one dev meltdown away from automatically sticking malware in my build process.

YMMV if your backend is in node or dotnet or similar though

Instead we had a log4j vulnerability that impacted every single Java service at our company.

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