Detailed use of webpack

what is webpack

Official definition: In essence, webpack is a modern JavaScript static module packaging tool.
Webpack is a solution for front-end engineering.
Main functions: Provides powerful functions such as front-end modular function support, module obfuscation, code compression, processing browser JS compatibility, and performance optimization.

webpack prerequisites

The premise of learning webpack is to know the modular knowledge of es6 or the knowledge of commonjs (not too deep), both of which provide modular functions. The modularization of es6 is the official standard, relatively new, and will definitely be the mainstream in the future, while commonjs has been around for a long time and has deep experience. It is better to know one or both. I didn’t learn to take a look, otherwise I wouldn’t understand the webpack example.
Other prerequisites:
javascript's es5 foundation (not too deep)
html (not too deep)
css (not too deep)
node.js (not too deep)

webpack installation

webpack depends on node.js. No need to install node.js first. Not to mention how to install it.

Install webpack3.6.0 this version.

npm install [email protected] -g

If you can see the version number, it means the installation was successful.

webpack -version

The basic process of using webpack

First create the directory, a main.js file, which is the entry file for js. The dist folder is used to store the packaged files, which will be used later. Because webpack supports modularization, a mathUtil.js is added to simply simulate modularization.
insert image description here
The code of main.js is as follows:
the code of mathUtils.js is called to realize simple output. The first line of code is the syntax of commonjs. If you don’t understand it, you just need to know that this is a reference module.

const {
    
    add,mult}=require("./mathUtils.js")
console.log(add(1,2))
console.log(mult(1,2))

mathUtils.js defines two methods and exports them for others to use.

function add(a, b) {
    
    
    return a+b
}

function mult(a, b) {
    
    
    return a*b
}

//使用commonJs导出
module.exports = {
    
    
    add,
    mult
}

The content of index.html is empty, which is the default html text, and nothing is written in it.
Analysis:
Now we have a main.js, which refers to the contents of mathUtils.js.
js is available, so should we quote it in js? The answer is no. If webpack is not used, we may refer to multiple js files, such as main.js and mathUtils.js. Of course, you may have many js files, and it is very troublesome to refer to them all. webpack can package these js files into one file. Then you only need to import the packaged file, and the packaging is very simple.
Executing the following code will generate a bundle.js file under the dist directory. This is the packaged file. Note that we only write main.js when packaging here, and webpack will help us package all the associated js files. . This is where webpack helps us simplify the steps. Compared with our manual references one by one, this is equivalent to an automatic reference. We only need to provide the entry js, which is our main.js js file.

webpack ./src/main.js ./disk/bundle.js

Let's take a brief look at the generated bundle.js. You don’t need to look at the previous code, but mainly look at the next few lines. The latter few lines actually merge the codes of main.js and mathUtils.js together, and there are some codes of commonjs, which are still not recognized by browsers. , A bunch of incomprehensible codes generated earlier are used to support commonjs.

