I am a dev on a web application that consists of Java Server Pages which act as the HTML, a Java backend, and Javascript front-end files. I have been tasked with looking into adding Webpack to the project, with the goal of only using it to minify Javascript files at first (eventually we will use more of Webpack's features of course). I have tried doing research via Google into Webpack minification, but I am having trouble finding anything detailing how to use it for just minification, instead of bundling the project files.
Does anyone know how to use Webpack for strictly Javscript minification?
Webpack out of the box is anticipating on processing JS and will run minification on production builds by default.
https://webpack.js.org/configuration/mode/ (different build modes)
Assuming you are already past configuring a JS entry file to consume all your JS files:
https://webpack.js.org/configuration/entry-context/#entry
AND configured a loader on how to handle each JS file imported in your entry file appropriately.
(Feels like you want asset/resource. Pay close attention to asset modules type and generator options)
https://webpack.js.org/guides/asset-modules/
The settings for minification on a production build are what is known as the optimization.minimize configuration of your webpack.
https://webpack.js.org/configuration/optimization/#optimizationminimize
With Webpack5, further options around the minification engine has been exposed and is known as optimization.minimizer configuration options:
https://webpack.js.org/configuration/optimization/#optimizationminimizer
So I have a few questions regarding how Webpack serves its bundles. I have a React application created using create-react-app. When I inspect the JS bundles in Chrome dev tools, I can see all the individual js files I created in my React app (eg. App.js). But I also see other bundles like bundle.js, 0.chunck.js and main.js. However, only the bundle files are shown in network tab. This indicates that only the Webpack bundles were actually downloaded.
So the question is, how were these other individual files get delivered to the browser? Is my application using the bundle or these separate files? I believe that the individual JS files are only available in 'development' mode of Webpack, and not in 'production' mode, but I would still like to understand this.
Further, is the React source code a part of these bundles or is React globally exposed? If React is part of the bundles, then how does React dev tools recognize that React is present on the page, given that all Webpack bundles are isolated from all other code?
As you mentioned in your question, for some reason you are still able to debug your bundled and probably minified code as if it has not been bundled and minified. The reason this is possible is called:
Source maps
Source maps are files, which map code in the bundled file to the locations of the code in unbundled files. Those source maps are generated by your bundler (if enabled) while bundling your code. They are shipped with the code on requesting it and are used by your browser, so that you can debug your own unbundled code in the browser dev tools. For more details, there is a good introduction into source maps here.
Regarding your second question: React dev tools will recognize React, if window.__REACT_DEVTOOLS_GLOBAL_HOOK__ is set. This property is a special object enabling communication with the developer tools backend in the browser or standalone app. As this is a member on the global window object, it is accessible everywhere and therefore not bound to a single bundle.
In my web app I was using RequireJS to asynchronously load my javascript files on demand. This worked well for dev - when debugging my app I could see which script is dependent on which and order in which they were loaded. This simplified debugging.
Later I switched to Webpack as it is much easier in configuration and easier to maintain. So Webpack now generates for me nice bundles containing my javascript code. This works perfectly well but what I'd like to have is an imitation of my previous RequireJS configuration for dev time.
When I am developing my app I want Webpack to generate some simple entry point (just like in RequireJS) which would load my javascript files one by one through their "require" references.
At the same time I still want that Webpack performed normal bundling when I deploy my app to a server.
Is this possible to achieve?
Enable Devtools in webpack.config.js to control and generate source maps (Source Maps enhance debugging process).
webpack.config.js
devtool: "#inline-source-map",
Chrome Debugger View
Nope, that's not possible. But have you tried the devtool-option? It maps back your original files in your devtools so you should see no difference whether the modules were in different files or just all in one.
I'm investigating the complexity involved in maintaining a cross-platform (web, ios, android) phonegap codebase that allows for platform specific code (and assets/tests) as simply as possible.
The current best approach I'm taking is to use grunt to build the code of a typical web app, and then use the grunt-phonegap module to generate the respective phonegap projects.
I'm confident this will work, however for my phonegap projects, I know I'm going to need to make use of some specially written plugins to make use of some device capabilities (these aren't typical cordova plugins)
I'm wondering if anyone has figured out an approach for maintaining a codebase that can adapt to different platforms and requirements. Javascript has no #IF_DEF functionality, but would it be possible to implement something like that using grunt?
I recently had the same question myself. I couldn't really find much online regarding this so I decided to deep dive into Grunt, Node, and Git.
Grunt and Node
In the root folder of my Cordova projects (alongside the www, platforms, merges, and plugins folders) I have a grunt project. I store modular JavaScript files and CSS files that may or may not be platform dependent inside a src folder inside the root of the Cordova project. This grunt project builds the JavaScript and CSS stored in the src folder and places the resulting files into the www or merges folder as appropriate.
I even wrote a grunt task that will make a production build of the app by optimizing and minifying css, javascript, and html templates, then rebuilds the Cordova platform projects to include these production files.
Because there is no #IF_DEF in JavaScript, I have to use Grunt (mentioned above) to build out the JavaScript for each platform. I modularize almost all of the JavaScript functions by platform. If there are no platform differences for that function (no native hooks), I only need one file. If there are differences, I need to create a separate file for each platform for that function. For example, my Cordova onDeviceReady and onResume function usually differ from platform to platform. I create files called
CordovaEvents-ios.js and CordovaEvents-android.js
Inside the package.json file, I describe the "features" I want in my app. CordovaEvents is an example of a feature.
I also support "arguments". I use the same approach above in the file names of the modular files. An argument could look like this
CordovaEvents-ios--production.js and CordovaEvents-android--production.js
In this case the code needed in a production app will differ from non production code. I can simply pass this argument (or list of arguments) during the build process, and the correct files will be picked up and built. I think this most closely addresses your question if there is an approach to maintaining a codebase that can adapt to different platforms and requirements. The requirements are the feature names and arguments. The argument can be anything you want, maybe using one plugin or another plugin.
I also describe the platforms I want to support ("iOS", "Android", and "Desktop"). Grunt processes each platform in a MultiTask, and then looks at the features I want to support. It will try to find a file called feature-platform.js. If it cannot find this file, it will just try to look for feature.js. After I concatenate all the functions together needed for the platform, it will copy the file over to the merges folder for iOS or Android. Typically all the files kept in the WWW folder in the root project will work on a desktop because there are no native Cordova hooks... this allows me to debug in Chrome. All the files that contain native hooks are stored in the merges folder. Once the Cordova project is built for the respective platform, the code can be tested in a device simulator.
If you are new to Grunt I would strongly suggest taking a look a their getting started guide.
http://gruntjs.com/getting-started
Git
I also employed Git to version my code. I used SourceTree to create the Git repository in the root folder of my Cordova project, and have a remote repository on my Mac Mini server that I can push my commits too. This allows us to have a backup copy of the code, and makes it so my team can also work on the code out-of-band.
I Git ignore the following folders:
node_modules
plugins
platforms
plugins
All the other files and folders contained in the root directory of my Cordova project are versioned. I used the following link as a reference to help define my Git strategy for Cordova:
https://leanpub.com/developingwithcordovacli/read#version-control
It didn't take me overnight to figure all this stuff out, in fact it took a little bit more than two months. I hope my answer can server as a guide to you and others to address your concerns you mentioned in your opening post.
I am using gruntjs, javascript, jade, bower, and phonegap to build hybrid web applications and phonegap mobile applications. After some investigation, I settled on to use jade template language for creating my html and javascript files. This is my setup.
//begin grunt module
module.exports = function(grunt) {
var $jadeConfigObject = {
compileDevelopment: {
options: {
pretty: true,
data: {
debug: true,
**phonegap : '<%= isPhonegapBuild %>'**
}
},
files: [{
expand: true,
cwd : "src",
src: "**/*.jade",
ext: ".html",
dest:"dist/development/www/"
}]
}
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: [$dist_folder,"www"],
jade: $jadeConfigObject
// other gruntjs tasks
})
grunt.registerTask('setPhonegap', 'Set Phonegap related values.', function(n) {
**grunt.config.set('isPhonegapBuild', true);**
});
grunt.registerTask('buildPhonegap', ['setPhonegap','buildDevelopment'
,'copy:phonegap_www']);
}
Now explanation
Use gruntjs setPhonegap task to distinguish between phonegap build and normal web application build.
Task setPhonegap set isPhonegapBuild config property, this property, in turn, is used by jade config object. Then I can use "if phonegap" statements in jade files.
I have following line in my jade layout file
include ../includes/mainJavascript.jade
mainJavascript.jade
if phonegap
script(type='text/javascript',src='#{mainFolder}/cordova.js')
script(type='text/javascript',src='#{mainFolder}/cordova_plugins.js')
script(type='text/javascript',src='#{mainFolder}/plugins/org.apache.cordova.device/www/device.js')
script(type='text/javascript',src='#{javascriptServicesFolder}/pushTokenService.js')
script(type='text/javascript',src='#{javascriptFolder}/plugins/com.phonegap.plugins.PushPlugin/www/PushNotification.js')
script(type='text/javascript',src='#{javascriptFolder}/phonegap/pushNotificationHelper.js')
This way I have following features
My web application does not contain any phonegap related scripts or html
I can use jade layouts (Master Page) to simplify my files very easily.
Adding new javascript to every page or changing every html for every page in application very easy.
Note that phonegap wants www folder for its build scripts, therefore I create following directory structure.
src -- every code file here, jade, javascript
www -- only created for phonegap build
dist/development/www -- normal development www build
dist/production/www -- production www build
I ignore www/* and dist/* in my source control. I only work with src jade and javascript files. Add this setup to bower, I believe it is a good option.
I've been searching for a version of javascriptcore that i can build into my iphone app to allow for embedded scripts in my application, but i can't seem to find an iOS ready project that has the settings and files i need. I've tried getting from the webkit svn, but if i make a cocoa-touch static library and include the relevant files, i get layers of compiler errors that reveal other errors when i resolve them. The javascriptcore files that apple provides on their website don't come with an xcode project, and copying those files into the xcodeproject provided in the webkit svn checkout still give me compiler issues. Is there anywhere i can find an iOS project that compiles javascriptcore for easy integration into an iphone app?