Answers to Some Confusions in Webpack

  webpack

Original connection:Webpack — The Confusing Parts


Webpack is the main module loader for React and Redux projects. I think people who use Angular2 and other frameworks are also using Webpack to develop a lot today.

When I first looked at the configuration files of the Webpack, I was overwhelmed. After using it for a period of time, I think this is because Webpack has unique grammar and unconventional philosophy, so it may cause some confusion when it is first used. Coincidentally, these philosophies also make it so popular.

Just because the start of Webpack is easy to cause confusion, I hope to write something out so that more people can get started and experience its powerful features.

The following is the first part.

The core philosophy of Webpack

The two core philosophies are:

  1. Everything is a module.-Just like JS files can be regarded as “modules”, everything else (CSS, pictures, HTML) can be regarded as modules. In other words, you canrequire(“myJSfile.js”)Or ..require(“myCSSfile.css”). This means that we can divide any static resource into controllable modules for different operations such as reuse.

  2. Only “what you need” and “when do you need” will be loaded.-A typical module loader will eventually package all modules into a huge “bundle.js” file.However, in many practical projects, the “bundle.js” file may reach 10 MB to 15 MB in size and will be loaded continuously!So Webpack goes through a lot of featuresSplit your code, generate multiple “bundle” fragments, andLoading different parts of a project asynchronouslyTherefore, only the “what you need” and “when do you need” sections will be loaded for you.

OK, let’s look at the “confusing” parts together.

1. development environment VS production environment

The first thing to realize is that Webpack has a lot of features. Some are “development environment specific”, some are “production environment specific” and some are “general”.
图片描述

In general, most projects use many Webpack features, so they usually have two large oneswebpack configDocument used to distinguish development environment from production environment.

2. webpack CLI Vs webpack-dev-server

It is very important to understand that the Webpack module loader has two interfaces:

  1. Webpack clitool-default interface (installed with webpack)

  2. Webpack-dev-servertool-this tool uses the command from the CLI and configuration files (default:webpack.config.js) to control the packaging action of the Webpack.

When you first started learning Webpack, you might start with CLI, but then you will probably only use it to build production environment projects.

Usage:

OPTION 1:
 //global installation
 npm install webpack --g
 
 //Use at Terminal
 $ webpack //<-- packaged via webpack.bundle.js
 
 OPTION 2 :
 //install and write package.json dependency locally
 npm install webpack --save
 
 //Add to script of package.json
 “scripts”: {
 “build”: “webpack --config webpack.config.prod.js -p”,
 ...
 }
 
 //Start building
 npm run build

Webpack-dev-server (for development environment)

This is an express-based node.js server running on port 8080. This server will call the Webpack internally. Its advantage is that it provides additional capabilities-similar to those that refresh browsers. “Live Reloading“and/or the local update module“Module Hot Overload” Function (HMR).

Usage:

OPTION 1:
 //global installation
 npm install webpack-dev-server --save
 
 //terminal usage
 $ webpack-dev-server --inline --hot
 
 OPTION 2:
 //Add to script of package.json
 “scripts”: {
 “start”: “webpack-dev-server --inline --hot”,
 ...
 }
 
 //Enter the following command line to use
 $ npm start
 
 The browser opens the following address
 http://localhost:8080

Webpack Vs webpack-dev-server options

It is worth noting that there are some options such as “inline” and “hot” for webpack-dev-server only, while “hide-modules” for CLI only.

webpack-dev-server CLI options Vs config options

Another thing to know is that you can configure webpack-dev-server in two ways:

  1. viawebpack.config.jsThe “devServer” object of the.

  2. Through CLI options.

//Use CLI
 webpack-dev-server --hot --inline
 
 //use webpack.config.js
 devServer: {
 inline: true,
 hot:true
 }

I find that sometimes devServer configuration doesn’t work! So I prefer to write these options in CLIpackage.jsonInside:

