5 ms·
There's nothing interesting on the site itself. It's a tool, i'm building. Like I said in the post the architecture is what I'm bragging about, not the app. The
by ClayFerguson 10y ago
There's nothing interesting on the site itself. It's a tool, i'm building. Like I said in the post the architecture is what I'm bragging about, not the app. The app is not tested, and all the things you mention don't surprise nor do they bother me. If you want to critique it, critique the code. I'm well aware what the state of the site itself is. Show me one issue in the code and I will thank you, but you won't find much fault there. :P
- minitech 10y agoAll the things I listed (and more) work by default. Your architecture broke them and didn’t benefit the user as far as I could see. Maybe list such a benefit if you’d like to argue for it?
- ClayFerguson 10y agoI showed you an F1 race car up on cinder blocks being worked on so you could see the engine design. You climb in, try to drive it away, and can't so you conclude the engine design is all wrong? Genius. It's not ready to drive yet (by the public), but that doesn't mean the architecture is wrong. The architecture is state-of-the-art.
- minitech 10y agoYour metaphorical engine weighs a metric ton and it’s very difficult to imagine how it’ll develop into anything resembling a racer. I’d put more effort into the car analogies but they’re making me physically ill. > The architecture is state-of-the-art. You should also probably back this statement up with something. Right now it appears to be a lot of self-horn-tooting. But hey, sure, let’s spend the same half-minute to talk about the code. I open to a random TypeScript file – thank goodness you’re using TypeScript, because the JavaScript you’ve put under version control for some reason would make any non-vendor code in the language difficult to find in this time – https://github.com/Clay-Ferguson/meta64/blob/d9f3740118e80999695dff226c851e444f0fc55d/src/main/resources/public/ts/dlg/UploadFromFileDropzoneDlg.ts https://github.com/Clay-Ferguson/meta64/blob/d9f3740118e8099.... declare var Dropzone; Oh okay I guess we’re not using types here let config: Object = { ⋮ var submitButton = document.querySelector("#" + thiz.id("uploadButton")); This… this isn’t how you reference elements in your “state-of-the-art” architecture, right? if (!submitButton) { console.log("Unable to get upload button."); } submitButton.addEventListener("click", function(e) { I guess the state of the art means you can’t use your browser’s debugger. Or it’s just for consistency given that you’re circumventing the rest of the browser too. this.on("queuecomplete", function(file) { meta64.refresh(); }); What? I have no idea what this does (`meta64` isn’t declared, I guess because this file is allergic to modules. it also appears to be a singleton or global, neither of which particularly screams “good design” when named in reference to your app) but it looks like some kind of indiscriminate state update given that nothing is being passed to it. Maybe it’s not that, but no time to find out. We’re running out of seconds here. Wait, back up a moment: submitButton.addEventListener("click", function(e) { //e.preventDefault(); dropzone.processQueue(); }); Isn’t a major aspect of most of these fancy SPA frameworks that you don’t have to do this? $("#" + this.id("dropzone-form-id")).dropzone(config); > This… this isn’t how you reference elements in your “state-of-the-art” architecture, right? oh no it is. Bonus points for kebab-case when the other two we’ve seen so far are camel. I’m nitpicking style because a meaningless literary device involving cars made me irritable. Sorry. let ret: boolean = false; for (let file of this.fileList) { if (file["name"].toLowerCase().endsWith(".zip")) { return true; } } return ret; That was a useful variable! I would write this: return this.fileList.some(isZipFile); and then probably not write this in the end because it’s a filename check but we’re here to talk about architecture or something, not that: const isZipFile = /\.zip$/i!test; `!` is a macro for bound property access in my state-of-the-art architecture. runButtonEnablement = (dropzoneEvt: any): void => { if (dropzoneEvt.getAddedFiles().length > 0 || dropzoneEvt.getQueuedFiles().length > 0) { $("#" + this.id("uploadButton")).show(); } else { $("#" + this.id("uploadButton")).hide(); } } I would think a F1 racer ninja rockstar architecture would be able to bind the visibility of this button to some state. More bonus points for not using `toggle()` and the same select-by-id antipattern. $("#" + this.id("uploadPathDisplay")).html("Path: " + render.formatPath(attachment.uploadNode)); Select-by-id again. I’ve suppressed the urge to gag by this point. `.html()` instead of binding this to some appropriate component? Nothing new. Mysterious global `render` due to declaring things allergy? Par for the course. Let me know if you would like a review of any other files so I can decline and spare my mental health thanks
- ClayFerguson 10y agoF1 race car analogy still works: I show you an engine on the test stand, saying it's a good design, and you proceed to point out all the loose wires, duct taped electrical connections, and all the stuff that's there temporarily because it's on a test stand, or are details that simply haven't even been addressed yet. I stand by the 'state-of-the-art' claim, and you didn't find any unfinished work that was news to me. My todo list is 10x as long as your list, but the architecture itself is perfect. SpringBoot, JSON API from browser, JCR, Mongo, GooglePolymer, etc., and the way it is all combined is the best architure for a modern app. and ESPECIALLY the SPA aspect.
- Kiro 10y agoYou asked for critique of your code. minitech gave it to you. How about you address these points instead of grinding on about your superiorness?
- ClayFerguson 10y agoI bragged specifically about the state-of-the-art architecture. Architecture can be perfected months or even years before a codebase itself is production-ready, and free of all unimportant band-aids/short-cuts. I'm not going thru my todo list for you to explain why each thing on it hasn't been done yet. You guys are hilarious.
- minitech 10y agoWhat definition of “architecture” are you using here? Is it at a very high level (“I’m using an SPA and an MV* JSON API”)? If it is, I hate to break it to you, but that’s how most of these things have already worked for ages.
- ClayFerguson 10y agoI use the standard every-day definition of "architecture". You're right about JSON and SPAs really catching on finally. That's why I shared this post, and to help people out who've been brainwashed into thinking SPAs are bad. I hope some people also see the code and find out how awesome TypeScript is. Also the JCR. Lots of well kept secrets encapsulated in meta64.
- Kiro 10y agoThe architecture is horrible though. I would suggest you to use a real framework next time instead of rolling your own jQuery mess.
- ClayFerguson 10y agoThe "framework" is Google Polymer. The only thing I use JQuery for is trivial stuff like selecting elements, cookie support, and DOM manipulations, which is exactly what the rest of the industry uses JQuery for, but i bet you didn't know any of that.
- Kiro 10y ago> Show me one issue in the code and I will thank you, but you won't find much fault there. You need to get off your high horse. Not even Jon Skeet thinks he creates perfect code. Your project is nowhere near "great example of modern architecture in a web app". You depend on mysterious global variables everywhere, mix jQuery with HTML tags hard coded in strings (with classes and everything) and have no unit or E2E tests. I applaud your overconfidence though. Most people are ashame of their code, even when it's ten times better than this. Serious tip: invest time in learning React+Redux/MobX or Vue. I promise you it will make your life much better once you realize your shortcomings.
- ClayFerguson 10y agoThose are not global variables. They're TypeScript namespaces. Everything is in a namespace. I'm using namespaces to accomplish the "singleton pattern" in TypeScript, and to avoid globals. Most modern Java-Spring Server-side code usually uses lots of singleton services, and i'm doing the same sort of pattern, in TypeScript. Regarding the generating of the presentation code being done in pure JS/TS rather than a bunch of template files rendered on the server is actually another innovation in disquise. This app is so dynamic that even if it were template-based the templates themselves would be 90% logic, which is why just generating presentation code on the client is ideal. This IS mainly a client-side app, that consumes a server-side JSON API, rather than getting any actual HTML from the server. Yes it's inverted from the way the rest most people are still doing it, but what I'm doing is the future. Learn a bit about microservices and RESTfull stuff and you might begin to see the light, about how a browser can consume an API that sends back JSON DATA rather than rendered HTML. It's the future. I'm doing it right. You just don't get it yet. And if you're irked by my confidence, frankly that makes me happy.
- WorldMaker 10y agoIf you want a critique of the code: it shows a clear lack of understanding of Typescript/JS modules. Your Typescript is compiled to a single mega file and outputs a giant global variable. The namespace keyword in Typescript is often considered bad form versus proper module organization. You even have a module loader installed (SystemJS) to use, but you aren't actually using it for module loading, its almost just a glorified <script> tag with the way you have the code architected. With a little more configuration you could get a lot more mileage out of SystemJS. (Furthermore, your code retains comments with mentions at failures to understand modules in general and a previous attempt with RequireJS specifically.) I'm not sure why you would assume no one could find faults in the code when they even have comments right there about said faults.
- ClayFerguson 10y agoBased on your definition of "giant global variable" the $ in JQuery is also precisely that. lmfao. Seriously bro, you know i'm right. Yes the m64 namespace is designed to encompass the entire app, to keep meta64 from having ANY global scope variables except for that one. Precisely like the JQuery $. I'm doing namespaces precisely by-the-book. So the mere fact that you said "giant global variable" is proof beyond any doubt that you don't know jack about namespaces, and all you were barely able to do was notice the lack of module loaders at the top of my files. You may not even know this, but packaging an app into a single downloadable JS file (modules not even necessary) is actually the modern approach. It lends itself to better compression+minification. Once installed in a browser cache it's usable just like an 'installed' piece of software. But I thank you for the phrase "giant global variable". I'll be laughing at that for years to come.
- WorldMaker 10y ago«Based on your definition of "giant global variable" the $ in JQuery is also precisely that.» Which is part of why I haven't used JQuery in ages. The last time I saw someone mention JQuery as a best practice example was arguably a decade ago, if not longer than that. If you are doing things by a book, it's not a book that was written any time recently. At this point, any library I see that uses a global variable and doesn't support proper module loading is a code smell and a sign that the library is probably not well maintained. «You may not even know this, but packaging an app into a single downloadable JS file (modules not even necessary) is actually the modern approach. It lends itself to better compression+minification.» Actually, this has changed a lot in recent years, and your ignorance of how module systems work also shows up here. First of all, you can have compression+minification and modules. Even in the bad old RequireJS days when AMD loaders were state of the art there were good AMD bundlers. With modern EcmaScript 2015 modules (ES2015) there are a lot of great bundler options, Webpack being a particular darling right now, but there's also others. This sort of bundling, compression, and minification is now seen as the last step in the chain, the job of the application/website developer and no longer something that every JS library under the sun needs to do bespoke. A big reason for this is developer experience (it's easier to debug when everything is a large collection of modules), but it also makes for a better user experience (the final application knows more precisely what modules it needs to operate [tree shaking], and in what order [optimizing bundles for specific use cases/first impressions]). Overall, frontend web development is shifting to share modules with more backend operations and the node ecosystem's npm (and relatives that piggyback on it like jspm and yarn) has become the package/module management ecosystem of choice. This is great for developer experience, whether or not you are doing your backend development in Node, because you have an easier access to a larger ecosystem of libraries, an increasing number of which are "universal"/"isomorphic" running just as well in the browser as on a server running Node (or app running in Electron or an app running in Cordova). Furthermore, for some of these platforms bundling+compression+minification isn't even necessary, such as an app or server loaded directly from the filesystem instead of shipped to a browser via HTTP. Even that is changing best practices because HTTP/2 mitigates a lot of the reasons that you even need to bundle in the first place (HTTP/1.x often can only handle a single file per connection while HTTP/2 was designed from the start to bulk download a collection of files in a single connection; the connection overhead being the biggest reason to bundle in HTTP/1.x). There's a lot of great stuff to learn about the current state of the art with respect to modules and ES2015 and modern frontend development ecosystem if you thought to give it a try instead of sticking to old practices now long considered harmful (not just in JS, even, but in about any language: giant global stateful singletons like JQuery are a miserable antipattern any time they show up in any language in the history of programming).