Webpack is a tool to package modular JavaScript. In Webpack, all files are modules, through Loader to convert files, through Plugin to inject hooks, and finally output files composed of multiple modules. Webpack specializes in building modular projects called module balers.

1. Core concepts

entry

Entry, the first step in the build that Webpack performs will start with entry, which can be abstracted into input;

module.exports = {
  entry: './main.js'
};
Copy the code

output

Output the result after Webpack has gone through a series of processes to get the desired code;

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist'); }};Copy the code

loader

Module converter, used to convert the original content of the module into new content as required;

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist');
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader'.'css-loader? minimize'],}]}};Copy the code

plugins

Extension plug-ins, which inject extension logic at specific points in the Webpack build process to change the build result or what we want to do;

module.exports = {
  entry: './main.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist');
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        loaders: ExtractTextPlugin.extract({
          use: ['css-loader']
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin({
      fliename: `[name]_[contenthash:8].css`,
    })
  ]
};
Copy the code

module

Modules, in Webpack everything is a module, a module for a file. Webpack recursively finds all dependent modules starting from the configured entry;

chunk

Code block: a chunk is composed of multiple modules for code merging and segmentation;

Summary: Webpack starts with the Module configured in Entry and recursively parses all modules that Entry depends on. When a Module is found, the system finds the corresponding conversion rule based on the configured Loader, converts the Module, and resolves the Module dependent on the current Module. These modules are grouped by Entry, and each Entry and all its dependent modules are grouped into a group called a Chunk. Finally, Webpack converts all chunks into file output, executing the logic defined in Plugin at appropriate times throughout the process.

2. Perform basic configuration

1. Entry

  • context

Webpack uses context as the root directory when looking for files with relative paths. Context defaults to the current working directory. Note that context must be an absolute path string.

module.exports = {
  context: path.resolve(__dirname, 'app'),};Copy the code
  • Entry type
type example meaning
String ‘./main.js’ The file path of the entry module, which can be a relative path
Array [‘./main.js’, ‘./app.js’] The file path of the entry module, which can be a relative path
Object {a: ‘./main.js’, b: ‘./app.js’} Configure multiple entries and generate one chunk for each entry
  • The name of the chunk

The name of chunk is related to the configuration of the entry. If the entry is a String or Array, only one chunk is generated. If an entry is an Object, multiple chunks are generated, named as keys in Object.

  • Configuring Dynamic Entry

If you are not sure how many page entries there are, you can set a function to dynamically return entry configuration.

// Synchronization function entry: () => {return {
    a: './page1/index',
    b: './page2/index'}} // Asynchronous function entry: () => {return new Promise( (resolve) => {
    resolve({
      a: './page1/index',
      b: './page2/index'})})}Copy the code

2. Output

  • filename

Filename is the name of the configuration output file. It is a string file. If there is only one output file, it can be written to bundle.js, but if there are multiple outputs, you can use template variable [name].js.

The variable name meaning
id The unique identifier of Chunk, starting from 0 by default
name The name of the Chunk
hash Hash value of the unique identifier of Chunk. [Hash :8] indicates the 8-bit Hash value. The default value is 20 bits
chunkhash The Hash value of Chunk content is the same as the preceding
  • chunkFilename

The CommonChunkPlugin is used to specify the file name of Chunk generated during the runtime. Supports built-in variables consistent with filename;

  • path

The local directory of the output file is a string absolute path. String templates are supported. The built-in variable has only one Hash.

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist_[hash]')}};Copy the code
  • publicPath

Configure the URL prefix to publish to online resources. The URL prefix is string relative path, default is “”, also support string template, built-in variable has only one Hash;

module.exports = {
  output: {
    filename: '[name]_[chunkhash:8].js',
    publicPath: 'https://XX.cdn.com/static/'}};Copy the code
  • crossOriginLoading

Some of the code blocks output by Webpcak may need to be loaded asynchronously, which is implemented through JSONP, so you can set the Crossorigin attribute in the

Crossorigin attribute values meaning
Anonymous (default) When this script resource is loadedDon’tBring the user’s cookie
use-credentials When this script resource is loadedwillBring the user’s cookie
  • LibraryTarget and library