//package.json
 {
 scripts:
 {“start”: “webpack-dev-server --hot --inline”}
 }

Note: Make sure you don’t have a handle.hot:trueAnd-hotWrite it together.

“hot” Vs “inline” webpack-dev-server options

The “inline” option provides the “Live reloading” function for the entire page. The “hot” option provides the “module hot reload” function, which attempts to update only the changed part of the component (instead of the entire page). If we write down both options, then when the file is changed, webpack-dev-server will try HMR first, and if it doesn’t work, it will reload the entire page.

//When the file is changed, the following three options will generate a new bundle. However,
 
 //1. The page will not refresh
 $ webpack-dev-server
 
 //2. Refresh the entire page
 $ webpack-dev-server --inline
 
 //3. Refresh only the changed part (HMR), and refresh the entire page if the HMR fails.
 $ webpack-dev-server  --inline --hot

“entry”-string VS array VS object

entryTell the Webpack entry file or where to start. It can be a string, an array or an object. This may confuse you, but different types are suitable for different occasions.

If you use a single starting point (which is true for most projects), then you can use any type and their results will be the same.
图片描述

Entry-array

However, if you want to add multiple files that are independent of each other, you can use the array format.

For example, chestnut, your HTML may need “googleAnalytics.js”. You can tell Webpack to add it after bundle.js:
图片描述

Entry-object

Now, when you have a multi-page application that contains multiple HTML files instead of a single-page application (index.html and profile.html), you can tell the Webpack to generate multiple bundle files at once through the object format.

The following configuration generates two JS files:indexEntry.jsAndprofileEntry.js, you can atindex.htmlAndprofile.htmlUse them separately
图片描述

Usage:

//profile.html
 <script src=”dist/profileEntry.js”></script>
 
 //index.html
 <script src=”dist/indexEntry.js”></script>

Note: the file name comes from the key of the “entry” object.

Entry-combined format

You can also use arrays in entry objects. The following example generates three files: one containing three filesvendor.jsOneindex.jsAnd oneprofile.js.
图片描述

4. output — “path” Vs “publicPath”

outputTell the Webpack where and how to place the packed files. It has two attributes: “path” and “publicPath”, which may cause some confusion to users.

“path” simply tells the Webpack where to generate the output file. “publicPath” is mostly used by plug-ins of some Webpack, and is used in HTML files toProduction environmentWhen the method is built, update the URL address in the CSS file.
图片描述

For example, chestnut, in your CSS file, you might load it in the URL./test.png. But in a production environment,test.pngIt is likely to be placed in a CDN-for example, when your node.js server is running in Heroku.This means that you may have to manually update the URL in the file in the production environment.

Instead, you can use the Webpack’spublicPathAs well as other plug-ins suitable for this attribute, automatically update the URL pointing inside the file in the production environment.
图片描述

