RequireJS: Multiple main.js? - javascript

I have been building a single page app using requireJS and so far loving it. I have come to the point of developing other parts of the site outside of the main app and am not really sure how (or if) to use requireJS for this.
In my main app everything is triggered by this script tag:
<script data-main='/scripts/main' src='/scripts/libs/require.js'>
I am now developing the home page which has it's own front end scripts. Using the optimizer when it comes to getting the site live which will bundle all these scripts into one main.js package. I am struggling to understand where the rest of my site fits into this.
Say my app is dependent on jQuery and it gets bundled up in the optimized version of the app, what if I want to use jQuery on the homepage? I don't want to load in my app's main.js just to get access to my jQuery module. So yeah... a little confused!
I am imagining a site structure sort of like this:
/scripts
- app-main.js //(includes all module dependencies after optimzation)
- home-main.js //(includes all module dependencies after optimzation)
App:
<script data-main='/scripts/app-main' src='/scripts/libs/require.js'>
Homepage:
<script data-main='/scripts/home-main' src='/scripts/libs/require.js'>
Questions
How can I use RequireJS to develop different parts of a site?
Is it recommended to have multiple main.js files?
How can my different main.js files share common modules such as jQuery post optimization?

The requirejs team has some samples for multipage applications on github.
Have a look at: https://github.com/requirejs/example-multipage
Basically you are going to have the following structure:
page1.html: page 1 of the app.
page2.html: page 2 of the app.
js app: the directory to store app-specific modules.
lib: the directory to hold third party modules, like jQuery.
common.js: contains the requirejs config, and it will be the build target for the set of common modules.
page1.js: used for the data-main for page1.html. Loads the common module, then loads app/main1, the main module for page 1.
page2.js: used for the data-main for page2.html. Loads the common module, then loads app/main2, the main module for page 2.

So require.js should always be used on any page to allow for modularity and a clean namespace. I believe each 'app' needs it's own main.js script. When optimizing your site r.js allows for you to exclude modules from the compilation which you should do for jQuery always.
That way require.js will always load jquery.js on the fly and most of the time from the cache. Finding other modules that might be cached between your app and homepage will have to be done at your own discretion and depends on the flow of your users and other factors.
It sounds like you have two projects, an app and a marketing site. I believe those should be separated to quite an extend and should have their own respective 'js' folders containing their own main.js.

Related

How to integrate Webpack in a multi-page PHP application

