"webpack5 actual combat 4" - loader

Posted by daucoin on Wed, 16 Feb 2022 01:51:26 +0100

Preface: the project has been packaged with webpack, and has systematically followed the video tutorial of station B, but I always feel that there is something wrong. Some configurations are still unknown. I decided to write down some examples, summarize the knowledge points, and learn webpack 5 by the way.

Catalogue of series articles

webpack5 practice 1: js/json packaging
css packaging of webpack5 Practice II
html packaging of webpack5 practice III

preface

The basic function of webpack loader is equivalent to a project plug-in, which can uniformly process the specified files. It is a function, which is equivalent to the source code. After this function, it becomes the desired target.

Official description:

Loader is used to convert the source code of the module. Loader allows you to preprocess files when importing or "loading" modules. Therefore, loader is similar to the "task" in other construction tools and provides a powerful way to deal with the front-end construction steps. Loader can convert files from different languages (such as TypeScript) to JavaScript or convert inline images to data URL s. Loader even allows you to import CSS files directly into JavaScript modules!

I don't need to repeat more. See the official document loader. The introduction is very detailed. This article mainly records the user-defined loader through actual combat to understand the whole process of loader work.

 

1, The simplest custom loader

preparation

The loader can be regarded as a function. The input is the source code and the output is processed by the loader.

Custom loader format:

/**
 *
 * @param {string|Buffer} content Contents of source file
 * @param {object} [map] Can be https://github.com/mozilla/source-map SourceMap data used
 * @param {any} [meta] meta Data can be any content
 */
function webpackLoader(content, map, meta) {
  // Your webpack loader code
}

The following goal is to create a hero loader of the hero League. The loader will replace the hero name and skills and add detailed instructions.

1. Create a custom loader file

hero-loader.js:

module.exports = function (source) {
  console.log(source);
  return  source.replace("Demacia","Hero alliance health brother: demacia!")
}

Such a loader is created. Next, use the loader

2. Use custom loader

On webpack config. JS file:

 {
                test:/\.js$/,
                use: "./src/custom-loader/hero-loader.js",   // Look here, look here
            }

Here is the storage path of the use r-defined loader file

3. Use verification

New hero js:

exports.hero ='Demacia'

New index js:

import hero from "./hero.js";
console.log(hero);

Next, execute the webpack packaging command to package and generate the file under dist. see the source code for the specific webpack configuration.

Import the packaged file into index HTML and open it in the browser.

As a result, demacia has been replaced with a more detailed introduction, which has been successful.

 

2, loader inline mode

target

  • Using loader by inline
  • Alias loading loader

1. Create a custom loader file

skill-loader:

module.exports = function (source) {
  return  source.replace("Big sword","R The skill is: big sword!")
}

2. webpack config configures alias loading

   resolveLoader:{
        alias:{
            'skill-loader':resolve(__dirname,'src/custom-loader/skill-loader.js')
        }
    }

3. Inline use

skill.js:

exports.skill = 'Big sword'

index.js import:

import skill from "!skill-loader!./skill.js";
console.log(skill);

4. Execute the webpack command to verify

Packaged files:

/***/ "./src/hero.js":
/*!*********************!*\
  !*** ./src/hero.js ***!
  \*********************/
/***/ ((__unused_webpack_module, exports) => {

eval("/*\n * @Author: ZY\n * @Date: 2022-02-14 16:26:29\n * @LastEditors: ZY\n * @LastEditTime: 2022-02-14 16:27:33\n * @FilePath: /webpack-demo/packages/loader-demo/src/hero.js\n * @Description: File description \ n */\n\nexports.hero ='Hero alliance health brother: demacia!'\n\n//# sourceURL=webpack:///./src/hero.js?");

/***/ }),

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _hero_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./hero.js */ \"./src/hero.js\");\n/* harmony import */ var _skill_loader_skill_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !skill-loader!./skill.js */ \"./src/custom-loader/skill-loader.js!./src/skill.js\");\n/*\n * @Author: ZY\n * @Date: 2022-02-14 11:44:14\n * @LastEditors: ZY\n * @LastEditTime: 2022-02-14 16:48:22\n * @FilePath: /webpack-demo/packages/loader-demo/src/index.js\n * @Description: File description \ n */\n\n\n\n\nconsole.log(_hero_js__WEBPACK_IMPORTED_MODULE_0__);\nconsole.log(_skill_loader_skill_js__WEBPACK_IMPORTED_MODULE_1__);\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ }),

