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
大功告成!!!