LibraryTarget and Library are used when using Webpack to build a library that can be imported and used by other modules. LibraryTarget and Library are usually used together. Rollup is recommended to build the base library.

LibraryTarget configuration and how to export base, the commonly used var/this/commonjs/window/global, etc.; Library Configuration export Library name used in conjunction with LibraryTarget;Copy the code
  • LibraryExport

The output. LibraryTarget is set to commonJS or commonjs2.

// A module source codeexport const a = 1;
exportdefault b = 2; // If output.libraryExport is set to a; Module.export = lib_code[// Webpack output module.export = lib_code['a']; // Use the library's method require('library-name') = = = 1;Copy the code

3. Module

  • Configure the Loader

Rules Configures the read and parse rules of the module and is usually used to configure the Loader. The type is array, each item in the array describes how to process part of the file, each item roughly has the following three ways to complete;

  1. Conditional matching: Use test, include, and exclude to select the file to be processed by the Loader.
  2. Application rule: Use the use configuration item to apply the Loader to the selected file. The Loader can be one or a group of Loaders from back to front, and parameters can be passed to the Loader respectively.
  3. Important order: The default order of a group of Loaders is from right to left. Use enforce to place one of them first (pre) or last (post).
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [{
          loader: 'babel-loader',
          options: {
            cacheDirectory: true
          },
          enforce: 'post'
        }],
        include: path.resolve(__dirname, 'src'),}, {test: /\.scss$/,
        use: ['style-loader'.'css-loader'.'sass-loader'],
        exclude: path.resolve(__dirname, 'node_modules'}]}};Copy the code
  • noParse

This optional configuration allows Webpack to improve build performance by ignoring recursive parsing and processing of files that are not modularize. The types are RegExp, [RegExp], Function, The ignored file cannot contain modular statements such as import, require, and define. Otherwise, the modular statements cannot be executed in the browser.

/ / regular form noParse: / jquery | chartjs noParse: / / / function (content) = > {return /jquery|chartjs/.test(content);
}
Copy the code
  • parser

This configuration item is syntactic enough that Webpack only parses the corresponding modularity files;

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader'],
        include: path.resolve(__dirname, 'src'),
        parser: {
          amd: false,
          commonjs: true,
          requirejs: false,
          harmony: true}}]}};Copy the code

4. Resolve

  • alias

This configuration item maps the original import path to a new import path through an alias.

module.exports = {
  resolve: {
    alias: {
      @components: './src/common/components',
      @assets: './src/common/assets'}}};Copy the code
  • mainFields

Some third-party modules provide several pieces of code for different environments, such as ES5 and ES6, respectively. Webpack decides which one to use first based on the configuration of mainFields. If you want to use ES6 code first, you can configure it as follows:

mainFields: ['jsnext:main'.'browser'.'main'].Copy the code
  • extensions

When an import statement does not have a file suffix, Webpack automatically adds the suffix to try to see if the file exists. The default is:

extensions: ['.js'.'.json'].Copy the code

If we want Webpack to use typescript files first, we can configure it like this:

extensions: ['.ts'.'.js'.'.json']
Copy the code
  • modules

Configure which directories Webpack will look for third-party modules. Sometimes a large number of modules in our project will be placed under Common.

modules: ['./src/common'.'node_modules']
Copy the code
  • descriptionFiles

This configuration item is the name of the file that describes the third-party module, namely package.json. The default is as follows:

descriptionFiles: ['package.json']
Copy the code
  • enforceExtension

If resolve.enforceextension is true, all import statements must be suffixed, such as import ‘./main.js’;

  • enforceModuleExtension

Just like the enforceExtension set to true, the enforceExtension works exclusively with modules under node_modules, because most third-party modules have no suffix. When the enforceExtension is set to True, Need to resolve. EnforceModuleExtension set to false to compatible with third-party modules;

5. Plugin

Plugins are simple to configure. Plugins receive an array, and each item in the array is an instance of the Plugin. Plugin parameters are passed in through the constructor.

module.exports = {
  plugins: [
    new CommonChunkPlugin({
      name: 'common',
      chunks: ['a'.'b']]}});Copy the code

6. DevServer

  • hot

Enable the module hot replacement function, without refreshing the whole page, by replacing the old module with new module to achieve real-time preview;

  • inline

