webpack
的loader
和plugin
为咱们提供了强大的功能,下面咱们就简单的实现一下webpack-loader
,顺便发布到npm
,以及使用npm link
本地调试咱们的模块。javascript
这个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 login
复制代码
发布前须要整理一下咱们的代码,只保留bundle-author-loader.js
和package.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
大功告成!!!