Introduction
This is a note on Webpack & Maven.
Background
The Webpack has been a recent popular web development tool, Maven has been a popular application building and packaging tool for more than a decade. In this note, I will talk about the following two problems.
- How to use Maven to initiate the Webpack and put the bundles to the right place in the project for Maven to further pack it into the WAR file.
- How to address some problems with the IDE. In this note, I will only talk about Eclipse.
The attached is a simple Webpack style Vue application. I will use Maven to initiate the Webpack and put the bundle into the "WebContent" folder for Maven to further package it into the WAR file. There are many ways for Maven to run Webpack and I will use the "frontend-maven-plugin" in this note.
The "Vue-app"
The Vue application is identical to the example in my earlier note. This note is about Webpack & Maven, but not Webpack itself. I will not spend much time on the example. If you are interested, you can check out my earlier note, or even better, check out the Vue official document. The "package.json" file of the Vue application is the following:
{
"name": "a-vue-example-wpack",
"description": "a-vue-example-wpack-version",
"version": "1.0.0",
"author": "Song Li",
"license": "MIT",
"private": true,
"scripts": {
"build-dev": "cross-env NODE_ENV=dev webpack --color",
"build-dev-w": "cross-env NODE_ENV=dev webpack --color --watch",
"build-prod": "cross-env NODE_ENV=production webpack --hide-modules"
},
"dependencies": {
"vue": "^2.5.11"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1",
"url-loader": "0.6.2"
}
}
Besides the NPM dependencies, the "package.json" defined three scripts:
- "
build-dev
" - Executing this script will run the Webpack in the development mode and the bundle will not be minified - "
build-dev-w
" - Executing this script will run the Webpack in the development mode and the bundle will not be minified. At the same time, a watcher is initiated on the source files. Whenever a source file is modified, Webpack will re-generate the bundle. This is very useful when you are developing the code, so you do not need to re-build the whole application to test your code - "
build-prod
" - Executing this script will run the Webpack in the production mode and the bundle will be minified. For a large application, the minification process is typically a lengthy process.
The "webpack.config.js" defines how Webpack should generate the bundle.
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './app/main.js',
output: {
path: path.resolve(__dirname, '../WebContent/Vue-app'),
publicPath: '/vue-components/dist/', filename: 'build.js'
},
module: {
rules: [
{ test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ] },
{ test: /\.vue$/, loader: 'vue-loader', options: { loaders: {} } },
{ test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } },
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
use: [{ loader: 'url-loader', options: { limit: 10240 } }]
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}, extensions: ['*', '.js', '.vue', '.json']
}
};
if (process.env.NODE_ENV === 'production') {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.optimize.UglifyJsPlugin({})])}
- The "
output.path = path.resolve(__dirname, '../WebContent/Vue-app')
" entry tells Webpack to put the bundle into the "WebContent/Vue-app" folder so Maven can package it into the WAR file; - The "
output.filename = 'build.js
'" entry tells Webpack to name the bundle as "build.js".
Finally, the "build.js" files will be used by the "index.html" file to display the Vue components in the browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-wpack-maven</title>
<style type="text/css">
* {
box-sizing: border-box;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="Vue-app/build.js"></script>
</body>
</html>
Webpack & Maven
To run Webpack during the Maven build process, we can add the "frontend-maven-plugin
" in the "pom.xml".
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>install-node-and-npm</id>
<goals><goal>install-node-and-npm</goal></goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm-install</id>
<goals><goal>npm</goal></goals>
<configuration>
<arguments>-prefix Vue-app/ install</arguments>
</configuration>
</execution>
<execution>
<id>webpack-build</id>
<goals><goal>npm</goal></goals>
<configuration>
<arguments>-prefix Vue-app/ run build-prod</arguments>
</configuration>
</execution>
</executions>
<configuration>
<nodeVersion>v8.11.1</nodeVersion>
<npmVersion>5.6.0</npmVersion>
</configuration>
</plugin>
</plugins>
</build>
- In the "
install-node-and-npm
" execution step, the plugin will download NPM to the local computer. If NPM is already downloaded by the previous builds, it will skip the download. - In the "
npm-install
" execution step, the plugin will run "npm install
" to download the "node_modules
" defined in the "package.json" file. If the "node_modules
" are already downloaded by the previous builds, it will skip the download. - In the "
webpack-build
" execution step, the plugin will run Webpack and pack the Vue application in production mode to the "WebContent/Vue-app" folder for the Maven to package it into the WAR file.
You can issue the following command to perform a complete Maven build.
mvn clean install
If the build completes successfully, you will have a WAR file. If you un-zip the WAR file, you should see that the "build.js" file is packed nicely at the correct folder. If you deploy and run the application, you should see that the application functions nicely in the browser.
IDE - Eclipse
The "frontend-maven-plugin
" downloads the NPM into the "node" folder and the "package.json" dependencies into the "node_modules" folder. These two folders are very large, too large for Eclipse to handle. In order for Eclipse to perform normally, you do better exclude them in the Eclipse resource filter.
In the development process, you need to constantly modify the components. You normally do not want to perform a full Maven build that is typically a lengthy process. After a success full Maven build, a copy of NPM is downloaded into the "node" folder in the root folder of the application, i.e., the folder where you find the "pom.xml". You can simply issue the following command to create a development bundle.
node/npm -prefix Vue-app/ run build-dev
The "build.js" file generated by "build-dev
" skips the minification process, so the Webpack runs a lot faster.
node/npm -prefix Vue-app/ run build-dev-w
You can also choose to set a watcher on the source files of you components. Whenever you make changes to the files in your components, Webpack will re-generate the "build.js" file. With the watcher, Webpack is optimized for speed. For a reasonably large application, the Webpack bundles are almost re-generated instantaneously after your make any changes to the component files.
Points of Interest
- This is a note on Webpack & Maven.
- I hope you like my postings and I hope this note can help you one way or the other.
History
- 4/1/4/2018: First revision