It is used to configure whether the proxy client is automatically injected to run in the chunk of the page.

— If inline is enabled, DevServer controls the page refresh through the proxy client when building the changed code;

— If inline is turned off, DevServer will run the web page as an iframe and refresh the iframe to preview the changes in real time when the code is built. At this moment need to go to http://localhost:8080/webpack-dev-server/ real-time preview your web page;

  • historyApiFallback

For easy development of a single page application using HTML5’s History API, it always returns the same HTML file and the browser will parse the current page state from the URL to display the corresponding interface;

  • contentBase

The root directory of the file used to configure the DevServer HTTP server. By default, it is the current execution directory, usually the root directory of the project, so you do not need to set it in general.

  • headers

You can inject HTTP response headers into the HTTP response using the following:

module.exports = {
  devServer: {
    headers: {
      'x-cookie': 12345}}};Copy the code
  • host

If you want other devices on the LAN to access your local service, you can start devServer with the parameter –host 0.0.0.0.

  • port

By default, port 8080 is used. If port 80 is occupied by other programs, +1 is used successively.

  • allowedHosts

Configure a whitelist in which only HTTP hosts are returned.

  • disableHostCheck

Configure whether to disable host checking for HTTP requests for DNS rebinding. Devserver accepts only local requests by default, and can accept requests from any host after disabling devServer.

  • https

Devsever uses HTTP by default. If you need to use HTTPS, you can enable this configuration. Devsever automatically generates an HTTPS certificate for you.

  • clientLogLevel

The default log level is INFO. Logs of all types (None/Error/Warning/INFO) are generated.

  • compress

Configure whether to enable Gzip compression. The value is a Boolean. The default value is false.

  • open

When DevServer starts and the first build is completed, it automatically opens the page we developed with the default browser of the system, and also provides the openPage configuration item to open the page with the specified URL;

7. Other

  • Target

The target configuration allows Webpack to build code for different runtime environments. Common examples are:

The target value meaning
web For browsers (the default), all code is in one file
node For NodeJS, use the require statement to load the Chunk code
async-node Load chunk code asynchronously for NodeJS
webworker In view of the webworker
electron-mian For the Electron main thread
electron-render For the Electron render thread
  • Devtool

Configure how Webpack generates the Source Map. The default value is false, that is, not to generate the Source Map. If you want to build code to generate the Source Map for debugging, you can configure it as follows:

module.exports = {
  devtool: 'source-map'
};
Copy the code
  • Watch and WatchOptions

Webpack supports listening for file updates and recompiling when the file changes. The listening mode is turned off by default.

module.exports = {
  watch: true
};
Copy the code

When devServer is used, the listening mode is enabled by default. In addition, the monitoring mode can be flexibly controlled.

