webpack+vite前端構建工具 -6從loader本質看各種語言處理 7webpack處理html

6 從loader本質看各種語言處理

語法糖?

6.1 loader的本質

  • loader本質是一個方法,接收要處理的資源的內容,處理完畢后給出內容,作為打包結果。

    所有的loader(例如babel-loader, url-loader等)export出一個方法。注冊loader去處理某種類型文件。

6.1.1 手搓一個loader

1 定義loader
// mycss-loader\index.js
module.exports = function (cssContent) {console.log("🚀 ~ cssContent:", cssContent);// 將0變為0pxcssContent = cssContent.replace("0", "0px");return cssContent;
}
2 注冊loader
// webpack.config.js
module.exports = {mode: "production", //webpack4以后要指定mode// loadermodule: {rules: [{test: /\.css/,use: [minicss.loader, "css-loader", "./mycss-loader"]},]}
}

最先調用mycss-loader.
注意路徑,mycss-loader在當前目錄下。

3 打包

打包出來的css文件里的padding,變為0px。
在這里插入圖片描述

6.1.2 loader本質

  • 從手搓的mycss-loader可以推測babe-loader

    • 【babel-loader編譯】通過babel-loader編譯js,即babel-loader函數接收js文件內容,對es6字符串編譯為es5字符串等等。
  • 同理,編譯ts, jsx都是這樣,目標都是轉換為js.

  • 基本上各種語言處理可以看做

    1. 為改語言編寫loader
    2. 編寫loader配置

6.2 ts編譯打包

6.2.1 安裝ts的編譯loader和編譯庫

命令:npm install typescript ts-loader --save-dev

6.2.2 定義編譯規則

ts規則較多,可以集成到單獨的文件tsconfig.json里。

// webpack.config.js
module.exports = {mode: "development", //webpack4以后要指定mode// loadermodule: {rules: [{test: /\.tsx?$/,//匹配ts,tsx文件use: {loader: 'ts-loader'}}]}
}
// tsconfig.json
// 暫時為空

定義ts文件

// ts1.ts
let a: number = 123;
console.log("🚀 ~ a:", a);

在app.js里引入ts1.ts

// app.js
import b from './a.js'
import "./test.css"
import img1 from "./img/兩狗對視.jpg"
import './ts1.ts';
new Image().src = img1;
(() => {let a = 23;console.log(b);console.log(a);
})()

6.2.3 打包

ts語言在打包文件里編譯為js語言
在這里插入圖片描述

6.3 規律總結

項目里所有的loader都是如此。面對新的loader,要學會如何使用,只需要查一下相關配置即可。
記義不記形。

7 webpack處理html

前面介紹了webpack處理js、css等,還剩下html。
一個項目在瀏覽器展示,先拿到html文件。

  • 項目的3要素
    • html
    • js
    • css
瀏覽器htmljs執行js,創建內容
css執行css渲染樣式

解讀:先拿到項目的html,然后html加載js和css。加載js后執行js,創建內容。加載css后執行css,渲染頁面樣式。
html是起點。

  • 需要html做什么
    • 提供html模版,復用固定內容
    • 打包時生成一個html
    • 打包的html自動引入打包后的js, css

7.1 示例

7.1.0 html文件

<!-- index.html -->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>webpackhtml</title>
</head><body><div id="app"></div>
</body></html>

快捷鍵: !

7.1.1 安裝plugin

  • 使用插件處理html而非loader
  • 為什么不用loader
    • loader本質:webpack只能識別js,讓webpack識別引入的其他文件需要用loader
    • 但html不需要webpack識別,而是作為載體去承載打包后的js文件
    • 因此webpack不需要識別html,只是用html承接weboack處理的結果(幾乎不可能需要在js文件里import html文件)
    • 因此不使用loader處理html
  • 需要做什么
    • 拿到html模板,將打包后的內容加入到html文件中

    因此不是處理html,而是使用html去處理打包結果

