Is there a way to not have to build my app every time I want to run it? It is impossible to debug once it is compiled. I have seen in videos the browser loads 100s of js files instead of one big build.js.
What do I need to change to make this happen?
This is a downfall in working with modern things like React, but the answer is to use something like webpack. Webpack is able to generate the single file, but generate source maps with it as well. Browser tools are then able to map the single build file to the original source code, making it much easier to debug. Browserify has this ability as well, which you can use along side gulp or grunt, along with babel to compile ES6.
I'd recommend checking out webpack though, as it's becoming more commonplace. Personally I find it a bit tricky to figure out, but once you have it running, it's great. I don't have a good example handy on using webpack with react, but there are a number of articles & tutorials out there on the subject: https://www.codementor.io/reactjs/tutorial/beginner-guide-setup-reactjs-environment-npm-babel-6-webpack
Related
Not specifically a Rails question, but a question within a Rails app.
In my app I am using the jsbundling-rails gem configured with esbuild.
This gem adds a build line to my package.json file. It works and compiles all my JS and runs fine. However, I found that the generated file is rather large so I started looking at ways to optimise it.
My esbuild statement at this point looks like:
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds"
Firstly I thought I could try making my imports conditional. Eg, only import them when they are actually required. I asked another question on how to do that here.
I learned quite a lot digging into that, but at the end of the day it's made no difference to the output of my JS weirdly.
Chrome currently says that my main JS file has 91% code unused. It looks like all the imports are still being compiled together, whether they are statically or dynamically imported. Why can this be?
I then looked further into esbuild, I spotted the --splitting flag. It sounded reasonably correct so I updated my build script to be:
"build": "esbuild app/javascript/*.* --bundle --splitting --format=esm --sourcemap --outdir=app/assets/builds"
This caused a huge amount of outputted JS files (I think they are referred to as "chunks".
I ran my app, and the JS failed to load. The console stated that
Uncaught SyntaxError: Cannot use import statement outside a module
I wasn't 100% sure why was the case but I just guessed that I needed to add type: "module" to my javascript_include_tag in my Rails application layout view.
This made the JS load (which is good :-) )
BUT... The percentage of unused JS code is still 84% of my application.js
So..... my questions are as follows:
Are my dynamic importing of modules working?
Why does static or dynamic importing appear to make no difference?
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
This all started because I ran Google's Lighthouse test on my site and it reported my Structure and Accessibility to be practically perfect but performance was < 40. I am aiming to solve this.
I look forward to hearing from you with ideas on how I can try to fix this and improve my Lighthouse Performance score.
Are my dynamic importing of modules working? Why does static or
The paradigm you want is called Propshaft. Try looking at the SProckets -> Propshaft
https://github.com/rails/propshaft/blob/main/UPGRADING.md
Why dynamic importing appear to make no difference?
Because even though ESBuild allows for ES Module syntax (import statements), it still bundles everything into "1" big file. (1 big file for each javascript_include_tag you have, of course).
How can I effectively reduce the size of the output code and reduce the unused percentage of JS on my home page?
The sprockets paradigm was built for the HTTP1 web when keeping connections open and progressive download wasn't realistic. HTTP2 changed all that and now it's more efficient to do code splitting as you want to do. But the Rails world is still very behind and most apps still use Sprockets and try to optimize/minify was much as possible.
I'd recommend you take this course of action:
(1) Try the old-style way first. Remove anything unnecessary, split your app into different sections and load different manifest files for different sections. Use minification. See how far that gets you.
(2) Start experimenting with the new Propshaft for a few weeks until you fully understand it. If you feel it is solid, migrate to that.
I'm using create react-app and noticed that with my builds the client can see my exact code as I see it when I'm editing. I would like to prevent this to (at least a little bit) deter clients from easily cheating in my game. If they can see how everything works that easily, they will be more likely to alter the client code. When I go to Facebook.com which uses React, I see that in Chrome source inspector I can't access the clean neat files, just a bunch of code jammed together. How can I achieve this with create-react-app? Also, how can I remove the comments before I build? I assumed, when I built this would happen, because why would the client need to see your comments, but it does not.
When you run react in the development mode using the create-react-app, the source code is not optimized for production. It offers more development purposes.
You need to run yarn build to get the optimized version which will be minified and uglified as you like which will give you some amount of code hiding ability.
How to organize Vue-JS project [files and directory]: Non Javascript way?
Coming from a non-javascript background, I found Vue.js very intuitive and easy to use. My earlier experience in Javascript is with JQuery and vanilla javascript on the browser.
I created an application using Vue , Vue-components and vue router. Everything works fine.
My problem is, I have ended up writing a lot of code in a single index.html file of my project. This file contains over 10 templates that I have created and attached to different component in my app. I want to know that is there a non-javascript way to organize these templates in seperate files.
I see that there are options using webpack and browserify to modularize the project. But coming from non javascript background, I don't find them intuitive. I don't want to go node - npm way because that has its own learning curve and moreover it downloads a dozen of files and dependencies in my project which I don't understand. I am old school and more comfortable downloading the files and including them in the webpages.
So probably, you understand where I am going to. I need a solution where I could put my templates as separate files and read those files in the different components.
What I have tried :
Declaring the templates inside my components. But writing all that html inside the component is not that clean. It also, makes my JS file too huge. I am better in putting all data in the index.html instead.
Storing template as smaller chunk "homepage.html","about.html" and in my components, using $.get / $.load to read different components in ready function of the component. This works but I still have to fire an additional ajax call for each component which is not efficient.
Please refrain from suggesting the obvious node-npm [webpack and browserify] way. I know thats what is supported by Vue but this needs a learning curve and complete setup. Answer to this question would actually help other developers who hesitate going the node-npm way.
Please shout back if you need more clarifications to the question.
The options you've mentioned are your only real ones... the HTML of the template needs to be available when it's needed, so you either have to have it within your html file off the bat, or load it using AJAX or an in-browser loader like RequireJS (and this extension that allows it to load HTML https://github.com/requirejs/text).
In-file templates make sense for very small projects. As your project grows, you'll need to start using the tools that are built for this. NPM rocks and every JS package that you'll ever need can be included in your project in seconds.
I highly encourage you to try the Vue CLI
It does use node, npm, webpack and downloads dozens of files. Which you've you've explicitly asked for not to use, so let me clarify:
The Vue CLI takes care of the complexity and configures webpack for you.
You don't even have to know it's using webpack.
It's very developer friendly (it even has a built-in gui) and lowers the barrier to entry compared configuring a webpack config.
I hope you'll also find it "intuitive and easy to use".
I'm very keen to make use of some build techniques in my Javascript/Web App development such as
Concatentation
Minification
Image replacement with data:uri's
Build vs Source *
App Cache Manifest generation *
It's those last two that I haven't found an answer for yet.
Build vs Source
By this I mean having a "source" version of my HTML and Javascript that is untouched so that I do not have to build each time to preview a change. All of my JS files are separate <script> tags as usual with the build vs updating these script sections with the final concatenated versions. To be honest I feel like I'm missing something here with all of these new Javascript build systems as this seems like an obvious need but I can't find anyone else talking about it. How is everyone else dealing with this?.. Build on each change during development?? surely not.
App Cache Manifest generation
This explains itself - walk through my source tree and build up a manifest and insert it into my <html> tag.
I've searched for these two with no luck - any pointers?
I'd be on the road with a killer build system if it wasn't for those two.
Thanks!!!
Re: Build vs Source
It sounds like you're already familiar with grunt. You may want to consider looking into the grunt node-build-script plugin.
It adds a number of new tasks, notably grunt mkdirs and grunt copy which duplicates your project directory into a separate staging folder and then copies your optimised project into a publish folder. If I'm not mistaken, this is what you mean by keeping an 'untouched' version of your source files?
Running grunt server will then serve up the contents of your publish files on localhost. You could always point your web server to your initial project directory if you want to examine your application in its unoptimised state.
node-build-script adds a bunch of other super convenient tasks, such as image optimisation, automatic file revving and substitution. It's incredibly easy to use and super customisable.
I have a basic single page template which uses node-build-script which also may be of interest.
Re: App Cache Manifest generation
I believe this used to be part of node-build-script but was since removed, see 1, 2
There would be nothing stopping you from creating a custom grunt task that utilised something like confess.js however.
Finally, it looks like Google's upcoming Yeoman might be worth keeping an eye on if you're not already!
I've developing JavaScript since many years but have never really thought about the whole testing, developing and building stuff - but I realized it's pretty much necessary. We've just used a Subversion repository with simple release tagging (switching to git soon). As a new bigger pure JavaScript project (using jQuery) is arriving soon, I'd like to optimize the whole process.
I already did some research but never found a good starting tutorial.
It's definetly a good idea to split classes and separate code blocks into several js-files and not a big one (as Prototype or jQuery do it). These js-files must be "build" into a single file. How do I achieve that?
It's pretty much necessary to Unit-test the stuff me and my colleagues are coding. I found the js-test-driver which has an eclipse plugin that seems to be doing his job quite good. If my developer-folder contains all these src- and src-test-files, how do I integrate this in the building process?
For testing, take a look at this: https://stackoverflow.com/questions/32809/javascript-unit-testing
For merging all of your JavaScript into one file you can use something like YUI Compressor. You need to be looking for a minimizer first, compression second. A minimizer just takes the files and merges them together and gets rid of whitespace. A compressor will actually try to optimize the js for you by changing variable names and removing unnecessary code.
As for unit testing I am unsure of how you will want to do that. There are a few unit test libraries out there. A popular tool for testing is Selenium. I don't currently do unit testing so I am out of my element there..
For setting up your code you could always look at using a JavaScript framework like ExtJS or JavaScriptMVC. Those help you with setting up your code in the proper way and also helps focus your team on the proper standards and coding structure while also writing a lot of the code for you so you don't have to re-invent the wheel.
EDIT: Just a quick after thought. Even if you don't want to use a JavaScript framework, I would suggest checking them out, especially ExtJS, just to see how they organize their code and some of the tricks they do to keep it clean.
I'll answer part of your question:
These js-files must be "build" into a
single file.
This is possible only with server side language - in ASP.NET you have built in tools for that, otherwise build your own "merger" server side file and reference that file instead of the actual .js files.
These js-files must be "build" into a single file. How do I achieve that?
Definitely keep your files separate in version control, and only merge them during the build process.
The YUI compressor mentioned elsewhere is a java-based tool that will not only merge but -- of course! -- compress your files for faster download.
If you just want a simple merge of files, a simple Perl or bash-script (or other preferred scripting language) could concatenate multiple .js files into one for release -- just make sure that the build script also updates all HTML in the release to reference only the single page.