Jump to content

boilerplate setup


dmko
 Share

Recommended Posts

Was reminded that each file should start out with a /// reference line for each file it depends on. I'd been using using namespace w/out these for awhile because my IDE didn't seem to need them (e.g. auto-complete, error-checking, etc. still worked fine without them), but I guess my projects weren't big enough to need them, in terms of the volume of original code with missing references.

/// <reference path="boilerplate/animals.ts" />
/// <reference path="boilerplate/vehicles.ts" />

let jaguarAnimal  = new Boilerplate.Animals.Jaguar();
let jaguarVehicle = new Boilerplate.Vehicles.Jaguar();

 

Link to comment
Share on other sites

3 hours ago, Taz said:

Yes naming the same module the exact same way over and over is a chore I would rather do w/out. If it's usually named after the library to prevent collisions anyway, why not allow that to be the default naming behavior?

Because its enforcing and can not be undone, not a great decision for an ecosystem.

If you like to use this in your own projects then more power to you, similarly if you want to use it for libraries you consume then cool.

They can be interoperable, as they are, anyways. Most large libraries export a UMD, which includes using a global for the library, which is a namespace for it, whilst also exporting a module system under the hood. The only issue with libraries including their own dependencies as part of their namespace (which they would need to do) is code duplication, for example, if you include some lodash functions and you export a bundle for your library attached to a namespace then you must include those dependencies (if the consumer also uses that same dependency they'll get it twice) or enforce that your consumers also include those exact same dependencies globally in their project so your dependency library can use them, which directly breaks encapsulation and makes your library harder to consume.

Out of interest, if you wanted to include an http library named Request and a state management helper utility library called Request, both expecting to stick to a global Request namespace, how would you handle that? Drop one? Seems a shame.

5 hours ago, intoxopox said:

JS modules currently look not-ready-for-my-suborn-ways

Yeah, I feel like I've been on the attack but, as with most opinions, if your system works for you and your team then why would you change it? You'd need tangible benefits, and that needs to be weighed against time/effort to learn a new system.

Good article, I keep meaning to run my own tests like this, but I can't see how a browser module system is going to be ready for a good while yet, its certainly coming, but, I wonder if it'll ever make it attractive enough to completely ditch a build system, on a slightly different note gzip (and other) compression is better over 1 big file than the same big file split into 100.

My current project runs at about 400 js files or so, of which, more than 250 or 300 will be bundled up for the browser, but I can not even guess at how many files will be bundled if you include dependencies, my guess is a lot for a couple of hundred kb of js (although weight wouldn't change too much, depending on gzipping) the number of requests will be through the roof so I see a good number of problems yet to be overcome before using modules natively can be a viable option.

Thats not to say module bundlers aren't superb at what they do and are now at the stage where they provide benefits to the deliverable to the browser (or other environment) rather than just a development benefit. So if you did want to take the dive with es modules there's no need to wait for browsers, solutions exist now (and have done for a couple of years) that let you get a head start on this, and as node chose commonJS modules (very similar to es modules, by design) you have full access to npm and the module ecosystem, which is a huge boon.

Link to comment
Share on other sites

> Out of interest, if you wanted to include an http library named Request and a state management helper utility library called Request, both expecting to stick to a global Request namespace, how would you handle that? Drop one? Seems a shame.

I guess I would add the first library to my project and tell the IDE to refactor the namespace's name from Request to HttpRequest. Then I'd add the second library and refactor from Request to StateRequest. Dropping one of the libraries wouldn't be necessary but I agree it's a bad situation to have to do a refactor for each conflicting library (and again when the library updates). Maybe there's a better way to handle it, if not the namespace feature should evolve to handle this better. Or module could evolve to allow default naming..

 

>> Yes naming the same module the exact same way over and over is a chore I would rather do w/out. If it's usually named after the library to prevent collisions anyway, why not allow that to be the default naming behavior?

> Because its enforcing and can not be undone, not a great decision for an ecosystem.

I was just wondering why not allow defaults since the module is usually named the same way over and over again. E.G., if you could omit name when importing a module to let the alias be created with the default name - as an option, not to enforce anything. And as a concept/goal, not as module vs namespace.

 

> If you like to use this in your own projects then more power to you, similarly if you want to use it for libraries you consume then cool.

Fair enough, and really I'm just sharing what I perceive to be one benefit of using namespace vs module, not really recommending namespace over module nor saying that anyone should use it instead, per se. If anything I would argue in favor of supporting default naming and allowing to name once, not for using module or namespace.

Link to comment
Share on other sites

7 hours ago, Taz said:

>  Do you have an example project on github where it's set up the way you describe?

https://github.com/pixijs/pixi-typescript/blob/v4.x/pixi.js.d.ts and https://github.com/pixijs/pixi-typescript/blob/v4.x/pixi.js-tests.ts.

Thanks for sharing an example! Though, it's very small.. seems like a case where adding the namespace doesn't serve any purpose at all (not that I have a problem with it- if it's the author's style in general and they simply carried it over out of habit that makes total sense to me).

I'd need to see something something larger, e.g. a game or web app. Typically that would involve webpack or gulp at some stage (for example - relying on tsc to output one bundled file has lots of major issues that will haunt you at that stage, though it wouldn't have any problems with the example here. Getting source maps to work across all the used files and in all environments is another issue)

I think it would be helpful if you can fork the boilerplate mentioned at the top of this thread and port it to use namespaces instead... keep in mind that mocha, webpack, and karma all need to still work (meaning you get relevant line numbers on error) as well as autocomplete in the IDE etc. You can pretty much reach all of that by satisfying the "npm run test:dist", and "npm run test:dev" commands

That way we can really compare and contrast between those two examples, on the same project, to see the pros and cons. If you're not up for it - I understand, no pressure... but it might shed more light on the advantages you're proposing.

Fwiw before coming over to JS/TS/PIXI I've been spending the past 2-3 years in Unity/C# on the frontend and Go on the backend. So I do have some sympathy with where you're coming from (w/ Unity)... I just think it's really apples/oranges since Unity imports everything into the global namespace and typescript (at least in the setup I shared here), does not. With that in mind, the odds of a name collision happened all the time for me in Unity... I would have been dead without namespace segregation and I did only come to that conclusion after a while. However, so far in my actual JS/TS/PIXI project it hasn't happened to me yet since I tend to split classes up by separate files and so I just don't hit the case too often.

Go also follows this sort of approach of ts modules (import each package as needed via path, ability to alias, etc.) I wrote a relatively largeish boilerplate api there too and there were only a small handful of times where I needed to alias and it was pretty clear, for example: https://github.com/dakom/basic-site-api/blob/master/endpoints/accounts/accounts.go (e.g. datastore and datastore aliased by gaeds)

Ultimately I think there is really a very small difference we're really talking about here, and it's about whether or not you need to define the path at the top of every file. 1) I don't think that's a big deal at all, and though VSCode doesn't do it automatically I know Atom did for Go so I assume there's some solutions to automate it if it does become a big deal, including refactoring 2) it seems like you may need to do that with your solution anyway e.g. the // references (not sure though)...
 