I'm working on an old Codeigniter website where the Javascript codebase is messy and poorly structured and I would like to use Webback to manage the scripts. My goal would be start using it to bundle the code I have the way it is, and gradually refactoring it to make use of modules and imports.
At the moment I'm using Gulp on development (but mostly to minify the files) and Carabiner (a Codeigniter library) to insert the scripts in the views.
The scripts, which are all written as IIFEs are not bundled, so in every controller function I have an array of the scripts needed in that page. For example:
public function homepage()
{
$this->carabiner->js([
['libraryThatIOnlyNeedHere.min.js'],
['myscript1.js'],
['myscript2.js'],
['myscript3.js'],
]);
I would like to use Webpack to create a series of bundles so that I end up loading maximum two files on every page: one for the libraries and one for my scripts.
All the practical examples I've seen with Webpack, though, are for Single Page Applications where it's quite easy to bundle everything together.
What would be the best approach in my case? Considering that the code is still not ready to properly use modules and imports, shall I create many entry points in the Webpack configuration file, possibly one for every page and list every script needed in that page?
Main idea behind webpack is to build modules graph from provided sources and then to combine it into bundles. If your code doesn't have explicit dependencies - it may be good idea to start with creating a module from every file using any of available approaches (AMD, CommonJS, etc). You will need to create module identifiers and define dependencies for every module. It may be worth to read this article for example.
As intermediate step you may want to use some loader like Require.JS to load your modularized code.
Until this step will be done - there is not much use of Webpack.

Angular 2 Lazy Loading

I'm trying to implement lazy loading on an application for a client. The purpose is to have a portal and load modules in the main app (portal) with dynamic paths - received from the backend, for example.
I've found a nice example here: Stackoverflow example
The problem is that I'm going to have the portal and the other applications separate. It means that I need to build all the applications (to create the dist folder with the minified js files). My question is:
Given the code bellow, how do I import the module of the other application after it's built?
this.loader.load('./src/test.module#TestModule').then((factory: NgModuleFactory<any>) => {
console.log(factory);
});
I'm going to have an index.html file, css files, vendor js files, polyfills files and the app files (all built inside the dist folder). What should I specify here './src/test.module#TestModule'? How do I load the built module?

laravel app.js very large file size

I have deployed a Laravel 5.3 application to Heroku. However, when loading /login, I noticed a very slow page load time. The problem seems to be a very large app.js file: /js/app.js. Here is a screenshot of the Network resource panel in DevTools: screenshot- Network panel. The 3rd resource from the top is the offending file.
I am not sure why this file has gotten so large. here is a link to the repository: https://github.com/AshMenhennett/Salon-Pricing.
I wasn't able to post anymore links, so do let me know if you would like direct links to specific files.
What should I be doing to mitigate this issue?
The most obvious thing you can do is to run npm run prod. This will compile the assets for production use. But in most cases, you must be looking at other solutions beyond running npm run prod. If your production file is too large, you must check your dependencies. Remove unnecessary dependencies and ensure that you don't use a lot of external libraries. For example, if you are using bootstrap, you should rely on Bootstrap's alerts in order to show alerts rather than using a Vue package to show alerts. I admit that sometimes you will need to use an external library to make your website interactive but to achieve that, you will have to sacrifice the performance. So your best bet in order to reduce the app.js file is to use the minimal external dependencies in your package.json.
The second thing you can do is use minimum HTML in your components' templates. A lot of components with heavy HTML/CSS will contribute to a larger app.js file. This is yet another approach that will result in a smaller app.js file.
Lastly, you should consider using Vue's component slots to pass HTML contents to your components. This will leave the HTML in your static files and only javascript data (API calls, props, etc.) will be compiled in the app.js file. This is an effective approach to build a smaller app.js file.
Edit: You can remove JQuery and Bootstrap scripts from the bootstrap.js file and can include these dependencies separately. It is always a good idea to have a few more scripts rather than having a very large script. i.e. browsers do parallel downloading and thus using JQuery and Bootstrap dependencies separately is a good idea.
From the looks of your link you've not created a production version of your assets, and currently all the source maps are in your app.js file, which will be adding a lot of the file size, the css and js output are also not compress/minified either.
Assuming you're using laravel elixir, you just need to run gulp --production and this will remove the source maps, compress the js and css outputs, etc.
For people that are using Laravel Mix you just need to run npm run prod to compress and remove source maps from app.js itself.
You need to load the components asynchronously
Webpack has an awesome feature to create chunks of code. The key to this is to use async components. These components get loaded completely asynchronously whenever the component is present on the page you just loaded.
Let's do it.
In resources/js/app.js
I changed
Vue.component('jobs', require('./pages/employer/jobs/Index.vue').default);
To
Vue.component('jobs', () => import('./pages/employer/jobs/Index.vue'));
and in webpack.mix.js
mix.webpackConfig({
output:{
chunkFilename:'js/vuejs_code_split/[name].js',
}
});
Now by running npm run watch or prod each component file is saved public/js/vuejs_code_split/[name].js
And the main app.js is automatically calling those components when required.

Deployment Strategy for Require JS Optimized/Concatenated Website Files

My question is partly technical and partly about deployment strategies and workflow. I built a project using Require JS. It includes a number of distinct js modules, and is built upon Kirby CMS. The directory structure of the project is something like this:
project
assets
styles
style.css
js
scripts
script1.js
script2.js
script3.js
vendor
app.js
images
fonts
content
...
kirby folders
....
The file app.js is called in the footer of my site's page like so:
<script data-main="/assets/js/app" src="/assets/js/vendor/require.js"></script>
It configures RequireJS by calling the requirejs.config() function and then calls the main script file that loads everything else using RequireJS's requirejs() function.
I've used RequireJS' s optimization tool to compile the project in such a way that the optimized files are all dumpted into a directory called dist (a name I just picked up from this tutorial). So in the end dist contains a replication of every directory and file under assets, only optimized, and the file app.js is a concatenated and optimized version of all the js modules that I have in the project. So far so good.
What I am unsure about, however, is how I'm the supposed to make use of this new secondary version of all the code. What for instance if I want to deploy a version of the site to the production server without all the source js files? Each time I deploy the site, I would need to go through my code and in every place that I referred to files under the assets directory, I would need to replace that with dist. I deploy using git and beanstalk. One way to do this would be to manage different branches for staging, production, and development, in which the production and perhaps staging branches have references to the files under dist, but this seems awkward.
So my question is given this kind of optimization set up, which if you look at the tutorial linked above is one way to do this, how then do you manage the switch to the optmized version of everything seemlessly, without having to go back into your code and change everything up? Is there some key part of the process that I'm missing here?
Each time I deploy the site, I would need to go through my code and in every place that I referred to files under the assets directory, I would need to replace that with dist.
I've looked at the tutorial you've linked to and do not see how it is true for the tutorial. The tutorial does not use absolute paths, so should be deployable from dist just as well as from the directory that contains the pre-optimization sources. If you cannot do this for your application, that's because you've done something different from the tutorial. Your script tag, for instance, shows absolute paths.
So the solution is to design your application to avoid absolute paths. This way, you won't have to change paths when you deploy from dist. I'm using this very method to deploy optimized and non-optimized versions of one of my apps.

structure for jquery in my mvc project

whats the best way of structure jqueryfiles in my mvc app.
Now i have all my scripts in script folder and it starting to be difficult to have
a good overview.
//thanks
We used the following structure on my last project:
Scripts
|
|- jQuery
|- Libraries
|- Infrastructure
|- PageSpecific
jQuery contained jQuery and any plugins. Libraries contained other third-party libraries (e.g. underscore.js). Infrastructure contained shared JavaScript modules, e.g. one full of utility functions, or one for handling server-side account-management communications, etc. PageSpecific contained code to wire up event handlers and page-specific logic.
The HTML5 Boilerplate has some minimal structure for JavaScript already. Anything I do will likely be built on top of that because there is at least a chance that another developer will have encountered it prior to hitting it in my project.
Boilerplate has a "js" subdirectory that contains all the JavaScript, another directory under that called "libs" that has just jQuery and Modernizr, and a "mylibs" directory where you're directed to put all the third party libraries (for example, the libraries for jQuery templates or Lawnchair).
js
libs
mylibs
plugins.js
script.js
They also recommend your short plugins should be concatenated in plugins.js and your basic script stuff go into script.js. Of course, that won't work for a large project, but you've at least got a start with just the js, js/libs, and js/mylibs structure. At the moment I'm using a JavaScript per HTML file with a corresponding name (blahblah.html + blahblah.js) but long term I know I'm going to need more structure than that.
Keeping your JavaScript files in the Scripts folder is the way to do it. If you want, you can use subfolders within the Scripts folder so that it's a little more organized.
It is always a good idea to keep your css files and javascripts organized within your web application.
Have two main folders 'styles' and 'scripts' in the root folder of your application.
Inside each of these folders, create sub folders that reflect specific module in your app like 'jquery', 'blueprint' etc and place those files over there.

Categories