Webpack, vue.js and component bundles separation - node.js

We are trying to build a 'pluginisable' Java webapp which use vue.js on client-side.
General description
Let say we want to get the following server-side application simplified architecture without NodeJs in production (and using Java and Osgi but it doesn't really matter here in my opinion, it may be PHP, .Net or wathever) :
A main webapp which exposes, among others : vuejs2, router and some general dependencies (bootstrap, jQuery etc...) on the client-side,
Many webapp plugins which expose, among others : additional and/or optional vue.js components and third party dependencies.
What we want
The webapp does the work to check for available webapp plugins on server-side and then expose the appropriate JS files in the index file. For example :
app.js : the main webapp loader and general dependencies,
pluginA.js : the vue.js components provided by the server-side plugin "A",
pluginB.js : the vue.js components provided by the server-side plugin "B".
The entire webapp is not build through nodejs but each of the 3 examples are built separately using node and webpack.
Constraints
How can we achieve a build process for the plugins following these constraints :
we want to avoid the javascript build process to have to conciliate all parts of the application at the same time : Checked, we have 1 embedded vue app per webapp plugin, Maven runs the node build process for each webapp plugin and the server-side already does the job to expose all of the 3 files separately,
the plugin JS files only contain the built vue components and 3rd-party dependencies that they want to provide : Not checked, all of the 3 output folders contains all the JS dependencies.
Line of thought
For each webapp plugin, we think we need to find a way to build all .vue files of a webapp plugin and exclude all other dependencies from the output file. As we are new to the node and vuejs world, how could we achieve this ?
Thanks for your help.

You may want to try code splitting:
Code splitting is the idea that a bundle [a .js file with all your Vue.js code bundled together] can be fragmented into smaller files allowing the user to only download what code they need, when they need it.
(...)
The key to code splitting a Vue.js app is async components. These are components where the component definition (including its template, data, methods etc) is loaded asynchronously.
(...)
We’ll need Webpack’s help to dynamically load [components]. (...) Webpack has an implementation [of an] import() [method] and treats it as a code split point, putting the requested module into a separate file when the bundle is created.
Source: Code Splitting With Vue.js And Webpack, a very helpful guide for implementing code splitting.
Below is the main.js code that the author of the guide ends up with to dynamically load a component. If I read the guide correctly, this change in the way you register a component is the only change necessary to implement code splitting. No changes are necessary in your Webpack config.
new Vue({
el: '#app',
components: {
ExampleAsyncComponent: () => import('./ExampleAsyncComponent.vue') /* This is the changed part. */
}
});

Related

How to aliasing Preact with Webpack?

Preact guide says
To alias any package in webpack, you need to add the resolve.alias section to your config. Depending on the configuration you're using, this section may already be present, but missing the aliases for Preact.
But using any of the official templates (default, typescript, material web components, etc...) doesn't generate any webpack.config.js file and preact has no eject command like react to access the full project configuration.
So, few things:
Firstly, Preact and Preact-CLI are two separate items.
You're quoting the section from our docs labeled "Integrating into an existing pipeline". This means adding Preact to an existing React application of yours, but, if you're using one of our templates, then this is a new project, not an existing one.
preact has no eject command like react to access the full project configuration.
There is no way to "eject" React. What you're referring to is the build tool called "Create React App".
We do allow for full configuration of the Webpack config with a preact.config.js. With this, you can edit any parts of the config that you'd like: change plugin options, add loaders, remove plugins, etc., without owning the configuration yourself. You can just comment out your changes in your config and you're back to the default config.
We believe CRA's "eject" is a poor API and therefore don't match it.

Building monorepo babel-transpiled node JS application with dependencies

I am working on a project that is hosted as a monorepo. For simplification purposes let's say that inside there are three self-explanatory packages: server, a webapp client and library. The directory structure would be something like the following:
the-project
packages
server
src
webapp
src
library
src
All packages employ flow type notation, use a few >ES5 features and, for this reason, go through babel transpilation. The key difference is that transpilation of the webapp package is done via webpack, whereas server employs a gulp task that triggers script transpilation through the gulp-babel package. library is transpiled automatically when web is built.
Now, the problem I have is that for server to build, babel requires library to be built first and its package.json to specify its (built) main JS source file so its transpiled artifacts can be included. As you can imagine, this would quickly become problematic if the project were to contain multiple libraries that are actively being developed (which it does), as all would require building, including any dependent packages (like server in this simple case).
As an attempt to overcome this annoyance, I initially thought of using webpack to build the server, which would take care of including whatever dependencies it requires into a bundle, but I ran into issues as apparently webpack is not meant to be used on node JS applications.
What strategies are available for building a node JS application requiring Babel transpilation, such that the application's source files as well as any dependencies are built transparently and contained in a single output directory?
Annex A
Simplified gulp task for transpilation of scripts, as employed by server.
return gulp
.src([`src/**/*.js`], { allowEmpty: true })
.pipe(babel({ sourceMap: true }))
.pipe(gulp.dest('dist'));
As can be seen above, only server's own source files are included in the task. If src were to be changed to also include library, the task would emit the dependencies' artifacts in server's own output directory and any require('library') statements within would attempt to locate the built artifacts in packages/library and not packages/server/dist, thus resulting in import failures.
First of all, I am not sure what your server is doing. If it is doing a database connection or some calculations then I would not recommend it to be built by webpack. Whereas If your server is just doing Server-Side Rendering and making some API calls to other servers then I would recommend it to be bundled using webpack.
A lot of projects follow this philosophy. For example, you can take a look at something similar, I have done in one of my personal projects [Blubus]. Specifically, you might be interested in webpack-server-config. And also you can take a look at how big projects like spectrum does it.

Best practices to develop VueJS app with Webpack, SASS, NPM ...?

I am writing application by using Python/Flask as the API back-end, and want to separate the front-end (browser-based) as an individual project (VueJS). I've read about Webpack, but I can't find any best practice to start, such as: can we use NPM to manage dependencies, use webpack for front-end not using an Node app as an entry ...
Thanks alot
WebPack isn't a framework.
It's something that a task runner.
Exemple: You use SASS, you want something that compile all your sass file in CSS file. You create a task and webpack have a task now. And you can ask him to automaticaly compile the file when change.
Maybe what you want it's more have two project:
One who handle the data an may available with an api
One who is the web ui for the user who get the data and format it in a beautifull UI
Webpack won't be your solution. Continue with your VueJS and look at VueX for your data handling browser side.

Angular2 deploying to production environment questions

Some questions to put angular2 web project to production environment
We do development on lite server but what is best for production? Is is some other server module of nodejs? Technically we can have any server (apache, tomcat, etc).
How should we do source code management for below context.
browser must include js files so project should have js files when deployed
In standard java project we just commit .java files and uses jenkins (may be other tools) to compile and make the deploy-able structure
Should we follow same strategy here? i.e. don't commit compiled js files and deploy using some node compiler which takes ts files and compiles it to js
What is the best way to minify/obfuscate the js files
I know a way using outDir and outFile with grump but I don't want every files tobe included in one minified file because it kills the concept of lazy loading
Is there a way to minify and obfuscate js files on compile time only?
What enableProdMode() do? How it is different than not using it?
Here are some answers to your questions:
Angular2 applications only consist of static files so they can be serve by any static Web servers or server applications that can define static folders (Express, ...)
Regarding source code management, you must have a packaging phase to optimize the application loading (gater files, uglify, ...). Your source code must contain your TypeScript files (or JS files if using ES5 or ES6). Such packaging can be done using Gulp for example. Your Jenkins server will be able to checkout the source code, build it and execute tests.
In fact, when not using the outFile property of the TypeScript compiler, you won't be able to gather all the JS compiled files into a single one since anonymous modules will be created within each JS files.
See this question for more details of this:
How do I actually deploy an Angular 2 + Typescript + systemjs app?
Regarding prod mode, here is an extract of the documentation:
Disable Angular's development mode, which turns off assertions and other checks within the framework.
One important assertion this disables verifies that a change detection pass does not result in additional changes to any bindings (also known as unidirectional data flow).

using requirejs without main file nor config()

I'm building an app that will contain many js (jquery) modules (files) using the following setup;
The build is run using Grunt task runner.
I use handlebars templates, then generate the html from *.hbs files.
During the build, I uglify all the js files into one minified file.
I call the minified file in my application <script src="assets/js/app.min.js"></script>
Now, I want to use requirejs to organize my code and adhere to the AMD specifications..
But I got 3 problems with this approach:
I need to have 1 single minified file for all the js; this keeps my code harder to "decode" thus to copy (since it is mixed with other dependencies; jquery, modernizer..) and also helps avoid extra http requests if scripts are called individually.. However, requirejs needs a main file to initialize the app and inside that main file It calls the other required files.. I don't have such configuration.
Many of the dependencies I'm using are in a bower package (that I don't include in the distribution); this makes it not possible to call those files using the suggested requirejs method.
I'm using jquery on this with some 3rd party plugins that don't call define(); to make them work I have to use shim config which again rises the problem #2!
So how am I supposed to take advantage of requirejs while keeping my code in modules and well organized?
Sorry for the long question and thanks for reading :)
ps: Feel free to change the title of the question as I couldn't find a better one!
I finally opted for AngularJS as it adheres to my setup above and allows me to split my app into manageable small modules.
I have also the possibility to use the ease of jQuery (even though it is not a best practice among angular community) and much more.

Resources