手写,发布并调试webpack-loader

webpackloaderplugin为咱们提供了强大的功能,下面咱们就简单的实现一下webpack-loader,顺便发布到npm,以及使用npm link本地调试咱们的模块。javascript

实现loader

这个loader的主要做用就是在打包出来的bundle文件里插入一段自定义信息,上代码java

// 新建一个项目
mkdir bundle-author-loader

npm init -y

npm install webpack webpack-cli --save-dev
复制代码

根目录新建webpack配置文件node

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

module.exports = {
  mode: "development",
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  // 从node_modules以及loaders文件夹下加载loader,方便咱们调试
  resolveLoader: {
    modules: ["node_modules", path.resolve(__dirname, "loaders")],
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          // 全部的js文件都将加载这个loader,而且有个text的配置项
          {
            loader: "bundle-author-loader",
            options: { text: "/*** author hsky ***/" },
          },
        ],
      },
    ],
  },
};

复制代码

根目录新建loaders文件夹webpack

// bundle-author-loader.js

// 校验loader传入的options
const { validate } = require("schema-utils");

// loader options的校验规则
// options是一个object类型,有一个text属性,这属性是string类型
const schema = {
  type: "object",
  properties: {
    text: {
      type: "string",
    },
  },
};

module.exports = function (source) {
  // 获取到用户给当前 loader 传入的 options
  // webpack v5 内置了这个方法,以前须要loader-utils这个包
  const options = this.getOptions();
  // 对loader传入的options作校验
  validate(schema, options, "bundle-author-loader");
  // 将咱们传入的信息插入到source中
  return `${options.text} ${source}`;
};

复制代码

而后咱们就能够愉快的测试了,新建一个src文件夹web

// index.js
const a = 134
复制代码

package.json中的script添加"build": "webpack",跑一下npm run build,此时的项目结构为npm

bundle-author-loader
|-- dist
|	|-- bundle.js
|-- loaders
|	|-- bundle-author-loader.js
|-- node_modules
|-- src
|	|-- index.js
|-- package-lock.json
|-- package.json
|-- webpackage.config.js
复制代码

dist文件夹下的bundle.js就是咱们打包出来的代码啦,瞅一眼json

/* * 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?");
/******/ })()
;
复制代码

咱们能够看到咱们在loader中配置的options已经被打包进去了markdown

发布到npm

// 输入帐号密码,没有的自行去npm官网注册
npm login 
复制代码

发布前须要整理一下咱们的代码,只保留bundle-author-loader.jspackage.json,由于loader的默认规则,因此咱们把bundle-author-loader.js重命名为index.js并补全一下package.json文件的信息,此时的文件目录结构为:测试

bundle-author-loader
|-- index.js
|-- package.json
复制代码

在生产环境中,devDependencies最好改为peerDependencies,避免与主项目的版本冲突ui

搞好准备工做,咱们开始发布

// 输入帐号密码,没有的自行去npm官网注册
npm publish
复制代码

若是出现403,可能的缘由:

  • 没有在刚才注册的邮箱验证
  • 使用了淘宝镜像地址

若是出现404,可能须要npm adduser --scope

而后咱们就能在npm里看到咱们的包了

如何调试

咱们新建一个项目,安装一下咱们刚发布的包

npm install bundle-author-loader --save-dev
复制代码

和刚才同样配置一下webpack.config.js,由于咱们再也不须要本地调试,因此也再也不须要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 ***/" },
          },
        ],
      },
    ],
  },
};

复制代码

跑一下npm run build,能够看到,咱们的配置信息成功的打到了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?");
/******/ })()
;
复制代码

若是咱们后续对这个loader进行更新维护的话,就须要本地调试,这里提供一种本地调试的方法npm link 咱们在bundle-author-loader(即咱们发布到npm的项目)中,执行

npm link
复制代码

注:若是用的是peerDependencies,则须要手动安装一下依赖的包

咱们注意到,npm link会把咱们本地的包生成一个全局的软连接,而后进入到另外一个项目(即便用bundle-author-loader的包),执行

npm link bundle-author-loader
复制代码

此时,咱们能够发现node_modules下面咱们没有安装bundle-author-loader,可是这个包却出现了,这说明咱们已经成功创建两个项目的连接,接下来就能够愉快的调试项目了(使用方式和npm install的同样)。 好比咱们在bundle-author-loader中想添加打包时的时间

// 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 ${new Date()} ****/ ${source}`;
};

复制代码

在测试项目中,直接执行npm run build,此时,打包后文件已是咱们想要调试的内容了

/* * 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?");
/******/ })()
;
复制代码

解除link状态,在项目和模块或者loader中 npm unlink xxx

大功告成!!!

相关文章
相关标签/搜索