Understanding Laravel Mix - javascript

Understanding Laravel Mix
I am currently in the process of migrating one of my websites to Laravel in order to make it a little more maintainable in future... I have plenty of experience building API's with Laravel but I have very limited experience building websites with Laravel and resultantly I am in need of a little bit of guidance from another pro.
In short, I would very much appreciate answers to the following very simple questions if anyone can spare me a couple of mins...
File based JS & CSS instead of App based
I like to write my JS and CSS files in a particular way where each page has their own specific files relevant to the page. For example, about.php might have the following dependencies:
JS:
jquery.js
any_other_third_party_library.js
app.js (global functions)
about.js (page specific functions)
CSS:
some_third_party_library.css
app.css (global styles)
about.css (page specific styles)
On my own framework, the above would be combined and minified into one file for JS and one file for CSS. From what I understand, Laravel Mix does exactly this...
However, as far as I can see, the way to do this would be as follows:
webpack.mix.js:
// About
mix.scripts([
'resources/assets/js/app.js',
'resources/assets/js/about/about.js'
], 'public/js/about/about.js');
Very simply, what I would like to know; is the above the correct way to go about this? Is there a better, more efficient, way to automate this for each page?
What are the bootstrap.js and app.js files?
From what I can see, these files just load dependencies but this is a little confusing as some dependencies might be page specific... Please can someone explain in a little further detail what these files are for? Or at least, what the difference is between them...
Getting rid of Vue
I have no interest in using Vue in my project so I have deleted the following files:
/components/Example.vue
and the Vue code in app.js
Does this matter in any way?

You'll bundle up all your styles and scripts a single file each and serve them to the client minified.
For front end assets, call mix.sass('resources/assets/sass/app.scss'). In that entry point to your styles you will be able to import your other stylesheets as you need using Sass's #import 'about'; syntax. (Rename your other CSS files to end in .scss too).
For your back end assets, call mix.js('resources/assets/js/app.js'). Then, similarly you can import other JavaScript modules using import './about.js';. You may want to look up ES2015 modules so you can learn how to write modular JavaScript.
Read through the bootstrap.js file to see how Laravel hooks up jQuery and Vue by default. You don't need any of this, so remove whatever you don't want or delete the entire file if you don't need any of it.
Vue comes out of the box with Laravel but it's just a suggestion, you can replace it with your own front end framework of choice or rip it out and replace it with nothing. Up to you.
Edit: Long story short; use mix.sass and mix.js, read up on using Sass and ES2015 modules to write awesome code.

Related

Import Vue Component only when added to blade pages

i'm starting to develop an app using Laravel, Vuejs, and blade for template engine.
Firstly, i'm new in Vuejs's world, and maybe is a simple task, but i didn't find an answer in any discussion.
The core idea is to use .blade page, and, when i need vuejs components, add them in the page passing server's data with props array. Everything's working fine, but after playing around for a bit, i've noticed one probably furure problem.
In the laravel's documentation, we register the component, or whatever Vue setting in app.js: then, using laravel mix, we boundle in a single file all the code(e.g imports, requires, different js pages...), and finally we load "app.[hash].js" in our page with a script tag. I've noticed that even only using a few vue components, app.js growing very fast(of course, we import every components in one file), even dinamically importing components and not setting them globally.
My question is: is normal to boundle all js code in a single file(having a large file), or is there a way to import vue component only when they are added in the .blade files, maybe with some sort of webpack(laravel mix) setting?
Thanks in advance for any support.
Found the solution after post the question:
Marcin and GoogleMac's answer might be both right, but i found an interesting topic about that, and i 'd want to share for anyone could have my problem. I suggest to check out this link https://alexjoverm.github.io/2017/07/16/Lazy-load-in-Vue-using-Webpack-s-code-splitting/, where they talk about code splitting.
I think this could be the best approach, mostly because even in vue's documentation talks about(detail here https://v2.vuejs.org/v2/guide/components.html#Async-Components).
My bad for haven't checked in detail documentations.
It's good to bundle js code in a single file because it's going to be downloaded only one time by the browser and cached.
JavaScript code is not that that big so don't bother yourself with it.
I agree with Marcin's answer, but if you are wanting a workaround, comment out Laravel's built in Vue registration in app.js and just use a cdn in your blade files.
You may add multiple app.js (including multiple router, vuex if needed).
Entry them separately on webpack.mix.js.
And then include suitable app.js file as needed in the blade file.
It's much easier I think if you don't want share some .js code with any user who will not use those component ever.
NB: Of course lazy loading is a solution, but that this is more convenient solution to me as I'll not deliver any component to the user who don't need it.

How to organize Vue-JS : Non Javascript way?

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".

Angular folder structure with nodejs and jade

