The project structure:
Under the ui.apps folder, where we want to keep all our components and their code, we have two main configuration folders: webpack.core and webpack.project.
webpack.core
This folder will keep all our build configuration files meaning: webpack.config files, aemsync settings, clientlib configs, etc. To make things easy to maintain we keep all the config files split in the internals folder. Don't worry we'll pick them up one by one.
webpack.config.js
This file mainly consists in a switch case to correctly consume the correct build configuration for our environments (dev / devenv / prod)
webpack.config.dev.js
The configuration file for the development (local) environment. Source-maps, clientlib configs, webpack code splitting (dynamic imports), everything is configured here for the ease of local development
webpack.config.devenv.js
The configuration for the remote development environment. Usually we, as developers, have a development environment where we can test and debug our code before deploying it to a pre-production or production environment. This configuration is what you need to run on such an environment. The bundled code will not be minified and will have the source maps included so we can easily debug and quickly fix any potential issue in the early development stages.
webpack.config.prod.js
This is the configuration file for production. All the files will be fully optimized, and minified, no source maps or development features enabled. This should be the default build configuration for the entire frontend of our AEM program.
clientlib.config.dev.js
Here we define the clientlib configuration for our local development and remote development environments. This configuration should have all the clientlibs that webpack generated (all the main bundles that should be deferred globally in our head section). We should define our webpack-generated main clientlib categories here. In this example, we used a wknd.webpack.**
convention so that we can easily distinguish between other potential clientlibs that we might include.
aemsync.js
Are you one of the AEM developers that used aemsync (aemfed, aem-front are built on the same aemsync) and suddenly got his/her instance destroyed? Evrika! That's why! :)
We usually run aemsync and forget about it and that's the root cause of our problem. Our IDEs are really smart these days, they are constantly indexing our code-writing behavior so that they can help us do fewer mistakes and write better code. Aemsync package sometimes detects these indexing as changes and it triggers changes on very important nodes in AEM which cause our AEM instance to explode.
This file has some filters to prevent any unexpected syncs that can destroy and make us reinstall our AEM instance. Please review these filters as they are specific to each project structure. I would recommend adding here any sensitive path from your root project.
I won't go into that many details for the rest of the files, but just to mention:
babel.config.js
Babel configuration here we can configure the javascript version we want the output to be.
eslint.config.js
Configurations for the javascript linter (avoid human errors).
stylelint.config.js
Linter configuration for our scss/css files.
kill-node.js
This is useful for Windows machines, when we close our local development server, this script will kill all the node processes so that we ensure to kill aemsync (basically when we use ctrl + c
to close the watchers)
I will talk about package.json
in the next articles, where I will explain also the scripts defined there.
webpack.project
The folder where we maintain our webpack entries -> here we control exactly what bundles webpack will build, the AEM clientlibs will then consume these bundles. In our case, we have authoring.js
, components.js
and global.js
.
authoring.js
Will resolve all the index.js files that exist in a webpack.authoring folder, matching the regular expression for a given path (in this case, './../../src/main/content/jcr_root/apps/wknd/'
):
/\/webpack\.authoring\/index\.js$/ ;
components.js
Will resolve all the index.js files that exist in a webpack.module
folder, matching the regular expression for a given path:
/\/webpack\.module\/index\.js$/ ;
global.js
Will resolve all the index.js files that exist in a webpack.global
folder, matching the regular expression for a given path:
/\/webpack\.global\/index\.js$/ ;
All these files are referenced in the index.js
file as entries. Each of these files will result in a webpack bundle which will be configured as AEM clientlibs and will be included in our head
tag.
Enough for today, get some rest! I do need after writing this article! :))
Note 1: I know I'm not the best technical content writer, but I'm trying to improve myself. The articles may seem confusing, so please leave me only lousy feedback! I will improve and I will try to adapt the articles so that as many developers can understand them better.
Note 2: I recommend always following the code on my github page.
Note 3: If the articles don't match anymore the content here, please let me know. I'll try to maintain the content when I'll do changes but I might be lazy or I'll forget - that " I'll do it later" that has an infinite "later".
Note 4: The code is here: https://github.com/LeheneTudor/aem-webpack-wknd
Note 5: The code is not perfect and will never be (there's no "perfect" code) but I will always try to commit completed code that successfully compiles and behaves as expected. ✌️