What is the webpack

Webpack can be viewed as a module baler: What it does is analyze the structure of your project, find JavaScript modules and other extension languages that browsers don’t run directly (Scss, TypeScript, etc.), and package them into a format that browsers can use.

The installation

Environment: nodeJS official website addressnodejs.org/en/

Version Refer to the latest version released on the official website to improve the packaging speed of WebPack

Global Installation (not recommended)

NPM install webpack webpack-cli -g

Webpack-cli can help us use NPX,webpack and other related commands in the command line.

View the current Webpack version: webpack-v

Uninstall webpack globally: NPM uninstall webpack webpack-cli -g

Partial installation (in-project installation)

Install: NPM install webpack webpack-cli –save-dev

View version:

Webpack -v // Command not found Is found in the global environment by default

NPX webpack -v // NPX helps us find webpack in node_modules of the project

Install the specified version:

** NPM info webpack ** // View the history of webpack releases

npm install webpack@xxx webpack-cli -D

Webpack configuration file

Zero configuration is very weak, and specific requirements always need to be configured themselves.

When we use NPX webpack index.js, we are using WebPack to handle the packaged entry module named index.js. By default, the dist directory is in the current directory, and the packaged module name is main.js. Of course, we can also modify webpack. There is a default configuration file called webpack.confifig.js, which we can modify and customize.

  • The default configuration file is webpack.config.js

After executing the NPX webpack command, Webpack finds the default configuration file and uses it to execute.

  • Do not use the default configuration file: webPackConfifig.js

Specify that webpack uses the webPackconfig.js file as the configuration file and execute:

npx webpack –config webpackconfig.js

  • Modify the package.json scripts field

     “scripts”:  {

          “bundle”:”webpack”

      }

Do not add NPX to this area, because NPM run commands will be used in the project first

Package, the effect is very similar to NPX. Run the NPM run bundle command

Core WebPack concepts

entry

Specify package entry files :Webpack performs the first step in the build starting with entry, which can be abstracted as input

Entry: {main: '. / SRC/index. Js'} = = is equivalent to short = = = entry: ". / SRC/index. Js. ""Copy the code

output

Packaged file output location: Output after Webpack has gone through a series of processes to produce the desired code.

