Webpack loader and Plugin provide us with powerful functions, let’s simply implement webpack-loader, by the way, publish to NPM, and use NPM link to debug our module locally.

Realize the loader

The main function of this loader is to insert a custom message in the packaged bundle

// Create a new project
mkdir bundle-author-loader

npm init -y

npm install webpack webpack-cli --save-dev
Copy the code

Root directory to create the WebPack configuration file

// webpack.config.js
const path = require("path");

module.exports = {
  mode: "development".entry: "./src/index.js".output: {
    filename: "bundle.js".path: path.resolve(__dirname, "dist"),},// Load loader from node_modules and loaders folder to facilitate debugging
  resolveLoader: {
    modules: ["node_modules", path.resolve(__dirname, "loaders")]},module: {
    rules: [{test: /\.js$/,
        use: [
          // All js files will load the loader, and there is a text configuration item
          {
            loader: "bundle-author-loader".options: { text: "/*** author hsky ***/"},},],},],},};Copy the code

Root directory to create a loaders folder

// bundle-author-loader.js

// Verify the options passed by the loader
const { validate } = require("schema-utils");

// Verification rule of loader options
// Options is an object with a text property of type string
const schema = {
  type: "object".properties: {
    text: {
      type: "string",}}};module.exports = function (source) {
  // Get the options passed by the user to the current loader
  // WebPack V5 has this method built in, and previously required the loader-utils package
  const options = this.getOptions();
  // Verify the options passed by the loader
  validate(schema, options, "bundle-author-loader");
  // Insert the information we passed into the source
  return `${options.text} ${source}`;
};

Copy the code

Then we can happily test it by creating a new SRC folder

// index.js
const a = 134
Copy the code

Add “build”: “webpack” to script in package.json and run NPM run build

bundle-author-loader
|-- dist
|	|-- bundle.js
|-- loaders
|	|-- bundle-author-loader.js
|-- node_modules
|-- src
|	|-- index.js
|-- package-lock.json
|-- package.json
|-- webpackage.config.js
Copy the code

The bundle.js folder in dist is the code that we packaged. Take a look

/* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to  create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */
/ * * * * * * / (() = > { // webpackBootstrap
/ *! * * * * * * * * * * * * * * * * * * * * * *! * \! *** ./src/index.js ***! \ * * * * * * * * * * * * * * * * * * * * * * /
eval("/*** author hsky ***/ const a = 1234; \n\n\n//# sourceURL=webpack://bundle-author-loader/./src/index.js?");
/ * * * * * * / })()
;
Copy the code

We can see that the options we configured in the loader have been packaged

Published to the NPM

// Enter your password. If you do not have one, go to the NPM official website to register NPM loginCopy the code

We need to clean up our code before publishing, leaving only bundle-author-loader.js and package.json, because loader’s default rules, So we rename bundle-author-loader.js to index.js and complete the package.json file.

bundle-author-loader
|-- index.js
|-- package.json
Copy the code

In a production environment, it is best to change devDependencies to peerDependencies to avoid conflicts with the main project version

Get ready for the launch

// Enter the user name and password. If no, go to NPM publishCopy the code

If 403 occurs, possible causes:

  • There is no authentication for the mailbox registered just now
  • Taobao mirror address was used

If 404 occurs, NPM adduser –scope may be required

Then we can see our package in NPM

How to debug

Let’s create a new project and install the package we just released

npm install bundle-author-loader --save-dev
Copy the code

Configure webpack.config.js as before, and since we no longer need local debugging, we no longer need the resolveLoader

const path = require("path");

module.exports = {
  mode: "development".entry: "./src/index.js".output: {
    filename: "bundle.js".path: path.resolve(__dirname, "dist"),},module: {
    rules: [{test: /\.js$/,
        use: [
          {
            loader: "bundle-author-loader".options: { text: "/*** author hsky ***/"},},],},],},};Copy the code

Run the NPM run build, and you can see that our configuration information is successfully exported to the bundle

/* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to  create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */
/ * * * * * * / (() = > { // webpackBootstrap
/ *! * * * * * * * * * * * * * * * * * * * * * *! * \! *** ./src/index.js ***! \ * * * * * * * * * * * * * * * * * * * * * * /
eval("/*** author hsky ***/ const ab = 123456; \n\n\n//# sourceURL=webpack://webpack-loader/./src/index.js?");
/ * * * * * * / })()
;
Copy the code

If we need to update and maintain the loader later, local debugging will be required. Here we provide a local debugging method NPM link which we perform in the bundle-author-loader (the project we publish to NPM)

npm link
Copy the code

Note: If you use peerDependencies, you need to manually install the dependent package

We notice that NPM link generates a global soft link for our local package, and then goes to another project (bundles using bundle-author-loader) to execute

npm link bundle-author-loader
Copy the code

At this point, we can see thatnode_modulesWe don’t have it installed belowbundle-author-loaderHowever, this package appears, which means that we have successfully established a link between the two projects and can now debug the project happily (using the method andnpm installIs the same as. Like when we were inbundle-author-loaderYou want to add the time when you pack

// index.js

const { validate } = require("schema-utils");

const schema = {
  type: "object".properties: {
    text: {
      type: "string",}}};module.exports = function (source) {
  const options = this.getOptions();
  validate(schema, options, "bundle-author-loader");
  return `${options.text} /**** bundled at The ${new Date()}* * * * /${source}`;
};

Copy the code

In the test project, the NPM run build is executed directly, and the packaged file is already what we want to debug

/* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to  create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */
/ * * * * * * / (() = > { // webpackBootstrap
/ *! * * * * * * * * * * * * * * * * * * * * * *! * \! *** ./src/index.js ***! \ * * * * * * * * * * * * * * * * * * * * * * /
eval("/*** author hsky ***/ /**** bundled at Mon Jan 25 2021 20:22:05 GMT+0800 (China Standard Time) ****/ const ab = 123456; \n\n\n//# sourceURL=webpack://webpack-loader/./src/index.js?");
/ * * * * * * / })()
;
Copy the code

Unlink: NPM unlink XXX in project, module or loader

Done!!