Extra Chunks From Rollup bundling Sapper - javascript

Base on the Sapper documentation, Rollup bundles Sapper by pages. It should be one chunk per page. However, in our situation, there is more than one chunk per page. Some of the components and utility functions (not all of them, not none of them, but some) got bundled into its individual chunk.
For example with the screenshot below, AdBanner and TextExpander are components within the sapper page, but they got bundled into their own js files rather than being with the sapper page js file index.27bfb559.js.
However, looking at the sapper page js file index.27bfb559.js, SimilarDrugTable is bundled with the sapper page js file.
Essentially, what we want to achieve is one chunk per page like Sapper documentation states.

Related

what main.js should contained in vuejs project?

I'm learning nodejs and vuejs to modify an already created web site.
I installed nodejs, vue and vue-cli and I launched "npm run serve" which apparently start "vue-cli-serve serve"
The problem is that I don't understand what this web server do on files, in this documentation : https://cli.vuejs.org/guide/prototyping.html , it's told:
It automatically infers the entry file in the current directory - the entry can be one of main.js, index.js, App.vue or app.vue. You can also explicitly specify the entry file:
vue serve MyComponent.vue
Ok, but does it run main.js, does it include it into a js file which is the loaded by the index.html on the client broswer.
I see in the browser that the page load a js file named like that: app.23d...js
My question is how this js file is created?
For instance, when the content of main.js is this one:
import './css/icon.css'
Vue.use(VueResource)
Vue.use(VueScrollTo)
what is the output in the app....js file?
It seems it doesn't work at all like php which I usually use on web server
Thank you
Vue uses Webpack to convert your potentially-numerous distinct .js files into bundles with names like app.23d92ab88708...js
From the Webpack documentation:
Concepts
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.
I don't suggest trying to get into the details of how Webpack works
This will take a lot of time. If you have an existing Vue project, you are much better off spending your time interpreting that as a Vue project, and accepting that the conversion into the actual app.23d.....js file or files is an automatic process that you do not need to involve yourself in.
It will avoid a colossal waste of time
It won't advance your understanding of how the Vue project works
Whatever you learn about the exact workings of today's Webpack, may be completely wrong about tomorrow's Webpack.
Nevertheless the interface that Webpack provides to you as a Vue programmer will remain constant over future versions.
This is the concept of software abstraction. It is highly advantageous to not have to know how every step of every process works, as long as you know how it is designed to respond to actions you take at a high level.
Horrific thought
I have just re-read your opening sentence:
I'm learning nodejs and vuejs to modify an already created web site.
Please tell me that you are not trying to modify an already created web site where you only have the compiled website available, without the Vue source code? That would be a stupendously painful enterprise.

Automatic vendor chunk with dynamic code splitting

How my application is split into chunks
My applications main and only entry chunk contains some common logic that is reused throughout the application such has layouting or helper methods and components related to authentication such as login/registration dialogs. This chunk has react, react-dom, redux, react-router and some other libs from node_modules directory in its dependency tree because they are being used by the authentication components.
All those dependencies are bundled into an app.js file that is always initially loaded. Whenever the user starts to use some part of the application that requires a logged in user - such as dashboards, forms and other app functionality, additional javascript chunks comprising that functionality are loaded. Those additional chunks are automatically generated by webpack because of import() calls distributed throughout the applications code.
When a new user loads the app and is not logged in, app.js is loaded and the user is presented with a login mask. After a user has successfully logged in and is redirected to the main dashboard, the code of the dashboard is asynchronously loaded. This code, automatically built into a dashboard.js chunk by webpack, also depends on a lot of the libraries already baked into the app.js chunk (e.g. react, react-dom etc). Because the dashboard.js chunk does not duplicate those libraries, it is quite small compared to the app.js.
To make good use of browser caching, all of those chunks (in this simplified
example: the entry chunk app.js and the dynamic chunk dashboard.js) have a
[chunkhash] in their name. In comparison to library code from node_modules, both the code of the dynamic chunks and the parts of the app.js that are actual application code change quite a lot.
What i would like to do
I would like to configure webpack in a way that detects which libraries from
node_modules are used in more than 2 (or any configurable number) of chunks and
automatically split those into an additional chunk, vendor.js.
This chunk should contain the library parts of the current app.js that don't change often so the user doesn't often re-download library code.
From what i've understood, something like this can be done with
CommonsChunkPlugin when manually adding lots of entry chunks. Can i also do
this with dynamic code splitting performed with import() calls?
Example
I might use lodash.partialRight somewhere in in dashboard.js. As long as it is only used there, i want it to be bundled with dashboard.js. The moment i also use it in the login/registration process, it should not be bundled into the
app.js the way it is now but should instead automatically be bundled into vendor.js with other libraries that are re-used across chunks.
You'll have to list out the libraries that you want to be added to vendor.js explicitly. https://webpack.github.io/docs/code-splitting.html#split-app-and-vendor-code
The rest of your code and node_modules that are not listed in "vendor" will be split automatically by webpack. So the more libraries you list in
vendor: ["jquery", "underscore", ...],
the larger vendor.js file is but with less frequent re-download from your users.

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.

Categories