I am new to webpack and I am converting an existing web application to use it.
I am using webpack to bundle and minify my JS which is great when deployed, however this makes it very challenging to debug while in developement.
Typically I use chrome's built in debugger to debug JS issues. (Or Firebug on firefox). However with webpack everything is stuffed in one file and it becomes challenging to debug using that mechanism.
Is there a way to quickly turn on and off bundeling? or turn on and off minifying?
I have looked to see if there is some script loader configuration or other setting but it does not appear ovious.
I have not yet had the time to convert everything to act like a module and use requires. So I simply use require("script!./file.js") pattern for my loading.
You can use source maps to preserve the mapping between your source code and the bundled/minified one.
Webpack provides the devtool option to enhance debugging in the developer tool just creating a source map of the bundled file for you. This option can be used from the command line or used in your webpack.config.js configuration file.
Below you can find a contrived example using the command line to generate the bundled file (bundle.js) along with the generated source map file (bundle.js.map).
$ webpack --devtool source-map ./entry.js bundle.js
Hash: b13b8d9e3292806f8563
Version: webpack 1.12.2
Time: 90ms
Asset Size Chunks Chunk Names
bundle.js 1.74 kB 0 [emitted] main
bundle.js.map 1.89 kB 0 [emitted] main
[0] ./entry.js 85 bytes {0} [built]
[1] ./hello.js 59 bytes {0} [built]
index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
entry.js
var hello = require('./hello.js');
document.body.innerHTML += 'It works ' + hello();
hello.js
module.exports = function () {
return 'Hello world!';
};
If you open index.html in your browser (I use Chrome but I think it is also supported in other browsers), you will see in the tab Sources that you have the bundled file under the file:// scheme and the source files under the special webpack:// scheme.
And yes, you can start debugging as if you had the original source code! Try to put a breakpoint in one line and refresh the page.
I think its better to setup your project using production and development mode
https://webpack.js.org/guides/production/
Its also include how to map your code to debug
devtool: 'inline-source-map'
Source maps are very useful as already pointed out.
But sometimes selecting which source map to use could be a pain.
This comment on one of the Webpack source map issue might be helpful for selecting which source map to use based on requirements.
Chrome also has a format option in the debugger. It doesn't have all the information a normal source file would but it's a great start, also you can set breakpoints. The button you click is on the bottom left of the first screen shot, looks like {}.
Before formatting:
After formatting.
Have a look Here
its a beautifier that deminifies javascript. at the bottom, it has a list of various plugins and extensions for browsers, check them out.
you might be interested in FireFox Deminifier , its supposed to deminify and style your javascript when its retrieved from the server.
(source: mozilla.net)
Related
I'm using a large library (around 1 MB) along with webpack for building. The library is just used normally - it's in package.json's dependencies, and at some point in my code I import it with an import from <lib_name> (this is in Typescript).
So right now, when I run a webpack build, the end result bundle.js contains all (or most? not sure how much webpack trims, actually) of the library's code. So even my barebones application that's only a couple lines of code and an import has that big 1MB build size.
What I would like to do is have the library not be thrown into the final build, and instead basically have in my HTML file something like this:
<script src="https://some.cdn.here/thelibrary-v0.0.0.min.js"></script>
<script src="bundle.js"></script>
In other words, the files in the build would be something like:
BEFORE:
dist/
bundle.js -- 1005 KB
AFTER:
dist/
thelibrary-v0.0.0.min.js -- 1000 KB
bundle.js -- 5 KB
Where bundle.js becomes a very small file with just my code, and it simply expects the library to be loaded beforehand. To be clear - bundle.js would still be using things from the library and would need it to run. I'm not sure if this is actually possible or not, because I don't have a good understanding of how webpack actually handles imports and stuff (especially in conjunction with uglify/minification). Is it possible to do something like this, and if so, how?
It can be done with externals.
module.exports = {
//...
externals: {
jquery: 'jQuery'// thelibrary in your case
}
};
Does Create React App provides gzip compression out of the box?
Since in console output it shows below , is it enough to serve them in production , is any particular configuration required ? Please confirm if anyone is aware
File sizes after gzip:
88.96 KB build\static\js\2.67a35d8a.chunk.js
45.81 KB build\static\js\3.06562e80.chunk.js
2.17 KB build\static\js\4.2dca02a2.chunk.js
1.71 KB build\static\js\main.01ef12c5.chunk.js
No it does not. And as a matter of fact, It does not allow us to change the default configuration of the Module Bundler which it uses ( Webpack). If you want to serve gzipped compressed bundle to make your apps load faster on client side, then you can find my answer posted at https://stackoverflow.com/a/67716096/2631276
I don't believe so but it looks like you can configure this on your own in your package.json file in your postbuild script.
This post might be helpful for you.
I have a simple Dojo application, that does only one require call, loading all the dependencies. The trouble is, while it is extremely simple, it still ends up loading ~100 files from server. I tried to solve that problem using Dojo build system, but seems I don't have a deep enough understanding.
So my question is - given a list of dependencies, like the following:
["dojo/parser",
"dijit/registry",
"dojo/dom",
"dojo/on",
"dojo/query",
"dojo/dom-class",
"dojo/request",
"dijit/form/ValidationTextBox",
"dijit/form/Select",
"dijit/form/NumberSpinner",
"dijit/form/CheckBox",
"dijit/layout/ContentPane",
"dijit/Dialog",
"dojo/NodeList-traverse",
"dojo/domReady"]
how do I set up the build to create a single-file (or several-file, just not 100-file) dojo file?
If you're using Dojo's require() loader, there are build tools that you can use to combine files and minify. According to the site, the build tools aren't included in an official release, so you'll have to get them from the development version (specifically, look in the buildscripts directory).
The Dojo documentation contains some info on its build system that you may also find useful.
As a proof of concept, here are the steps I took:
Go to the download page, and download the Source Dojo Toolkit SDK (it's the only one that contains the util scripts needed for a build).
Extract to a location (for the sake of this post, let's say it's /opt/dojo-toolkit).
From the Dojo toolkit directory (i.e. /opt/dojo-toolkit), run the build util: ./util/buildscripts/build.sh action=release htmlFiles=/path/to/my/index.html (careful, this slowed my 5-year-old dual-core to a crawl)
Example of index.html (this one is exactly inside the dojo-toolkit directory):
...
<head>
<script src="dojo/dojo.js"></script>
<script>
dojo.require("my.test");
</script>
</head>
...
The require() call looks for nested modules (I couldn't get it to work with a top-level module), so in this case, I've got a my directory inside of dojo-toolkit which contains a test.js file. That file is the main "bootstrap" file which loads in all of the dependencies. I just put random require() calls in mine:
dojo.require('dijit.ProgressBar');
dojo.require('dijit.Tree');
And that should do it. Basically, running the build utility against your HTML file (the one that contains the reference to dojo.js) makes sure that all of the dependencies are found, starting from the top.
Note: the build system create a release directory with the built output, but it looks a little misleading at first - it appears to have minified each individual file, but if you look at your actual bootstrap file (my/test.js, in this case), it will be a combined, minified file with (I presume) everything you need to run your app.
Otherwise, if you're using AMD style require()'s (as in require.js), you can use its optimization tool. According to the site, it will:
Combine all dependent files (including require.js itself) into a single file. It analyzes the require() call to figure out which files it needs to combine.
Minify your JavaScript using either UglifyJS (default) or Closure Compiler.
I needed to do the same thing and this is how I solved it.
If you read the documentation about how to create custom builds (http://dojotoolkit.org/documentation/tutorials/1.8/build/), in the Layers section they talk about creating custom layers. You can add all the modules you need there. Here is an example of my custom layer file:
layers : {
"dojo/dojo" : {
include : [
"dojo/dojo",
"dojo/_base/window",//
"dojo/dom",//
"dojo/dom-class",//
"dojo/ready",//
"dojo/store/Memory"
],
customBase : true,
boot : true
}
}
What this will do is build only those modules into dojo.js, along with the bootstrap loader so that you can load other modules on the fly.
Currently I have one QA server to run on, svn update can be run there to test the code that everyone commits to subversion.
The issue I have seen with more and more javascript and css that the min or full version that get compiled, eg:
Build tool: Jake
JS compressor: UglifyJS
CSS optimizer: CSSO
either have to manually be updated/compiled just before promotion to production servers or we just have the min/full version on our svn but that would be not so great.
The way I see an approach would be:
* keep the full/split css java script files outside of the path where web served content sits, subversion or trac builds the min/full version on submit/trigger.
Has anyone further automated this process?
How do you separate your full source/full version/min version as not to mess up final deployment? When do you compile the min version?
Only at the last step before going to production?
Where do you leave the original source, it cannot live right next to the web served other files, in my example php files?
Just been dealing with something similar myself. If I understand your question correctly you're looking to have unminified files in a local or dev environment but have them minified upon deployment. There are, of course, many different ways that you can go about this, and we're currently working on a better solution but I'll give you an example of a project I just finished up...
Uses symfony 1.4, YUI Compressor, and git.
I have a symfony task (php cli script) set up to run YUI Compressor on a given list of css and js files, which get dumped into min.css and min.js in the appropriate directories. The script simply dumps all of the contents of the listed files into one big file and minifies them. Then symfony is set to only use min.js. Of course, debugging minified files can be a pain, so another option is to skip minifying on your local or dev boxes and just keep them as a combined file. Personally I have it minifying anyway because Chrome's "Pretty print" option works well enough for me most of the time, although it's not 'ideal'.
I've created a local post-commit and server side post-merge script for git that simply runs the symfony task so the files are automatically updated whenever you commit locally or do a git pull on the server, so any changes made inside the js/css files are updated when committing. The only pain point of this is having to manually run the minify script whenever you've updated locally but haven't yet committed.
An alternative to keep unminified code on local/dev would require some more coding so that it is environment specific, which is certainly doable but I've just been lazy with it thus far as this works well enough for now :)
I have taken the following convention-based approach and it works well for me for traditional web-development as well as for mobile apps and offline HTML5 mobile apps.
Conventions
All non-minified/full-version js/css scripts are named with .debug.js or .debug.css extensions.
Example: global.debug.js and global.debug.css
All references to js/css in html reference non-debug versions: global.js or global.css
Process
I use a custom MSBuild task to minify js (using AjaxMin, but you could use YUI Compressor or others) to the following naming convention *.release.js or *.release.css
(Example: global.release.js).
After minification into the *.release.js files. I have one more MSBuild task that calls a simple batch file (JS.bat) that accepts the current Configuration (Debug or Release) and copies either the debug (full-source version) or the release (minified) version to the normal destination.
Here's the sample MSBuild tasks I add to my project file to accomplish the minification and call to my batch file:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="AfterBuild">
<ItemGroup>
<DebugJS Include="**\*.debug.js" />
</ItemGroup>
<AjaxMin SourceFiles="#(DebugJS)" SourceExtensionPattern="\.debug.js$" TargetExtension=".release.js" />
<Exec Command="JS.bat $(Configuration)" />
</Target>
For example, assuming:
I'm in Debug mode
and I have a global.debug.js file (full-source version that I work in)
When I build my project, global.debug.js get's minified into global.release.js
Since I'm in the Debug mode configuration, global.debug.js will get copied to global.js (which is what my html references) and, therefore, I'll have the full-source version when debugging
If I switch to Release mode configuration, then global.release.js (the minified version) gets copied to global.js and this is what I would want for release/deployment to production.
Here's the simple batch script (JS.bat) that I use to handle the copy of the Debug or Release script based on the passed argument:
#Echo off
REM ----------------------------------------------------------------------------------------
REM <summary>
REM Script used to copy the Debug (or Release) javascript files to the runtime location
REM </summary>
REM <history>
REM <change date="9/22/2010" author="Adam Anderly">Created</change>
REM </history>
REM ----------------------------------------------------------------------------------------
REM Grab the first argument as variable Config (Debug/Release)
SET Config=%~1
REM The loop below is used to get the Length of the Config variable
REM The Length variable is then used in the substring function on Line 22
for /f "tokens=1 delims=:" %%a in (
'^(echo."%Config%"^& echo.!##^)^|findstr /O /C:"!##" '
) do set /a Length=%%a-5 + 4
FOR /R %%i IN (*.%Config%.js) DO CALL :REN "%%i"
GOTO :END
:REN
SET File=%~f1
REM Set File2 variable to the runtime filename (minus .debug or .release)
CALL SET File2=%%File:~0,-%Length%%%.js
REM First make sure the destination file is not read-only
IF EXIST "%File2%" ATTRIB /S -R "%File2%"
REM Finally, we copy the current debug|release file to the runtime file
COPY /Y "%File%" "%File2%"
:END
The batch script above works recursively so you can have nested folders of js or css and it still works.
While I'm using MSBuild, you could certainly incorporate this batch file into your process using a different build tool (previously I did the same using NAnt).
Hope that helps!
Adam
Say I had 1 MB of compressed Javascript, all combined into one file using Google Closure.
Now 500 KB of it is only needed for one section of the site.
So I want to combine & compress the Javascript, but separate it into two packages:
Package A - 500 KB - used across the site
Package B - 500 KB - used only in one section of the site
At the moment I'm just putting a comment at the top of the Javascript files like this:
/// <package name="Main" />
And using my own custom .NET application to parse them and put them in the appropriate package.
Is it possible to do all of this with Google Closure? I'd rather use an existing solution than re-invent the wheel.
wrong closure compiler does have option to compress files into multiple files
for example:
java -jar compiler.jar \
--module mod1 --js src1.js --js src2.js \
--module mod2:mod1 --js src3.js
After further investigation, it looks like Closure doesn't have such a feature.
I'm going to build the feature into my own custom JS combiner, which I might open source when I have the time.