安裝命令:npm install html-webpack-plugin --save-dev

7.1.2 引入plugin

// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');

7.1.3 注冊plugin

// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {plugins: [new htmlwebpack({template: './index.html',// 寫法1,指定html模板// templateContent: function () {  // 寫法2,自定義模板,使用頻率較低//     return '<div>123</div>'// }filename: "index.html"})]
}

7.1.4 打包

打包結果
在這里插入圖片描述
打包后的html
可以看到引入了打包后的js和css文件

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>webpackhtml</title>
<script defer src="app1.34fb.bundle.js"></script><link href="test.bundle.css" rel="stylesheet"></head><body><div id="app"></div>
</body></html>

如果mode為production,打包后的index.html會壓縮為一行代碼

7.2 多入口情況

  • 傳統vue項目是單入口(單頁面項目)。
    • vue項目中頁面的切換,本質還是同一個頁面,只是執行不同的js創建不同的內容
  • 多入口,即多個頁面,用于多個html的情況。切換頁面時是切到另外一個html文件。
    • 多入口,表示多個js文件。

下面給出多入口處理的示例

7.2.0 多入口html文件

在原來基礎上加入一個app2.js.

// app2.js
console.log("app2.js")

7.2.1 多入口文件打包配置

webpack.config.js的entry添加app2.js.

// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {// entry: "./app.js",//單入口寫法,入口指定為app.jsentry: {  // 多入口寫法:入口名稱+入口文件app1: ["./app.js"],app2: './app2.js'},// entry: ["./app.js", './app2.js'] // 兩個文件同時作為一個入口output: {path: __dirname + '/dist', // 絕對路徑,__dirname是node的全局變量,表示當前目錄的絕對路徑filename: "[name].[hash:4].bundle.js", //將name加到filename里,打包結果文件是app.bundle.js和app2.bundle.js,hash是對文件是否有改變的標志,:4表示截取前4位},mode: "production", //webpack4以后要指定mode// loadermodule: {rules: []},plugins: [new htmlwebpack({template: './index.html',// 寫法1,指定html模板// templateContent: function () {  // 寫法2,自定義模板,使用頻率較低//     return '<div>123</div>'// }filename: "index.html"})]
}

7.2.2 打包

1 打包結果

打包結果包含兩個js文件。
在這里插入圖片描述
兩個js文件在html如何加載呢
——都加到index.html里。

在這里插入圖片描述

2 問題
  • 多入口意味著多個html,每個入口js應該有自己的html。
  • 正確邏輯:每個打包的js文件都應該有專屬的html,html只引入一個js文件,而不是一個html文件引入2個js文件。
  • 正確做法:再new一個html-webpack-plugin插件

app2.js的html模板可以是之前的index.html,也可以指定新的,例如index2.html.

3 正確配置并打包

index2.html就不贅述了,與index.html一樣的。

  • webpack.config.js的plugin再加一個plugin,用于給app2.js指定html模板,即index2.html.
  • 注意還加了chunks屬性,注意chunks的值要與entry的key對應。
// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {// entry: "./app.js",//單入口寫法,入口指定為app.jsentry: {  // 多入口寫法:入口名稱+入口文件app1: ["./app.js"],app2: './app2.js'},// entry: ["./app.js", './app2.js'] // 兩個文件同時作為一個入口output: {path: __dirname + '/dist', // 絕對路徑,__dirname是node的全局變量,表示當前目錄的絕對路徑filename: "[name].[hash:4].bundle.js", //將name加到filename里,打包結果文件是app.bundle.js和app2.bundle.js,hash是對文件是否有改變的標志,:4表示截取前4位},mode: "production", //webpack4以后要指定mode// loadermodule: {rules: []},plugins: [new htmlwebpack({template: './index.html',// 寫法1,指定html模板// templateContent: function () {  // 寫法2,自定義模板,使用頻率較低//     return '<div>123</div>'// }filename: "index.html",chunks: ["app1"]}),new htmlwebpack({template: './index2.html',filename: "index2.html",chunks: ["app2"]})]
}