//Development environment: servers and pictures are all located locally
 .image {
 background-image: url(‘./test.png’);
 }
 
 //Production environment: server in Heroku and picture in CDN
 .image {
 background-image: url(‘https://someCDN/test.png’);
 }

5. Loaders and Chain Loaders

The loader is an additional node module, which is used to “load” or “import” different types of files and convert them into formats recognized by browsers-such as JS files, inline style sheets, or other formats. In addition, the loader also allows these files to be introduced into JS files in the form of “require” or “import” of ES6.

For example, you can usebabel-loaderConvert ES6 code into ES5 code:

module: {
 loaders: [{
 Test: /\.js$/, // judge the file format, and call loader if it is a ".js" file
 Exclude: /node_modules/, // exclude the node_modules folder
 Loader: ‘babel' ///Use Babel (short for babel(babel-loader)
 }]

Chain loader (working from right to left)

Different loaders can work on the same file type in chain.The working order of the chain loader is from right to left and passes “!” Segmentation.

Take chestnuts, we have one calledmyCssFile.cssThe CSS file, now want to put it to<style></style>This method is used in our HTML file and can be implemented by two loaders:css-loaderAndstyle-loader.

module: {
 loaders: [{
 test: /\.css$/,
 loader: ‘style!  css’ // style-loader!  Abbreviations for css-loader
 }]

This is the principle of operation:
图片描述

  1. Webpack searches CSS files referenced by modules. It means that the Webpack checks if there is any in a JS filerequire(myCssFile.css)If there is this sentence and the dependency is found, it will first hand over the file tocss-loader.

  2. css-loaderLoad all CSS files and their dependency packages (for example, by@importOther CSS files introduced) into a JSON file. Then the Webpack will give the results tostyle-loader.

  3. style-loaderGet this JSON file and inject it into<style></style>Tag, and add this tag to theindex.htmlIn the document.

6. The loader itself is configurable

The loader itself can realize different functions by configuring different parameters.

In the following example, we configuredurl-loaderWhen the picture is less than 1024byte, use DataURL; when the picture is raining heavily 1024byte, use URL. We pass in through the following twolimitParameter to implement this function:
图片描述

Babelrc document

babel-loaderUsepresetsTo specify how to convert ES6 code into ES5 code and how to convert JSX of React into JS. We can pass.queryMethod to configure:

module: {
 loaders: [
 {
 test: /\.jsx?  $/,
 exclude: /(node_modules|bower_components)/,
 loader: 'babel',
 query: {
 presets: ['react', 'es2015']
 }
 }
 ]
 }

However, babel’s configuration items will be very large in many projects. So instead, you can write these configuration items into a program called.babelrcIn the first half of this year. If this file existsbable-loaderThis file will be loaded automatically.

So in many cases, you will see:

//webpack.config.js
 module: {
 loaders: [
 {
 test: /\.jsx?  $/,
 exclude: /(node_modules|bower_components)/,
 loader: 'babel'
 }
 ]
 }
 
 //.bablerc
 {
 “presets”: [“react”, “es2015”]
 }

8. Plug-ins

Plug-ins are additional node modules that are mostly used to process output files.

For example,uglifyJSPluginJS code will be compressed and confused to reduce its size.

Similarly,extract-text-webpack-pluginWill be used internallycss-loaderAndstyle-loaderTo merge all CSS into one file, and finally extract the results to a separate externalstyle.cssIn the document, finally inindex.htmlThis CSS file is referenced in.

//webpack.config.js
 //Take all the .css files, combine their contents and it extract them to a single "styles.css"
 var ETP = require("extract-text-webpack-plugin");
 
 module: {
 loaders: [
 {test: /\.css$/, loader:ETP.extract("style-loader","css-loader") }
 ]
 },
 plugins: [
 new ExtractTextPlugin("styles.css") //Extract to styles.css file
 ]
 }

Note that if you only intend to use CSS as an inline style in HTML, you can use onlycss-loaderAndstyle-loader, like the following example:

module: {
 loaders: [{
 test: /\.css$/,
 loader: ‘style!  css’ // style-loader!  Abbreviations for css-loader
 }]

9. loader VS plug-in

As you may have already understood,To the extent of a single file, the loader runs before or during packaging..

AndPlug-ins operate in the process of outputting packaged files to the extent of packaging or data blocks.. Some plug-ins, such as commonsChunksPlugins, started to operate even at an earlier stage and can be used to modify the packaging method.

10. Resolve file extensions

Some Webpack configuration files have the property of parsing extended file names, and they contain some, like the following examplenull character string. These empty strings are used to help load files without extensions, such asrequire("./myJSFile")Or ..import myJSFile from './myJSFile'.

{
 resolve: {
 extensions: [‘’, ‘.js’, ‘.jsx’]
 }
 }

The full text is complete.

Thank tobias koppers (author of webpack) for helping me review this article!


Thank you for reading. I am Jrain, welcome to pay attention.My column, will not regularly share their learning experience, development experience, carrying dry goods outside the wall. See you next time!