webpack build to multiple files - javascript

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.

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!

Javascript modules, loaders, bundlers and package managers confusion

I don't get all the connections. Where do they resides and what is the impact of their usage. Are any of following statments correct?
the loader will reside in browser(after loaded)? So when the main app javascript needs some module it will load it behind the scenes
if I use bundler(command line tool) it will create one file from all of my modules(and all common ones used), so no async loading, as there is only the big bundled.js?
why do I need for example bower.json and package.json in the same project(is npm used just to download build utilities)
from where do they take the modules (npm repository or all have its own?)
package managers are just to download the modules to your project for further processing
npm modules holds only .js files
you always needs way to orchastrate the build(gulp, grunt, npm scripts)
So far I have not found resource with information like : packagers do that, loaders do that.
the loader will reside in browser(after loaded)? So when the main app javascript needs some module it will load it behind the scenes
Loaders is a webpack feature, these loaders are used to process code that webpack does not understand by default (css, sass, images, etc.). They are just used when your code is compiled, when you publish your code it does not contains loaders with it. Loaders just run during build time.
--> Edit: this does not apply to the question since the question refeers to require.js for example, but still relevant overall.
if I use bundler(command line tool) it will create one file from all of my modules(and all common ones used), so no async loading, as there is only the big bundled.js?
You can have prefetch, prelight, you can load chunks (pieces of your bundle) only when required (look for code splitting using dynamic import import(...). This makes the code be loadede/requested only when it is going to be loaded.
why do I need for example bower.json and package.json in the same project(is npm used just to download build utilities)
Nowadays you don't need bower, most (if not all) the things that bower has you can find on the npm repositories.
from where do they take the modules (npm repository or all have its own?)
Every package you download was uploaded to npm, you can look at npm as a "github" but for libraries.
packagers are just to download the modules to your project for further processing
Yes
npm modules holds only .js files
False, look at bootstrap.
you always needs way to orchastrate the build(gulp, grunt, npm scripts)
Yes, but if you want to transpile content, you can use only babel-cli.

Webpack 2: Watch external files

I have a project that uses source files external to the project. Effectively, there is the actual project source code (an Typescript/Angular 2 application, lets call it the 'core' stuff), and this is a generic web application that is meant to be the base code that consumes these external source files.
The external files include additional stuff-- that could be SCSS files, images, evn additional JS. The way I want this to work is that webpack copies these external files from any source directory (this is critical, it is not part of the core project) to a local .tmp directory. The files in the .tmp directory are worked on along with the core src files to generate the prod output.
I can't figure out how to add these additional external source files to the watch list. Effectively what I'm looking to do is watch that directory and as things change, it re-copies the affected files to the local .tmp directory and triggers a recompile.
Presently I have to restart webpack and have a very very ugly solution using Grunt to watch the additional files. It's nasty but these kinds of workarounds have historically been what I've had to do with webpack.
Does anyone have a better solution? Ideally I'd like to not have to mix grunt with webpack. Webpack should be able to do this, but its hard to know whether there's an existing plugin for this or what the best approach would be.
Also, please spare the "look for it on google" or "read the docs" comments. I've combed through it all, hard, and have not found anything.
Thanks in advance.
As of now Webpack doesn't watch external files out-of-the-box . You need a plugin for that.
Basically idea is to have a file watcher module chokidar / watch , listening to the file change , and when there is a change, restart the webpack compilation phase . Webpack plugins can access the compilation object and we you need to hook it to a compiler phase i.e. 'emit' , 'after-emit' etc.
This Webpack plugin exactly solves your problem - https://www.npmjs.com/package/filewatcher-webpack-plugin .

What is "npm run build" in create-react-app?

I could not find any explanation regarding the work of "npm run build",
It is simple and easy to use and i get the "build" folder that works great,
But, in create-react-app, what happens exactly behind the scene?
Is it a complete different use of a build tool?
If not, is it utilizing other build tools?
Developers often break JavaScript and CSS out into separate files. Separate files let you focus on writing more modular chunks of code that do one single thing. Files that do one thing decrease your cognitive load as maintaining them is a quite cumbersome task.
What happens exactly behind the scene?
When it’s time to move your app to production, having multiple JavaScript or CSS files isn’t ideal. When a user visits your site, each of your files will require an additional HTTP request, making your site slower to load.
So to remedy this, you can create a “build” of our app, which merges all your CSS files into one file, and does the same with your JavaScript. This way, you minimize the number and size of files the user gets. To create this “build”, you use a “build tool”. Hence the use of npm run build.
As you have rightly mentioned that running the command (npm run build) creates you a build directory. Now suppose you have a bunch of CSS and JS files in your app:
css/
mpp.css
design.css
visuals.css
...
js/
service.js
validator.js
container.js
...
After you run npm run build your build directory will be:
build/
static/
css/
main.css
js/
main.js
Now your app has very few files. The app is still the same but got compacted to a small package called build.
Final Verdict:
You might wonder why a build is even worth it, if all it does is save your users a few milliseconds of load time. Well, if you’re making a site just for yourself or a few other people, you don’t have to bother with this. Generating a build of your project is only necessary for high traffic sites (or sites that you hope will be high traffic soon).
If you’re just learning development, or only making sites with very low traffic, generating a build might not be worth your time.
It's briefly explained here: https://github.com/facebookincubator/create-react-app#npm-run-build-or-yarn-build.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Behind the scenes, it uses babel to transpile your code and webpack as the build tool to bundle up your application.

Webpack: Bundle several js framework into one bundle?

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.

Categories