打包完成,可以看到有2個html,每個html各引入對應的js.
在這里插入圖片描述

7.3 其他配置項

7.3.1 代碼不處理壓縮

打出來的代碼是壓縮后的,不便于閱讀,可以稍加配置(minify屬性)。
在這里插入圖片描述

// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {// entry: "./app.js",//單入口寫法,入口指定為app.jsentry: {  // 多入口寫法:入口名稱+入口文件app1: ["./app.js"],app2: './app2.js'},// entry: ["./app.js", './app2.js'] // 兩個文件同時作為一個入口output: {path: __dirname + '/dist', // 絕對路徑,__dirname是node的全局變量,表示當前目錄的絕對路徑filename: "[name].[hash:4].bundle.js", //將name加到filename里,打包結果文件是app.bundle.js和app2.bundle.js,hash是對文件是否有改變的標志,:4表示截取前4位},mode: "production", //webpack4以后要指定mode// loadermodule: {rules: []},plugins: [new htmlwebpack({template: './index.html',// 寫法1,指定html模板// templateContent: function () {  // 寫法2,自定義模板,使用頻率較低//     return '<div>123</div>'// }filename: "index.html",chunks: ["app1"],            minify: {collapseInlineTagWhitespace: false, // 是否一行展示removeComments: false, //是否移除注釋removeAttributeQuotes: false, //是否移除屬性之間的多余空格}}),new htmlwebpack({template: './index2.html',filename: "index2.html",chunks: ["app2"]})]
}

配置后打包出來的index.html

// dist\index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>webpackhtml</title>
<script defer="defer" src="app1.506b.bundle.js"></script><link href="test.bundle.css" rel="stylesheet"></head><body><div id="app"></div>
</body></html>

7.3.2 js加載位置

  • 可以看到目前script標簽是加載在head標簽里的。是否可以指定js文件的加載位置(默認加載到head標簽)?
    • 加入inject屬性,值為body.
// webpack.config.js
const htmlwebpack = require('html-webpack-plugin');
module.exports = {// entry: "./app.js",//單入口寫法,入口指定為app.jsentry: {  // 多入口寫法:入口名稱+入口文件app1: ["./app.js"],app2: './app2.js'},// entry: ["./app.js", './app2.js'] // 兩個文件同時作為一個入口output: {path: __dirname + '/dist', // 絕對路徑,__dirname是node的全局變量,表示當前目錄的絕對路徑filename: "[name].[hash:4].bundle.js", //將name加到filename里,打包結果文件是app.bundle.js和app2.bundle.js,hash是對文件是否有改變的標志,:4表示截取前4位},mode: "production", //webpack4以后要指定mode// loadermodule: {rules: []},plugins: [new htmlwebpack({template: './index.html',// 寫法1,指定html模板// templateContent: function () {  // 寫法2,自定義模板,使用頻率較低//     return '<div>123</div>'// }filename: "index.html",chunks: ["app1"],            minify: {collapseInlineTagWhitespace: false, // 是否一行展示removeComments: false, //是否移除注釋removeAttributeQuotes: false, //是否移除屬性之間的多余空格},inject: "body" // 指定js加載位置: body|true(加載到body中), head, false(不加載)}),new htmlwebpack({template: './index2.html',filename: "index2.html",chunks: ["app2"]})]
}

在這里插入圖片描述

7.3.3 其他配置

html的標題title標簽支持可配置,也可在webpack.config.js設置。

vue項目可以實現處理,這部分就不看了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84907.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84907.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84907.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

算法第41天|188.買賣股票的最佳時機IV、309.最佳買賣股票時機含冷凍期、714.買賣股票的最佳時機含手續費

188.買賣股票的最佳時機IV 題目 思路與解法 基于 買賣股票的最佳時機iii&#xff0c;得出的解法。關鍵在于&#xff0c;每一天的賣或者買都由前一天推導而來。 class Solution { public:int maxProfit(int k, vector<int>& prices) {if(prices.size() 0) return …