Link to comment
Share on other sites

Yeah that was bad example relative to what you're looking for,  since it's for providing typescript definitions and doesn't show how a typescript project would be structured, it was more for showing the basic usage in the test file. Maybe someone else has a good example.

Link to comment
Share on other sites

14 hours ago, Jinz said:

I was just wondering why not allow defaults since the module is usually named the same way over and over again.

There would be no way to consume that in an es module style project, if you did:

import 'MyLibrary'

Would you then just use the namespace:

var triangle = new MyLibrary.Triangle()

I guess that would be an option but to work it would have to molest globals when you import it (as some do, looking at you Pixi ;) ), which negates some of the point of using a module system in the first place.

You could achieve this easily enough in a module world by aliasing yourself in an entry point:

import Library from 'MyLibrary'

window.Library = Library

If you really wanted to do that ;) This would prevent libraries from having to molest globals but still allow you to manually shove it global so you don't have to import it in each file you want it.

Most larger libraries have a UMD build which does the same as the above. For those libraries that need that (like Phaser, which currently doesn't work with a module system) you just keep them outside your module system, which means you now have to be responsible for updating them etc etc, no big deal really, but I wouldn't want to do that for a project with 20-30 top-level dependencies, and to ensure you didn't dupe dependencies you'd have to do it for all your dependencies, part of my current project has over 1000 modules in my node_modules folder (thats from only 18 top-level deps) and whilst npm now flattens where it can, some of those deps will have their own deps contained within when version conflicts occur (wow, hadn't thought of that, imagine trying to work that out manually!!), but many will be development dependencies. I'd still guess our current bundle that hits the browser would encompass potential 100 (maybe more) external modules, without a module system I'd go so far as to say that it would be so time consuming as to be practically impossible.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...