module.exports = {
  watch: true// ignore: /node_modules/. // aggregateTimeout is 300ms. // default is 300ms. Poll: 1000}}; poll: 1000}; poll: 1000}; poll: 1000};Copy the code
  • Externals

These templates are used to tell Webpack which unpackaged modules are used in the code to build, that is, these templates are provided by the external environment and Webpack can ignore them when packaging.

module.exports = {
  externals: {
    jquery: 'jQuery'}};Copy the code
  • ResloveLoader

Used to tell Webapck how to find Loader. This configuration item is used to load the local Loader. The default configuration is as follows:

module.exports = {
  resolveLoader: {
    modules: ['node_modules'],
    extensions: ['js'.'json'],
    mainFields: ['loader'.'main']}};Copy the code

3. Performance optimization

Optimize development experience:

1. Narrow down the file search scope

2. Use DllPlugin

3. Use HappyPack

4. Use ParallelUglifyPlugin

5. Use automatic refresh

6. Enable hot replacement

Optimize output quality:

1. Compress code

2. The CDN acceleration

3. Extract common code

4. Tree Shaking

5. Use Code Spliting

6. Start the Scope collieries

7. Output analysis

4. Commonly used Loader

file

The name of the Loader Functional description
raw-loader Load the original contents of the file (UTF-8)
val-loader Execute code as a module and export to JS code
url-loader Works like a File loader, but can return if the file is smaller than the limitdata URL
file-loader Send the file to the output folder and return the (relative) URL

JSON

The name of the Loader Functional description
json-loader loadingJSONFiles (included by default)
json5-loader Load and translateJSON 5file

Transpiling

The name of the Loader Functional description
script-loader Execute a JavaScript file once in a global context (such as in a script tag) without parsing
babel-loader Load the ES2015+ code and use itBabelTranslated into ES5
buble-loader useBubleLoad the ES2015+ code and translate it to ES5
traceur-loader Load the ES2015+ code and use itTraceurTranslated into ES5
ts-loaderawesome-typescript-loader Load like JavaScriptTypeScript2.0 +
coffee-loader Load like JavaScriptCoffeeScript

Template (Templating)

The name of the Loader Functional description
html-loader Export HTML as a string that references a static resource
pug-loader Load the Pug template and return a function
jade-loader Load the Jade template and return a function
markdown-loader Translate Markdown to HTML
react-markdown-loader Compile markDown into the React component using markdown-parse parser
posthtml-loader usePostHTMLLoad and convert HTML files
handlebars-loader Move Handlebars to HTML
markup-inline-loader Convert the inline SVG/MathML file to HTML. Useful when applying icon fonts, or CSS animations to SVG.

style

The name of the Loader Functional description
style-loader Add the module’s export to the DOM as a style
css-loader After parsing the CSS file, load it using import and return the CSS code
less-loader Load and translate LESS files
sass-loader Load and translate SASS/SCSS files
postcss-loader usePostCSSLoad and translate CSS/SSS files
stylus-loader Load and translate the Stylus file

Linting && Testing

The name of the Loader Functional description
mocha-loader usemochaTesting (browser /NodeJS)
eslint-loader PreLoader, useESLintClean up the code
jshint-loader PreLoader, useJSHintClean up the code
coverjs-loader PreLoader, useCoverJSDetermine test coverage

Framework (Frameworks)

The name of the Loader Functional description
vue-loader Load and translateVue components
polymer-loader Using the selection preprocessor, andrequire()A Web component that resembles a first-class module
angular2-template-loader Load and translateAngularcomponent

5. The Plugin is commonly used

The name of the Plugin Functional description
AggressiveSplittingPlugin Break up the original chunk into smaller chunks
BabelMinifyWebpackPlugin usebabel-minifyBe compressed
BannerPlugin Add a banner at the top of each generated chunk
CommonsChunkPlugin Extract common modules shared between chunks
CompressionWebpackPlugin A pre-prepared compressed version of the resource that provides access to the service using Content-Encoding
ContextReplacementPlugin rewriterequireThe inferred context of the expression
CopyWebpackPlugin Copy a single file or entire directory to the build directory
DefinePlugin Global constants that are allowed to be configured at compile time
DllPlugin To greatly reduce build time, separate packaging
EnvironmentPlugin DefinePluginprocess.envShort for key.
ExtractTextWebpackPlugin Extract text (CSS) from bundles into separate files
HotModuleReplacementPlugin Enable Hot Module Replacement – HMR
HtmlWebpackPlugin Simply create AN HTML file for server access
I18nWebpackPlugin Added internationalization support for bundles
IgnorePlugin Exclude certain modules from the bundle
LimitChunkCountPlugin Set the minimum/maximum limit for chunks to fine tune and control chunks
LoaderOptionsPlugin Used to migrate from Webpack 1 to WebPack 2
MinChunkSizePlugin Ensure that the chunk size exceeds the specified limit
NoEmitOnErrorsPlugin A compilation error was skipped during the output phase
NormalModuleReplacementPlugin Replaces resources that match the regular expression
NpmInstallWebpackPlugin Missing dependencies are installed automatically at development time
ProvidePlugin You don’t need to use modules with import/require
SourceMapDevToolPlugin More granular control of the Source Map
EvalSourceMapDevToolPlugin More fine-grained control of the Eval Source Map
UglifyjsWebpackPlugin You can control the version of UglifyJS in your project
ZopfliWebpackPlugin A pre-compressed version of the resource via Node-Zopfli

For more third-party Loaders and plugins, see the awesome- Webpack list.

This article is organized in the “simple Webpack”, if there is an error, please yazheng 😄

More exciting content welcome to follow my official account [God helps Those who help Themselves Lewis]