【AI News | 20250623】每日AI進展

AI Repos 1、tools Strands Agents Tools提供了一個強大的模型驅動方法&#xff0c;通過少量代碼即可構建AI Agent。它提供了一系列即用型工具&#xff0c;彌合了大型語言模型與實際應用之間的鴻溝&#xff0c;涵蓋文件操作、Shell集成、內存管理&#xff08;支持Mem0和Amazon…

Python裝飾器decorators和pytest夾具fixture詳解和使用

此前一直認為fixture就叫python中的裝飾器&#xff0c;學習后才發現decorators才是裝飾器&#xff0c;fixture是pytest框架的夾具&#xff0c;只是通過裝飾器去定義和使用。所以要了解fixture就得先了解python裝飾器。 一、裝飾器(decorators) 1.定義 裝飾器&#xff08;dec…

目標檢測之YOLOv5到YOLOv11——從架構設計和損失函數的變化分析

YOLO&#xff08;You Only Look Once&#xff09;系列作為實時目標檢測領域的標桿性框架&#xff0c;自2016年YOLOv1問世以來&#xff0c;已歷經十余年迭代。本文將聚焦YOLOv5&#xff08;2020年發布&#xff09;到YOLOv11&#xff08;2024年前后&#xff09;的核心技術演進&am…

leetcode:面試題 08.06. 漢諾塔問題

題目鏈接 面試題 08.06. 漢諾塔問題 題目描述 題目解析 當只有一個盤子時&#xff1a;直接從A柱放到C柱即可。當有兩個盤子時&#xff1a;將A柱第一個盤子先放到B柱&#xff0c;再將A柱第二個盤子放到C柱&#xff0c;最后將B柱上的盤子放到C柱子。當有3個盤子時&#xff1a;先…

mybatis-plus一對多關聯查詢

MyBatis-Plus 本身主要關注單表操作&#xff0c;但可以通過幾種方式實現一對多關聯查詢&#xff1a; 1. 使用 XML 映射文件實現 這是最傳統的方式&#xff0c;通過編寫 SQL 和 ResultMap 實現&#xff1a; <!-- UserMapper.xml --> <resultMap id"userWithOrd…

一些想法。。。

1.for里面的局部變量這種還是在for里面定義比較好 比如 for(int i 0;i<n;i){ int num; cin>>num; } 實不相瞞&#xff0c;有一次直接cin了i怎么都沒看出來哪里錯了。。。 2.關于long long 如果發現中間結果大約是10^9&#xff0c;就要考慮int 溢出 即用 long …

遷移科技拆垛工業相機:驅動智能拆碼垛革命,賦能工業自動化新紀元

——將復雜技術轉化為可感知價值&#xff0c;引領行業標桿級解決方案 作為工業自動化領域的品牌策略專家&#xff0c;我深知企業面臨的痛點&#xff1a;拆垛環節效率低下、人工成本高、安全隱患頻發。遷移科技憑借其領先的3D視覺技術&#xff0c;通過拆垛工業相機將抽象參數轉…

Linux筆記---線程控制

1. 線程創建&#xff1a;pthread_create() pthread_create() 是 POSIX 線程庫&#xff08;pthread&#xff09;中用于創建新線程的函數。調用該函數后系統就會啟動一個與主線程并發的線程&#xff0c;并使其跳轉到入口函數處執行。 #include <pthread.h>int pthread_cr…

Ragflow 源碼:ragflow_server.py

目錄 介紹1. 初始化和配置2. 數據庫管理3. 核心功能4. HTTP 服務5. 信號處理6. 調試支持 流程圖系統架構 代碼解釋1. **初始化系統**2. **運行時控制**3. **核心服務** 介紹 ragflow_server.py 是 RAGFlow 項目的主服務器程序&#xff0c;負責啟動和管理 RAGFlow 的核心服務。…

