Webpack: Bundle several js framework into one bundle? - javascript

I'm trying to understand the purpose of webpack. I'm intending to use fixed-data-table from React and it has to be processed through webpack and transformed with Babel as it uses require function which otherwise can't be processed by the browser.
To output a bundle.js file, could I include, say, several frameworks in one bundle? I.e. Bootstrap, React, React-dom, and other frameworks? As far as I can tell in the documentation, you can only input one .js file and process it into a bundle.js - or am I wrong? Are there examples of importing several frameworks into one webpack configuration file, and outputting just one Bundle.js? I haven't been able to google myself to that point. Seems like most people process just one framework to one bundle, which doesn't seem intuitive to me.

Webpack, literally takes all your dependencies and mashes it into one big file known as the ultimate bundle.js
There is no limit (other than the space of your hard drive) to how many frameworks you can include in one bundle, Webpack just needs to be aware that this dependency is in use and needs to be required. Depending on your build configurations, Webpack should find these immediately after traversing your directory.
The easiest method is to register the framework via. require or import call in your Babel ES6 files. If this is not possible, I suggest reading the documentation on RequireJS that is an alternate method to register them.

Related

How could I write a Webpack plugin that updates `resolve.modules` and `resolve.alias` in `--watch` mode at runtime?

I work in a large monorepo that has very many files that are processed by Webpack. One of our main patterns is that we use fully-qualified filenames for every module name and import. For example, if I have a file with path "/path/to/module/MyCoolModule.js", the import would simply look like import MyCoolModule from 'MyCoolModule' without needing any explicit path to the module. This is enabled by recursively scanning the project's directories for all relevant .js files/folders at Webpack init and then passing in the scanned files into resolve.modules and resolve.alias.
We like this pattern, and it works well for general usage when webpack is run in watch mode; however, it breaks down when new folders and files are added to the project while Webpack is already running. Because the files and folders are only scanned at Webpack init, Webpack is unable to resolve imports for new files/folders added since it started, so compilation will fail. This requires us to restart Webpack, which takes 1-2 minutes on our project. Across many engineers when switching between git branches or updating changes from master, this can add up to a significant slowdown in raw time and in breaking flow.
I'd like to write a plugin that will dynamically update the resolve.modules and resolve.alias such that we do not have to restart Webpack when new folders and files are added to the project. However, I am at a loss for how to do this. It seems like I have three main questions:
What hook(s) can I tap into to be notified when Webpack detects new files or folders?
Where would I put this plugin to access the above hooks? Would it exist in the top-level plugins config? resolve.plugins? etc.. As I'm understanding it, where the plugin is placed/configured will affect what hooks are available to it
How would I make Webpack aware of these dynamic updates? I am guessing there's a reference to the resolve obj somewhere that holds resolve.modules and resolve.aliases that Webpack actively references, but I'm not sure where that would live or where to access it (this could be completely wrong too)
(note: we are technically using Webpack 4, but answers for Webpack 5 are welcomed because I know we're behind there, and I'd guess a Webpack 5 solution would still point me in the right direction)
Thanks!

Splitting my Webpack bundle is causing JS issues

I'm using Webpack in a fairly simple, straightforward way that bundles together a few JS and TS files into one bundle, and it works well on my site.
However, I want to split the current bundle into smaller bundles, as I get both a warning when I build the bundle due to it's size, and I get warnings running Lighthouse audits in browser that I should reduce the file size of my bundle.js file.
The simplest solution in my mind is to split my current bundle into 4 parts, i.e. bundle1.min.js, bundle2.min.js, etc... Then I just serve the bundles consecutively.
The problem is splitting and serving my bundle this way is breaking other JS on my page. For example a function defined in bundle1 and called in a different JS file no longer works, unless I remove all the other bundle.js files. It seems that only the most recently loaded bundle file works.
Is there a better approach to get smaller bundles, and make sure that all bundles work correctly?
Route-based code splitting is quite popular because each page/route usually has a small subset of components on it.
The guide can be found here (for React)
A little embarrassed, looks like this was just a scoping issue with a dependency in one bundle breaking code in another by being absent. Reorganizing my bundles so dependencies are present where needed. Ai ya.

Javascript bundling and module loading