I've been trying to figure out a folder structure that will stay effective when my project has grown, and I've found a few resources (this for example), but I don't know how I should implement this folder structure and the more I try to read about it, the more confused I get.
Right now I'm basically using the structure that express generated for me with a few small modifications, like this:
All javascript files are in src/js/*, all scss files in src/scss/*, and all jade files in views/
Grunt concats all the js files into public/js/app.js and compiles all the scss-files to css and to public/css/*. Both destinations are statically served. However, the part I don't understand is how this is supposed to work for the views. Right now, grunt doesn't touch them and they're always located in views/ where node finds them and renders them.
This works well for sorting by type, but I'm really confused about how I'd structure it by feature instead. There is probably something wrong already, but I don't know what.
Also, should I separate the server code and client code more? If so, how? Can someone provide an example of what it could look like?
Sorry if this post was confusing, I couldn't think of any better way to formulate it.
Okay, after reading a lot and trying out Yeoman, everything makes more sense to me. I was still relying on jade rendering from nodejs and I only served css/js/images statically, which made everything more complicated. I've now rewritten it and ditched Jade (although I have to say that writing Jade is 50 times nicer than html) and I'm serving everything statically.
In case anyone is in my earlier situation, try out Yeoman generator-angular to see how it sets up everything.

Ember.js - Loading additional .js-Files in some templates

Im developing a ember.js based app.
On some "sites" (templates) I want to load a specific js-game, so I have to include extra tags like <script src="game.js"></script>. But since handlebar-templates are defined by <script>-Tags itself, its not possible to simply put my dependencies within a template directly.
How can I include js-files on some individual sites only?
Including files in an Ember.js application is a bit more complex than in a regular website.
If you do not use ember-cli, then you could either include your all your JavaScript files directly in your index.html (one by one) or (and this is better) you could also bundle all your game JavaScript files into a single file (called games.js for instance) and include that single file in your index.html. You can bundle JavaScript files using tools such as grunt or brunch or broccoli.
Now if you do use ember-cli (which I recommend), then you could simply list your files in your Brocfile.js (see documentation here). Learning ember-cli might take a little bit of extra time but it will really help you in the future :)
Good luck!
Ok I found an possibility to solve that problem:
Like described in the handlebars.js-FAQ here (5.), I have to use some kind of a "Hack" to avoid parsing errors. Just need to add an empty command {{!}} into the word "script" like <scr{{!}}ipt src=...>...</scr{{!}}ipt.
That works for me.
Also, as kpdecker says here, it is better to use precompiled templates than defining them inline.
You can try to insert the necessary scripts from didInsertElement hook of the corresponding view. And, if so, in order to avoid duplicates, remove that scripts in willDestroyElement hook of the same view.

How to minify javascript file generated by liquid template generator

I'm trying to optimize the shopify website and GoogleSpeed Insights recommends me to minify css and js files.
The recommended files are all generated by liquid template generator, so I can't use the popular minify tools available.
If anyone have experience in this issue, please advise me.
Thank you.
If you try to minify such file, you will see an error because of Liquid templating code. Here is a trick which can help you to minify JavaScript files containing Liquid templating code. But this involves little manual labor.
Replace all Liquid templating code with some random unique string. Remember all the replacements. You can use a file diff app to find the difference of a .js.liquid file and the generated .js file so that it will be easy to find where you need to replace. Now you can minify this modified file without any error using any JavaScript minification tool. After the minification is over, you can replace the random unique strings with their corresponding replacements.
I am optimizing a theme for a good PageSpeed Insights score. This trick helped me to minify, combine and compress many .js.liquid files.
I haven't tested this with pagespeed, but it looks like it works html level.
In Business Catalyst I am able to do the following with liquid
{% assign allthedata = {{myData|json}} -%}
{{allthedata | remove: ' '}}
I don't know if this would affect pagespeed, but it is simple enough to try it
This removes all the spaces I have in myData.json which is generated dynamically.
https://prepros.io/
I've been using this app for like 7 months, and I absolutely love it. It can convert and compress your files.
I'm using SASS as my CSS preprocessor, and this app helps me to keep my code clean, here's my way how I make 10 files into one file and compress it:
Create 10 .sass files
Create one more .sass file where you will import all these files into one, I call it main.sass
Use prepros to import all the files into one and then convert it to main.css
So, for debugging I leave the main.css and create another css files called main-dist.css
Use prepros to compress main.css to main-dist.css.
And here you go, you got 2 different css files, one compressed and one not. You can use main.css when creating the website, for debugging purposes and later, when you're done and your website works perfectly, you can use main-dist.css and have your styles compressed.
Oh, btw I don't know how to work with Grunt or Gulp, and I love this app because of it's simplicity
P.S I'm using trial version (it's free) and planning to buy this app as soon as I get some work to do for clients.

Categories