Output: {publicPath:" XXX ", filename: "bundle.js", path: path.resolve(__dirname, "dist") // must be absolute path}Copy the code

loader

Module converter, used to convert the original content of the module into new content as required. Webpack is a module packaging tool, and modules are not just JS, they can be CSS, images or other formats. But webpack only knows how to handle JS modules by default, so other formats of module processing, and processing methods need loader.

moudle

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

module: {
 rules: [
 {
  test: /\.xxx$/,
  use: {
      loader: 'xxx-loadr'
      }
   }
 ]
}
Copy the code

When webpack processes an unknown module, it is necessary to configure the module in Webpack. When the module is detected, what loader is used to process it.

  • file-loader

Process static resource modules. The principle is to move the resource module identified in the package entry to the output directory and return an address name.

So when do we use fifile-loader?

Scenario: when we need modules, just move from source to package directory, we can use fifile-loader to handle TXT, SVG, CSV, Excel, image resources and so on.

Install: NPM install file-loader -d

Case study:

Module: {rules: [{test: / \ | GIF (PNG | jpe? G) $/, / / use the use of a loader can use object, string, two loader need to use an array to use: {loader: "File-loader ", // options Additional configuration, such as resource name options: {/ / placeholder placeholder [name] old resources module name / / / ext old resources module of the suffix name: / / https://webpack.js.org/loaders/file-loader#placeholders "[name] _ [hash] [ext]", / / the location after packaging outputPath: "images /]}}}}"Copy the code
  • url-loader

Fifile-loader can handle all sorts of things, but when it encounters a JPG module, it converts the image to a Base64 string and packages it into JS. It is suitable for small size images, not large ones.

NPM install url-loader -d

Case study:

module: { rules: [ { test: /\.(png|jpe?g|gif)$/, use: { loader: "url-loader", options: { name: "[name]_[hash].[ext]", outputPath: "images/", // base64 limit: 2048}}}]}Copy the code
  • Style to deal with

Css-loader analyzes the relationship between CSS modules and synthesizes a CSS.

Style-loader will mount the content generated by CSS-loader to the head section of the page in style.

Install: NPM install style-loader CSS-loader -d

Case study:

{
 test: /\.css$/,
 use: ["style-loader", "css-loader"]
}
Copy the code
  • Sass style processing

Sass-loader converts SASS syntax into CSS and relies on the Node-sass module.

NPM install sass-loader node-sass -d

Case study:

{test: /\. SCSS $/, use: ["style-loader", "css-loader", "sas-loader "]} Loaders are ordered from right to left and from bottom to topCopy the code
  • postcss-loader

Styles are automatically prefixed and compatible with non-stop browser versions

Installation: NPM I postCSs-loader -d

Case study:

{
 test: /\.css$/,
 use: ["style-loader", "css-loader", "postcss-loader"]
}
Copy the code

Create the postcss.confifig.js file in the root directory and install autoprefixer

Install: NPM I autoprefixer -d

module.exports = {
 plugins: [require("autoprefixer")]
}
Copy the code

plugins

Plugins can do something for you when webPack is running at a certain stage, similar to the concept of a life cycle.

Inject extension logic at specific points in the Webpack build process to change the build result or do what you want.

  • HtmlWebpackPlugin

Htmlwebpackplugin automatically generates an HTML file after packaging, and introduces the JS module generated by packaging into the HTML.

NPM install –save-dev html-webpack-plugin

Configuration:

Title: The title element used to generate the page

Filename: indicates the output HTML filename. The default is index.html. You can also configure the file with a subdirectory.

Template: the path to a template file that supports loaders such as HTML! . / index. HTML.

Inject: true | ‘head’ | ‘body’ | false, the injection of all resources to a specific template or

In templateContent, if set to true or body, all javascript resources will be placed in the body

At the bottom of the element, ‘head’ will be placed in the head element.

Favicon: Adds a specific Favicon path to the output HTML file.

Minify: {} | false, pass HTML – minifier option to minify the output.

Hash: true | false, if true, will add a unique webpack compile hash to all scripts and contain

CSS file, very useful for removing cache.

Cache: true | false, if true, this is the default value, just won’t be published file after file modification.

ShowErrors: true | false, if true, this is the default value, error message will be written to the HTML page.

Chunks: allows only certain chunks to be added (for example, only unit test chunks)

ChunksSortMode: allows the control block is added to the page before the sort of way, support value: ‘none’ | ‘default’ |

{function}-default:’auto’

ExcludeChunks: Allows certain blocks to be skipped (for example, blocks for unit tests).

Case study:

const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
 ...
 plugins: [    new htmlWebpackPlugin({
       title: "My App",
       filename: "app.html",
       template: "./src/index.html"
    })
 ]
}
Copy the code
  • clean-webpack-plugin

Use to delete/clean up your build folder each time you pack

NPM install –save-dev clean-webpack-plugin

Case study:

const { CleanWebpackPlugin } = require("clean-webpack-plugin"); . plugins: [ new CleanWebpackPlugin() ]Copy the code
  • mini-css-extract-plugin

Extract the CSS styles to form a CSS file, and link a CSS file in the head tag

Install: NPM install –save-dev mini-css-extract-plugin

Case study:

const MiniCssExtractPlugin = require("mini-css-extract-plugin"); . modules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] } ]plugins: [ new MiniCssExtractPlugin({ filename: "[name].css" }) ]Copy the code

sourceMap

Mapping of source code to packaged code

In dev mode, this is enabled by default, and can be disabled in the configuration file

Eval: the fastest, using EVAL to wrap module code,

Source-map: generates the. Map file

Cheap: fast, does not care about the column information and does not include the loader sourcemap

Module: third-party Module containing loader sourcemap (e.g. JSX to JS, Babel sourcemap)

Inline: embed.map as a DataURI, not generate a separate.map file

Recommended configurations:

Devtool :"none" devtool:"cheap-module-eval-source-map",// development environment configuration devtool:"cheap-module-source-map", // online generation configurationCopy the code

WebpackDevServer

Every time you change the code, you have to repackage it, open the browser, and refresh it. We can install and use webpackdevserver to improve the experience. When you start the service, you find that the dist directory is gone, because devServer places the packaged modules not in the dist directory, but in memory to speed things up.

Install: NPM install webpack-dev-server -d

Modify package.json:

"scripts": {
    "server": "webpack-dev-server"
 }
Copy the code

In webpack.confifig.js configuration:

devServer: {
 contentBase: "./dist",
 open: true,
 port: 8081
}
Copy the code

Hot Module Replacement (HMR: Hot Module Replacement)

DevServer {contentBase: './dist', open: true, hot: true, // hotOnly:true}Copy the code

The header of the configuration file introduces WebPack and adds:

const webpack = require('webpack')
plugins: [
 new CleanWebpackPlugin(),
 new HtmlWebpackPlugin({
 template: "src/index.html"
 }),
 new webpack.HotModuleReplacementPlugin()
 ]
Copy the code

Babel processing ES6

Install: NPM I babel-loader @babel/ core@babel /preset- env@babel /polyfill -d

Babel-loader is the communication bridge between WebPack and Babel, and will not turn ES6 to ES5. This work needs to use @babel/preset-env, which contains the conversion rule of ES6 to ES5. But syntax features like Promise, async/await have not been converted, so @babel/ Polyfifill is needed to add es features to compensate for the missing features in the older browser.

{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", options: { presets: ["@babel/preset-env"]}} // index.js top import '@/ Babel /polyfill' const arr = [new Promise(() => {}), new Promise(() => {})]; arr.map(item => { console.log(item); });Copy the code

Polyfifill injects all features into the package by default. If I want to use es6+, I inject them. If I don’t use them, I don’t inject them. Of course, modify the webpack.config.js configuration.

options: { presets: [ [ "@babel/preset-env", { targets: { edge: "17", firefox: "60", chrome: "67", safari: }, useBuiltIns: "usage"}]]}Copy the code

@babel/plugin-transform-runtime

When we are developing component libraries, tool libraries, etc., polyfill is not suitable, because polyfill is injected into the global variable, window, will pollute the global environment, so we recommend closure: Babel /plugin-transform-runtime, which does not cause global pollution.

Installation:

npm install –save-dev @babel/plugin-transform-runtime

npm install –save @babel/runtime

Comment out polyfill in index.js

// index.js top // import '@/ Babel /polyfill' const arr = [new Promise(() => {}), new Promise(() => {})]; arr.map(item => { console.log(item); });Copy the code

Modify the configuration file: Comment out the presets and add plugins

options: {
    "plugins": [      [
      "@babel/plugin-transform-runtime",
        {
        "absoluteRuntime": false,
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
        }
      ]
     ]
}
Copy the code

The Development vs Production model differentiates packaging

Install: NPM install webpack-merge -d

Case study:

const merge = require('webpack-merge')
const commonConfig = require('./webpack.common.js')
const devConfig = {
    ...
}
module.exports = merge(commonConfig, devConfig)
Copy the code

In the package. The json configuration

"scripts":{
 "dev":"webpack-dev-server --config ./build/webpack.dev.js",
 "build":"webpack --config ./build/webpack.prod.js"
}
Copy the code