I've recently been thrown in to clean up a project which has like 45-50 individual .js javascript files. I wonder what the best approach would be to decrease the loading size of them all. Just concatenate all files into one with npm or gulp? Install some module loader? webpack?
If you're already concatenating, minifying, and uglifying and you don't want all the files to be loaded on all the pages due to a monolithic bundle, you might be looking for something like Webpack's Commons Chunk Plugin.
This plugin walks down the tree of dependencies for each endpoint defined in your Webpack.config file and determines which modules are required across all pages. It then breaks the code into two bundles, a "common" bundle containing the modules that every page requires, which you must load with a script tag on each page:
<script src="commons.js" charset="utf-8"></script>
And an endpoint bundle for each individual page that you reference normally in a script tag placed after the commons script tag:
<script src="specificpage.bundle.js" charset="utf-8"></script>
The result is that an individual page will not have to load modules that will only ever be used on other pages.
Again, this is a Webpack plugin. I don't know if this functionality is available as a Gulp plugin, because it must have knowledge of all endpoints in order to determine which dependencies are common to them all.
I redirect you to the very good https://github.com/thedaviddias/Front-End-Checklist
In particular the following advises:
JavaScript Inline: High You don't have any JavaScript code inline
(mixed with your HTML code).
Concatenation: High JavaScript files
are concatenated.
Minification: High JavaScript files are minified (you can add the .min suffix).
You can accomplish this with a package manager such as gulp, grunt or webpack (for the most famous ones). You just need to choose what you prefer to use.
If you consider webpack, You can start with my very simple (but understanding) starter: https://github.com/dfa1234/snippets-starter
There's no much thing that you can do, basically is:
Concatenation - https://www.npmjs.com/package/gulp-concat
Minification - https://www.npmjs.com/package/gulp-minify
Instead of creating all those scripts, you can get something to re-use on yeoman, f.e. the Fountain, so it will reduce a lot of time just typing procedural code for doing the concatenation/minification.
Also if you can use some lazy load (like RequireJS or some frameworks have support to lazy load the module, like Angular) that will improve the performance of your aplication
EDIT:
If you want even more performance, you can install some compression tool in your server, for example this one for NodeJS https://www.npmjs.com/package/compression
I'm my personal opinion, if you have time, the best approach would be to read and understand the purpose of the project. Then plan a proper refactor. You are not fixing anything with concatenating, this is just a deployment step.
You should analyze which technologies are being used and if you want to maintain this code, in the long run, make a proper refactor into a much more modern stack, maybe you can take a seed project with ES6, webpack, Babel... and create a proper repository well maintained with proper modularity and dependencies resolution.
Once you have that, decreasing the load its just about adding proper tools in build time (babel, webpack, etc).
You would like to add some unit tests and continue working properly :)

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.

webpack build to multiple files

I have web pack application and want to build output multiple files not a single javascript file. for example if I have such folder structure
components
1.js
2.js
actions
1.js.
2.js
my webpack build have to compile files in same folder structure. How i can achieve that?
I tried babel cli:
babel ./src --out-dir ./lib --source-maps --presets es2015,react --plugins babel-plugin-add-module-exports,babel-plugin-transform-decorators-legacy,babel-plugin-transform-class-properties --watch
It outputs files as I wanted but getting error
Cannot resolve module
Because it does not know anything about webpack resolve.
Any suggestions?
Getting webpack to output multiple files is possible but it does have limitations. First it's important to understand how this works. Webpack actually provides a runtime script that can load code "chunks" as they are needed, this is important for large applications so the user doesn't have to download the javascript for the entire app just to see the homepage. But webpack needs to keep track of these chunks and what they're named at build time to be able to load them correctly at run time. For that reason it has it's own file naming conventions to enable this functionality. See more here: https://webpack.js.org/guides/code-splitting/. So you can require.ensure all of your deps, but they won't be named and foldered they way you describe as webpack's runtime wouldn't be able to find them in that case.
The other thing that's important to consider is that webpack is a bundler, so it's meant to bundle files. Essentially your saying you don't want to bundle your files. So if that's the case, you should probably look into using require.js. Many people have moved from require to bundlers such as Wepback and Browserify as typically it's not efficient to download every little module seperately. But, every app is different so you may in fact have a good reason to not bundle.
If you do in fact want to do some bundling but want to optimize how it's done, then I can help with that as well, and webpack is certainly a great tool for that. But I'll need to understand your use case a little more to give the best advice.

Categories