springboot企業級項目開發之項目測試——單元測試!

項目測試 項目測試是對項目的需求和功能進行測試&#xff0c;由測試人員寫出完整的測試用例&#xff0c;再按照測試用例執行測試。項目測試是項目質量的保證&#xff0c;項目測試質量直接決定了當前項目的交付質量。 測試人員在開展測試之前&#xff0c;首先需要進行測試的需…

Linux kdump遠程轉存儲配置手冊教程

一、前言 kdump是一個Linux內核崩潰轉儲機制,當系統崩潰時,它可以捕獲內核的內存轉儲信息,幫助分析崩潰原因。將轉儲文件存儲到遠程位置,便于集中管理和分析。本教程將詳細介紹如何配置kdump將轉儲文件遠程轉存儲。 二、安裝kdump 在大多數Linux發行版中,kdump相關的工…

c++bind和forward完美轉化

前言 1. std::bind概述 std::bind是C11引入的功能模板&#xff0c;位于<functional>頭文件中&#xff0c;用于將函數、成員函數或函數對象與特定參數綁定&#xff0c;生成一個新的可調用對象。 1.1 基本用法 #include <iostream> #include <functional>v…

【Dify精講】第14章:部署架構與DevOps實踐【知識卡片】

第14章&#xff1a;部署架構與DevOps實踐http://www.airinto.com/share/49997bb7 一、Docker 容器化方案&#xff1a;從開發到生產的統一 二、Kubernetes 部署&#xff1a;走向云原生 三、CI/CD 流程設計&#xff1a;自動化的藝術 四、高可用架構&#xff1a;讓 AI 服務永不停歇…

el-cascader 設置可以手動輸入也可以下拉選擇

el-cascader 設置可以手動輸入也可以下拉選擇 稍微修改一下就可食用 <template slot"stationId" slot-scope""><div style"position: relative;"><!-- 可輸入也可顯示選項 --><el-input:value"stationNameInput"…

Unity Shader開發-著色器變體(1)-著色器變體概述

有時我們希望一份 Shader 源代碼可能滿足多種功能&#xff08;如處理法線貼圖、自發光、不同光照模式、陰影&#xff0c;支持GPUInstacing等多種功能&#xff09;。所以我們需要能夠實現Shader分支的方法。 一.Shader分支實現 主要有三種手段實現Shader分支&#xff1a; 1.靜…

ECK 簡化:在 GCP GKE Autopilot 上部署 Elasticsearch

作者&#xff1a;來自 Elastic Eduard Martin 學習如何使用 GKE Autopilot 和 ECK 在 GCP 上部署 Elasticsearch 集群。 想要獲得 Elastic 認證&#xff1f;了解下一次 Elasticsearch Engineer 培訓的時間&#xff01; Elasticsearch 擁有豐富的新功能&#xff0c;可以幫助你為…

測試一個軟件的性能有哪些指標?

在測試軟件性能時,通常會關注多個維度的指標,以評估系統在不同負載下的表現。以下是關鍵的性能測試指標分類和詳細說明: ?? 核心性能指標分類 1. 響應時間(Response Time) 定義:從發送請求到接收到響應所花費的時間 細分: 平均響應時間:所有請求的平均耗時 *P90/P95…

淺析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong

目錄 std::atomic ::compare_exchange_weak 和 std::atomic ::compare_exchange_strong 核心原理 函數簽名 核心區別 典型用法 1. compare_exchange_weak&#xff08;循環內重試&#xff09; 2. compare_exchange_strong&#xff08;單次嘗試&#xff09; 底層機制 總…

舉出一個異步接口測試的例子

以下是一個完整的 ?異步接口測試? 實際案例&#xff0c;包含問題場景、解決方案、代碼實現和面試回答技巧&#xff0c;適合在面試中展示技術深度&#xff1a; ?案例背景? ?業務場景?&#xff1a; 測試一個AI圖片生成平臺的異步接口&#xff0c;用戶提交生成請求后&#…