在webpack中pitch对打包的影响和inline-loader的使用

webpack版本为5.74.0

module: {
  rules: [
    {
      test: /\.css$/i,
      use: [path.resolve(__dirname, './loader1.js'), path.resolve(__dirname, './loader2.js')],
    }
  ],
},

loader1.js

module.exports = function () {
  console.log('========loader1=========');
  return ''
}

module.exports.pitch = function loader() {
  console.log('========pitch1=========');
  return `
  import a from "!!../loader2.js!./index.css"
  export default a
  `
}

loader2.js

module.exports = function (content) {
  console.log('========loader2=========', content);
  return `import {a} from "../test.loader.files.js"
          export default a
  `
}

test.loader.files.js

export const a = () => {
  console.log(12345);
}
export const b = () => {
  console.log(12345);
}

index.css

div{
  background-color: red;
}

控制台显示如下:

========pitch1=========
========loader2========= div{
  background-color: red;
}

pitch的执行顺序

在有pitch方法的前提下会先从上至下执行pitch方法,再从下至上执行loader函数,如果pitch方法有返回值那么只会从当前pitch方法对应的loader的前一个loader开始执行。

但是我们从控制台可以看到首先执行的就是loader1的pitch方法,再执行loader2函数。这里有人就有疑问了,不是说pitch方法有返回值只会从当前pitch方法对应的loader的前一个loader开始执行吗,那就是执行loader1前面的loader开始执行。loader1前面是没有loader的,所以loader1不会执行,更不会执行loader2。但是loader2为什么执行了呢?主要是因为pitch1返回的值的原因,注意看!!../loader2.js!./index.css,!!表示不执行pre、post、normal等等loader,而且再次导入了index.css文件。由于是inline-loader,会从右至左执行loader,此时有个loader2.js,会执行该loader,这个loader前面有!!,所以只会执行loader2。我们再来看看打包文件:

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

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

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _loader2_js_index_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !!../loader2.js!./index.css */ \"./loader2.js!./src/index.css\");\n\n  \n  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_loader2_js_index_css__WEBPACK_IMPORTED_MODULE_0__[\"default\"]);\n  \n\n//# sourceURL=webpack://test-webpack/./src/index.css?");

/***/ }),

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

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _test_loader_files_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../test.loader.files.js */ \"./test.loader.files.js\");\n\n          \n          /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_test_loader_files_js__WEBPACK_IMPORTED_MODULE_0__.a);\n  \n\n//# sourceURL=webpack://test-webpack/./src/index.css?./loader2.js");

/***/ }),

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

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"c\": () => (/* binding */ c),\n/* harmony export */   \"d\": () => (/* binding */ d)\n/* harmony export */ });\nconst c = function () {\r\n  const node = document.createElement('div')\r\n  node.innerText = 888891\r\n  node.style.color = 'red'\r\n  document.body.appendChild(node)\r\n}\r\n\r\nconst d = function () {\r\n  console.log(1141111);\r\n}\r\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://test-webpack/./src/b.js?");

/***/ }),

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

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./b */ \"./src/b.js\");\n/* harmony import */ var _index_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./index.css */ \"./src/index.css\");\n\r\n\r\nconst add = document.createElement('button')\r\nadd.innerText = '新增'\r\n\r\nconst div = document.createElement('div')\r\ndiv.innerText = Math.random()\r\nadd.addEventListener('click', function () {\r\n  const div = document.createElement('div')\r\n  div.innerText = Math.random()\r\n  document.body.append(div)\r\n})\r\ndocument.body.appendChild(add)\r\nconsole.log(_index_css__WEBPACK_IMPORTED_MODULE_1__[\"default\"]);\r\nif (false) {}\r\n\n\n//# sourceURL=webpack://test-webpack/./src/index.js?");

/***/ }),

/***/ "./test.loader.files.js":
/*!******************************!*\
  !*** ./test.loader.files.js ***!
  \******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"a\": () => (/* binding */ a),\n/* harmony export */   \"b\": () => (/* binding */ b)\n/* harmony export */ });\nconst a = () => {\r\n  console.log(12345);\r\n}\r\nconst b = () => {\r\n  console.log(12345);\r\n}\n\n//# sourceURL=webpack://test-webpack/./test.loader.files.js?");

/***/ })

/******/ 	});

可以发现index.css的模块内容就是pitch方法的返回值。引用的模块./loader2.js!./src/index.css和./test.loader.files.js也都被打包进去了。类似的案例就有style-loader和css-loader,style-loader只有pitch方法返回值如下:

import API from "!../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js";
import domAPI from "!../node_modules/style-loader/dist/runtime/styleDomAPI.js";
import insertFn from "!../node_modules/style-loader/dist/runtime/insertBySelector.js";
import setAttributes from "!../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js";
import insertStyleElement from "!../node_modules/style-loader/dist/runtime/insertStyleElement.js";
import styleTagTransformFn from "!../node_modules/style-loader/dist/runtime/styleTagTransform.js";
import content, * as namedExport from "!!../node_modules/css-loader/dist/cjs.js!./index.css";
var options = {};
options.styleTagTransform = styleTagTransformFn;
options.setAttributes = setAttributes;
options.insert = insertFn.bind(null, "head");
options.domAPI = domAPI;
options.insertStyleElement = insertStyleElement;
var update = API(content, options);
export * from "!!../node_modules/css-loader/dist/cjs.js!./index.css";
export default content && content.locals ? content.locals : undefined;

和我们讲的类似重新引入了./index.css,并使用css-loader处理,使用!!防止再次进入style-loader。并且导出了css-loader的返回值content:

{
    "default": [
        [
            "./node_modules/css-loader/dist/cjs.js!./src/index.css",
            "div{\r\n  background-color: red;\r\n}",
            ""
        ]
    ]
}

然后执行style-loader的var update = API(content, options)方法将css样式放到header中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Young soul2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值