/***/ "./src/custom-loader/skill-loader.js!./src/skill.js":
/*!**********************************************************!*\
  !*** ./src/custom-loader/skill-loader.js!./src/skill.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, exports) => {

eval("/*\n * @Author: ZY\n * @Date: 2022-02-14 16:26:35\n * @LastEditors: ZY\n * @LastEditTime: 2022-02-14 16:28:04\n * @FilePath: /webpack-demo/packages/loader-demo/src/skill.js\n * @Description: File description \ n */\n\nexports.skill = 'R The skill is: big sword!'\n\n//# sourceURL=webpack:///./src/skill.js?./src/custom-loader/skill-loader.js");

/***/ })

You can compare the difference between inline and webpack rule configuration

  • When collecting the code map, the key is different, and the loader path will be added in the internal two methods

index. Run results after html is imported into packaged js:

 

3, Loader interface

After understanding the use of basic loader, take a look at other advanced interfaces of loader.

The official website is very detailed, so I won't repeat it one by one here( Official website loader interface)

 

4, Loader parameters

When setting the loader, there are some variables that need the external environment. These variables can be set in the configuration.

webpack config provides loader configuration options. Here is a small example to illustrate this scenario.

1. Create a new select hero loader

The meaning of this loader is very clear. I want to choose heroes. Package them into the browser through the loader and tell me what heroes I choose.

The loader interface will be used here:

  • query or getOptions to get variables
  • resourcePath location using loaderjs

select-hero-loader.js :

module.exports = function (source) {
 const {heroName} =  this.query
 //You can also find the options map
//  const {heroName} =  this.getOptions()
 if (heroName && this.resourcePath.endsWith('select.js')) {
  this.callback(null,source.replace('You have chosen a hero',`You have chosen a hero:${heroName}`))
 }
  return source
}

2. webpack config configuration

It is easier to use inlining for a single file, but it is configured in the way of rule to keep the previous loader.

{
                test:/\.js$/,
                use: [
                    "./src/custom-loader/hero-loader.js",
                    {
                        loader:"select-hero-loader",
                        options:{
                            heroName:'Ice shooter'
                        }
                    }
                ]   // Look here, look here
            }

For these two custom loaders, you can verify the running order by adding log in the loader. They are executed from bottom to top. If you are interested, you can verify them yourself.

3. Use verification

select.js :

module.exports = function selectHero() {
  console.log(`You have chosen a hero`);
}

index.js :

import skill from "!skill-loader!./skill.js";
selectHero()

Execute webpack packaging and run to the browser:

 

4, Summary

Loder property

  • Loader supports chained calls. Each loader in the chain applies the transformation to the processed resources. A set of chained loaders will be executed in the reverse order. The first loader in the chain passes its result (that is, the converted resources applied) to the next loader, and so on. Finally, the last loader in the chain returns the JavaScript expected by the webpack.
  • The loader can be synchronous or asynchronous.
  • The loader runs on the node JS, and can perform any operation.
  • The loader can be configured through the options object (the query parameter is still supported to set options, but this method has been abandoned).
    In addition to the common through package JSON to export an npm module as a loader, or in module Rules use the loader field to directly reference a module.
  • Plug ins can bring more features to loader s.
  • loader can generate additional arbitrary files.

Topics: Javascript loader webpack5