Weekly post (1/16)

  • Webpack 2 is out . I’ve been using pre-release versions of v2 in my project for a month now. Among other things, this new major version includes these exciting features:

    • Webpack now natively understands ES2015 code, especially ES2015 modules, so you don’t have to compile *.js files to CommonJS using Babel anymore. Because ES2015 modules are static1, this new capability enables Webpack to do tree-shaking. This means Webpack can look at an ES2015 module and performs static analysis to figure out which exported variable isn’t used by any other module and remove this variable from the list of emitted exports from that module. The minifier (UglisyJS by default) will then strip these values from the final minified output.
    • Webpack now has configuration validation built-in. Any newcomer to Webpack would agree that its configurations can appear convoluted and myeterious at times. For example, why is the setting for source map generation called dev-tools? Previously, Webpack will not validate its configuration and instead, emit cryptic error messages when there’s an error in the configuration, such as using loader instead of loaders. The convoluted configuration and lack of meaningful error messsages mean user has to use external validators like webpack-validator. This problem is now fixed.

For example, ES2015 exports are really live “views” into the original exported values, which helps resolve the circular dependency problem that plagues other module systems. For example, AMD, which I used in the past, requires a special convoluted syntax to deal with circular dependency.

  • There are 2 ways to install an npm package:

    • Locally with npm install [package-name], which will install the package into the node_modules directory inside your current working directory
    • Globally with the -g flag: npm install -g [package-name] which will install into the global modules directory.

    The main benefit of local installation is that it allows you to have different versions of a package inside different projects. For example, you can run Webpack 1 for an older project you’re maintaining and Webpack 2 for another newer project to take advatange of Webpack 2’s new features.

    The main obstacle that I’ve found to conveniently use locally installed packages is that you must somehow prepend their executables, located in the local node_modules/.bin directory, to the PATH environment variable without polluting the PATH.

    A solution that I’ve found to work quite well for me is to define a shell alias npm-exec that automatically prepends the directory of locally installed npm executables to the PATH just for the duration of the command. The alias is defined as alias npm-exec='PATH=$(npm bin):$PATH'. The npm bin command programmatically returns the absolute path to the local directory where npm install its executables. A usage example is npm-exec webpack [webpack command line arguments] to run the locally installed Webpack.

    Of course, some tools require globally installed packages. For example, the TypeScript plugin for Sublime Text looks for a global tsc executable in your PATH and the eslint plugin looks for a eslint executable so you have no choice but to install those packages globally. However, you can still have local versions of those packages and the npm-exec command above will make sure that local installations takes precedence over global ones.


  1. This is a very good and detailed description of the new ES2015 module, including things even an experienced JavaScript developer like me didn’t know.