/******/ (function(modules) {
    
     // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {
    
    };
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
    
    
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
    
    
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
    
    
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {
    
    }
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
    
    
/******/ 		if(!__webpack_require__.o(exports, name)) {
    
    
/******/ 			Object.defineProperty(exports, name, {
    
    
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
    
    
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() {
    
     return module['default']; } :
/******/ 			function getModuleExports() {
    
     return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) {
    
     return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
    
    

const {
    
    add,mult}=__webpack_require__(1)
console.log(add(1,2))
console.log(mult(1,2))

/***/ }),
/* 1 */
/***/ (function(module, exports) {
    
    

function add(a, b) {
    
    
    return a+b
}

function mult(a, b) {
    
    
    return a*b
}

//使用commonJs导出
module.exports = {
    
    
    add,
    mult
}

/***/ })
/******/ ]);

Finally, we only need to reference our generated bundle.js in index.html.

<script src="./dist/bundle.js"></script>

Open the browser to see the execution output of js.
insert image description here

Configuration of webpack

When we used webpack to package, we manually specified the path. These things can be written into the configuration file for our convenience.

webpack ./src/main.js ./disk/bundle.js

A webpack.config.js file needs to be created in the project root directory. This is the configuration file of webpack, which is called this name by default.
insert image description here
Write the following content, and then execute the webpack command in the terminal without adding any parameters. At this time, an error will be reported, telling you to use an absolute path. In fact, the following path is written incorrectly and requires an absolute path. It is not appropriate for us to write directly, but to obtain it through the path package provided by node.js.

module.exports = {
    
    
    entry:"./src/main.js",
    output:{
    
    
        path:"./dist",
        filename:"bundle.js"
    }
}

By default, there is no path package. We need to initialize the project as a node project.
Provide the following command to initialize the node project. To be executed in the parent directory of index.html.

npm init

You will be asked to fill in some values, do not write Chinese, if it is not Chinese, you can always default, and the specific configuration will be described later.
After completion, there will be an additional package.json file, which is the configuration file of node.
The content inside is roughly as follows.

{
    
    
  "name": "meetwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

insert image description here
Now you can use the path library provided by node.
Import the library through require, get the absolute path through the path.resolve method, __dirname is the project path provided by the path library

const path=require("path")
module.exports = {
    
    
    entry:"./src/main.js",
    output:{
    
    
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js"
    }
}

Now we can use webpack to package directly without specifying the path.
insert image description here

Running webpack in the previous way is already available. But there is a better way. That is to run webpack using node's script.
The previous problem is that we may have multiple webpack configuration files, one for the production environment and one for the development environment, so if the environment changes, our webpack packaging command needs to specify the configuration file.
The configuration file name was not specified earlier because the default configuration file name is called webpack.config.js.

webpack production.config.js

We can use a more flexible way, which is to configure these commands into the script. The following command is to run the build script, which is defined by ourselves.

npm run build

Inside our package.json we have the following script. We can create our own build script here, and a script called test is written by default.

  "scripts": {
    
    
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }

Now execute npm run build to achieve the same effect as before.
insert image description here
There is still a problem here, that is, when we execute commands in the terminal, we call the global webpack command. This will cause problems, because in actual projects, local and global may need to use different versions for some reason. Using globals will cause problems.
At this time, we need to install a local version.

 npm install [email protected] --save-dev

After execution, the following directory will appear. node_modules contains all the modules of node, there are hundreds of them, and webpack is inside.
By default, executing webpack in the terminal is to execute the global node, unless it is written as follows

./node_modules/webpack xxxxx

Of course, now we have a better way, just execute the following code, and this is the final effect.

npm run build

insert image description here
And package.json will have the following nodes.

  "devDependencies": {
    
    
    "webpack": "^3.6.0"
  }

webpack configuration CSS

We first create the css directory and add the normal.css file, the content is as follows.

body{
    
    
    background-color: lightgreen;
}

Adjust the js file structure and expose the main.js as the entry to the outside.
insert image description here

At this time, we don't introduce css code into html, but hand it over to webpack.

Webpack itself does not support CSS functions, and these functions are provided through loaders.
We only need to load the corresponding loader to realize the corresponding function.
webpack provides many loaders, CSS loader is just one of them.

We open the documentation:
https://www.webpackjs.com/loaders/#%E6%A0%B7%E5%BC%8F

There are only two css loaders we need to use, one is css-loader, which is used to parse the css code and return the css code. If you only use this loader alone, it will have no effect, because this loader is only responsible for loading, not for exporting and displaying to dom. So we also need a style-loader module, which is dedicated to this.
insert image description here
Install the module, the 0.9.0 corresponding to webpack 3.6.0 can be used, and a warning will be given if the version is too high.
Using npm seems to directly report an error, but cnpm only has a warning, and gives a hint that the current version can only correspond to the version range.

npm install --save-dev [email protected]
npm install [email protected] --save-dev

Then you need to add a module node in the configuration file and add the content of rules.
It should be noted that the two loaders in use are loaded later, and if the order is wrong, an error will be reported, as stated in the document. Don't know why it's designed this way.

const path=require("path")
module.exports = {
    
    
    entry:"./src/main.js",
    output:{
    
    
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js"
    },
    module: {
    
    
        rules: [
            {
    
    
                test: /\.css$/,
                use: [
                    {
    
     loader: "style-loader" },
                    {
    
     loader: "css-loader" }
                ]
            }
        ]
    }
}

At this time, execute the following code and then run index.html to see the css style

npm run build

If the background color changes, it means success.

webpack configuration less

The configuration of less is similar to the configuration of css.
One difficulty here is the version issue, you simply don't know what version matches your webpack.
And the version number is not unified, a loader is an independent version number.
The solution is to go to github to directly search for the loader you want to install, such as the less-loader here, and click on a tag version. Check the package.json inside, and you can see the version range of webpack in it.
It is similar for any loader, and these loaders are officially released by webpack.
It is possible to use the following version corresponding to webpack3.6.0, but it will tell you that it has been abandoned, and the math method has a bug. The actual project is still not used, and the webpack version should be upgraded.

npm install --save-dev [email protected] [email protected]

Add the following code under the rules node under webpack.config.js.

{
    
    
                test: /\.less$/,
                use: [{
    
    
                    loader: "style-loader" // creates style nodes from JS strings
                }, {
    
    
                    loader: "css-loader" // translates CSS into CommonJS
                }, {
    
    
                    loader: "less-loader" // compiles Less to CSS
                }]
            }    

Create a css folder and prepare our special.less test file in it.
insert image description here

@fontSize:50px;
@fontColor:lightblue;
body{
    
    
  font-size: @fontSize;
  color: @fontColor;
}

Reference less in main.js

require("./css/special.less")

Add the following content to index.html:

<div id="box">
  Hello Webpack
</div>

Finally run.

npm run build

If the effect is correct, the configuration is successful.

Webpack's processing of images

Images also need a loader. There are two types of images in webpack. You can configure a limit attribute in the configuration file to determine whether the size of the image exceeds this value. If it is smaller than this value, it will be treated as base64. If it is larger than this value, it will be treated as a normal image file.
The version must be 1.1.2, 1.0.0 cannot display pictures, for webpack3.6.9.

npm install --save-dev [email protected]

The key point here is that there is an additional limit, which is the image size limit we mentioned above.

{
    
    
        test: /\.(png|jpg|gif)$/,
        use: [
          {
    
    
            loader: 'url-loader',
            options: {
    
    
              limit: 8192
            }
          }
        ]
}

Introduce two pictures, the size of gun.jpg is 4kb, and the size of baidu.png is 15kb.insert image description here

Specify the background of the body as gnu.jpg, because the size of the image is smaller than the limit, so the image will be transmitted in the form of base64.

body{
    
    
    /*background-color: lightgreen;*/
    background: url("../img/gnu.jpg");
}

insert image description here
Execute the following code, you can see the effect.

npm run build

insert image description here
If you change the picture to baidu.jpg, an error will be reported directly. Telling you that file-loader cannot be found. As mentioned earlier, there are two ways for webpack to process images. When the size of the image is smaller than the limit, the base64 string method is used. At this time, you need to use url-loader, and when the picture is larger than the limit, you cannot use url-loader, but use file-loader.

Module build failed: Error: Cannot find module 'file-loader'

Download file-loader.

 npm install [email protected] --save-dev

Configure file-loader.
The previous url-loader is implemented based on the file-loader, and only one of the two can be written, and pictures cannot be generated by writing at the same time.
The previous url-loader is implemented based on the file-loader, and only one of the two can be written, and pictures cannot be generated by writing at the same time.
The previous url-loader is implemented based on the file-loader, and only one of the two can be written, and pictures cannot be generated by writing at the same time.

{
    
    
        test: /\.(png|jpg|gif)$/,
        use: [
          {
    
    
            loader: 'file-loader',
            options: {
    
    }
          }
        ]
      }

After compiling and running, it is found that the picture does not display. However, pictures are generated in the dist directory.
insert image description here
Let's look at the url address of the browser body. The path is wrong, and a dist/ should be added in front. This can be achieved by providing a configuration.

url(d9c8750bed0b3c7d089fa7d55720d6cf.png)

You need to add the publicPath node in the webpack configuration file.

    output:{
    
    
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js",
        publicPath:"dist/"
    },

Now baidu.jpg can be displayed as a picture.
We are unlikely to put all the pictures in the dist root directory. It is more reasonable to create an img directory for dist. The following code can be provided for implementation. [name] means the original file name [hash:8] means the 8-bit hash value, if not written, the default is 32 bits, and [ext] means the extension. This is very engineering.

options: {
    
    
       name:"img/[name]-[hash:8].[ext]"
}

Output effect:
insert image description here

Convert ES6 syntax to ES5 syntax

One of the biggest advantages of webpack is that it helps us deal with some compatibility issues. It can be achieved through babel-loader.

npm install [email protected] @babel/core @babel/preset-env

Add the following to the webpack configuration file:

{
    
    
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
    
    
        loader: 'babel-loader',
        options: {
    
    
          presets: ['@babel/preset-env']
        }
      }
    }

Observe the output js file, the previous const and other es6 grammars have been converted into es5 grammars.

Guess you like

Origin blog.csdn.net/ScottePerk/article/details/126676076