📜 ⬆️ ⬇️

The first official release of Webpack 2. What's new compared to Webpack 1?

Webpack 2 Release


Warning : check how the version of webpack is installed in package.json. Perhaps your continuous integration will break soon.


Finally, Webpack 2 broke the line of the beta and release candidate. This means that everything works stably, and you can safely use it in production.


List of changes / improvements:



Details under the cut.


Native support for ES6 modules


Now Webpack for working with modules supports constructs using import and export keywords without first transforming code into CommonJS, and does it quite well. To ensure support flexibility, let's take a look at the following code:


 import { currentPage, readPage } from "./book"; currentPage === 0; //true readPage(); currentPage === 1; //true 

 // book.js export var currentPage = 0; export function readPage() { currentPage++; } export default "This is a book"; 

Code Splitting with chunks - Code Splitting with ES6


Using System.import provides the ability to delay the loading of modules in runtime.


If a module is loaded using System.import , the Webpack will separate it from the rest of the code into an independent chunk .


System.import accepts a module name / module path and returns a Promise , so its use is perfectly combined with async/await ;


 function onClick() { System.import("./module").then(module => { module.default; }).catch(err => { console.log("Chunk loading failed"); }); } 

UPDATE:


System.import will be deprecated in webpack 2 release (removed in webpack 3)
import () should be used instead of System.import ()

Dynamic expressions support for dynamic expressions when loading modules


If you use System.import with a dynamic expression as a path to a module, then Webpack packs the code for each of the modules that match the pattern into a separate chunk .


 function route(path, query) { return System.import("./routes/" + path + "/route") .then(route => new route.Route(query)); } // This creates a separate chunk for each possible route 

Changes when working with Babel


The habitual babel-preset es2015 , by default, transforms ES6 modules into CommonJS. Instead, you now need to use babel-preset es2015-webpack .


UPDATE:
babel-preset es2015-webpack declared deprecated instead you need to use the options:


 { "presets": [ [ "es2015", { "modules": false } ] ] } 

ES6-specific optimizations


The static nature of the ES6 modules opens up opportunities for new optimizations at the compilation stage. For example, now Webpack can find unused export s and delete them - Tree-shaking.


ES6 export mangling support is also announced - minification of the name of the exported variable or function, if possible.


Changes in the configuration file


Previously, many Webpack configurations used environment variables to configure optional parameters. Webpack 2 introduces another way to define them externally.


Now, when launching the Webpack via the command line, you can specify one or more --env arguments in the following format: ( --env dev => "dev" ) or ( --env.minimize --env.server localhost => {minimize: true, server: "localhost"} ). It is recommended to use the second option.


 // webpack.config.babel.js exports default function(options) { return { // ... devtool: options.dev ? "cheap-module-eval-source-map" : "hidden-source-map" }; } 

There are many improvements in the Webpack subsystem responsible for resolving . It has become more flexible, and the probability of adjusting something wrong has decreased.


New options:


 { modules: [path.resolve(__dirname, "app"), "node_modules"] // (was split into `root`, `modulesDirectories` and `fallback` in the old options) // In which folders the resolver look for modules // relative paths are looked up in every parent folder (like node_modules) // absolute paths are looked up directly // the order is respected descriptionFiles: ["package.json", "bower.json"], // These JSON files are read in directories mainFields: ["main", "browser"], // These fields in the description files are looked up when trying to resolve the package directory mainFiles: ["index"] // These files are tried when trying to resolve a directory aliasFields: ["browser"], // These fields in the description files offer aliasing in this package // The content of these fields is an object where requests to a key are mapped to the corresponding value extensions: [".js", ".json"], // These extensions are tried when resolving a file enforceExtension: false, // If false it will also try to use no extension from above moduleExtensions: ["-loader"], // These extensions are tried when resolving a module enforceModuleExtension: false, // If false it's also try to use no module extension from above alias: { jquery: path.resolve(__dirname, "vendor/jquery-2.0.0.js") } // These aliasing is used when trying to resolve a module } 

Breaking changes


Polyfills


Dynamic loading of chunks will now only work if Promise is available. So if you need support for old browsers, then the support of the web application itself will need to provide support for Promise through polyfiles.


This is done in order to avoid duplication of Promise-polyfiles code in different parts of bundle-js.


Can I use Promises?


Also for older browsers through polyfiles it is necessary to provide support for the following functions:


Object.defineProperty ,
Function.prototype.bind ,
Object.keys


Loaders configuration


Webpack-loaders are now configured using the resourcePath parameter instead of the resource . This means that the query string is no longer involved regex-matching.


Now, instead of complex structures like /\.svg($|\?)/ , simply /\.svg$/ .


The syntax for using Webpack-loaders is as follows:


 loaders: [ { test: /\.css$/, loaders: [ "style-loader", { loader: "css-loader", query: { modules: true } }, { loader: "sass-loader", query: { includePaths: [ path.resolve(__dirname, "some-folder") ] } } ] } ] 

HMR communication


Webpack 1 for rebuild bundle notifications used the Web Messaging API (postMessage). Webpack 2 uses the standard event emitter. This means that the binding for the WebSocket will be included in the bundle.


webpack-dev-server now uses the default "inlined" mode.


This should allow webpack-dev-server to be used to hot swap code in Web Workers.


Code splitting


require.ensure and AMD require now always work asynchronously, even if the chunk is already loaded.


References:


  1. Webpack 2.2: The Final Release
  2. New site with documentation
  3. Migrating from v1 to v2

Picture from the official blog Webpack on Medium


')

Source: https://habr.com/ru/post/319906/


All Articles