欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

從0-1搭建webpack的前端工程化項目教程

 更新時間:2025年08月26日 09:04:06   作者:xrkhy  
文章系統(tǒng)講解了前端工程化概念及Webpack的核心作用,涵蓋模塊化、組件化、自動化開發(fā)流程,重點介紹Webpack配置、插件(如devServer、htmlWebpackPlugin)使用、Loader處理CSS/JS等文件、SourceMap調試機制,以及@路徑別名優(yōu)化項目結構的實踐方法

1.1 前端工程化的相關概念

1 小白眼中的前端開發(fā) vs 實際的前端開發(fā)

小白眼中的前端開發(fā):

  • 會寫HTML+CSS +javascript
  • 美化頁面就拽一個bootstrap過來
  • 需要操作DOM或發(fā)起Ajax請求就拽一個jQuery過來
  • 需要快速實現一個頁面布局效果就拽一個Layui過來

實際的前端開發(fā):

  • 模塊化 (js的模塊化,css的模塊化,資源的模塊化)
  • 組件化 (復用現有的UI結構,樣式,行為)
  • 規(guī)范化 (目錄結構的劃分,編程規(guī)范化,接口規(guī)范化,文檔規(guī)范化,Git分支管理)
  • 自動化 (自動化構建,自動部署,自動化測試)

2 什么是前端工程化

前端工程化指的是:在企業(yè)級的前端項目開發(fā)中 把前端開發(fā)所需的工具,技術,流程,經驗等進行規(guī)范化,標準化。

企業(yè)中的Vue項目和React項目,都是基于工程化的方式進行開發(fā)的

好處:前端開發(fā)自成體系,有一套標準的開發(fā)方案和流程

3 前端工程化的解決方案

早期的前端工程化解決方案:

  • grunt( https://www.gruntjs.net/ )
  • gulp( https://www.gulpjs.com.cn/ )

目前主流的前端工程化解決方案:

  • webpack( https://www.webpackjs.com/ )主要用于做項目
  • parcel( https://zh.parceljs.org/ )更多是開發(fā)第三方包的時候會用

1.2 webpack 的基本使用

1.2.1 什么是 webpack

  • 概念:webpack 是前端項目工程化的具體解決方案。
  • 主要功能:它提供了友好的前端模塊化開發(fā)支持,以及代碼壓縮混淆、處理瀏覽器端 JavaScript 的兼容性,性能優(yōu)化等強大的功能。
  • 好處:讓程序員把工作的重心放到具體功能的實現上,提高了前端開發(fā)效率和項目的可維護性
  • 注意:目前 Vue,React 等前端項目,基本上都是基于 webpack 進行工程化開發(fā)的。

1.2.創(chuàng)建列表隔行變色項目

① 新建項目空白目錄,并運行 npm init –y 命令,初始化包管理配置文件 package.json。(文件夾必須是英文的)

  • package.json
...

② 新建 src 源代碼目錄。 (放程序員寫的代碼)

③ 新建 src -> index.html 首頁和 src -> index.js 腳本文件

④ 初始化首頁基本的結構

ul>li{這是第$個li}*9 //快速生成1-9個li
  • src -> index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./index.js"></script>
</head>


<body>
  <ul>
    <li>這是第 1 個 li</li>
    <li>這是第 2 個 li</li>
    <li>這是第 3 個 li</li>
    <li>這是第 4 個 li</li>
    <li>這是第 5 個 li</li>
    <li>這是第 6 個 li</li>
    <li>這是第 7 個 li</li>
    <li>這是第 8 個 li</li>
    <li>這是第 9 個 li</li>
  </ul>

</body>

</html>

⑤ 運行 npm install jquery –s 命令,安裝 jQuery (不用搜索下載了,–s是加到dependencies()) -s是–save的縮寫

  • package-lock.json(增加)
.....
  • node_modules(增加文件夾)

⑥ 通過 ES6 模塊化的方式導入 jQuery,實現列表隔行變色效果

  • src -> index.js
// 1. 使用 ES6 導入語法,導入 jQuery
import $ from 'jquery'

// 2. 定義 jQuery 的入口函數
$(function () {
  // 3. 實現奇偶行變色
  // 奇數行為紅色
  $('li:odd').css('background-color', 'red')
  $('li:even').css('background-color', 'pink')
  // 0 是偶數
  // 1 是奇數
})

結果你會發(fā)現報錯因為語法高級無法識別接下來就需要用webpack

1.2.3. 在項目中安裝 webpack

在終端運行如下的命令,安裝 webpack 相關的兩個包:

  • npm install webpack@5.42.1 webpack-cli@4.7.2 -D (–S是加到devDependencies(只在開發(fā)階段用)這個節(jié)點中)
  • -D是–save-dev的縮寫 在npmjs.com 官方文檔中可以查看放在那里

注意:安裝完webpack在node_modules文件夾會多很多文件夾

1.2.4 在項目中配置 webpack

① 在項目根目錄中,創(chuàng)建名為 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:

  • webpack.config.js
module.exports = {
  // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
  // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
  // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
  mode: 'development'
  }

② 在 package.json 的 scripts 節(jié)點下,新增 dev 腳本如下:

  • 注意package.json中原先就有
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }//把"test": "echo \"Error: no test specified\" && exit 1"刪掉換成下面的
  //"test": "echo \"Error: no test specified\" && exit 1"是沒用的代碼
  • package.json
  "scripts": {
    "dev": "webpack"
  },

③ 在終端中運行 npm run dev 命令,啟動 webpack 進行項目的打包構建(一會介紹打包介紹)

終端(又又又報錯了):

PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev

> change-rows-color@1.0.0 dev
> webpack

node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)
    at BulkUpdateDecorator.hashFactory (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\util\createHash.js:145:18)
    at BulkUpdateDecorator.update (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\util\createHash.js:46:50)
    at RawSource.updateHash (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack-sources\lib\RawSource.js:64:8)
    at NormalModule._initBuildHash (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\NormalModule.js:868:17)
    at handleParseResult (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\NormalModule.js:934:10)
    at D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\NormalModule.js:1026:4
    at processResult (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\NormalModule.js:743:11)
    at D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack\lib\NormalModule.js:807:5 {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v18.15.0
這個錯誤是node版本太高

我的建議是安裝nvm可以隨意切換node的版本
安裝方法自己查

如下:

PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev 
   
> change-rows-color@1.0.0 dev D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
> webpack

asset main.js 319 KiB [emitted] (name: main)
runtime modules 937 bytes 4 modules
cacheable modules 279 KiB
  ./src/index.js 315 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 278 KiB [built] [code generated]
//將上面的兩個index.jsjquery.js合并在了main.js
webpack 5.42.1 compiled successfully in 253 ms

運行完之后在文件中多了 dist文件夾 并且在dist文件夾下有main.js

main.js是webpage根據我們index.js生成的

也就是說index.js可以用main.js替換,因為main.js解決了兼容性問題

  • 第四步 修改 src -> index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <script src="./index.js"></script> -->
    <script src="../dist/main.js"></script>
</head>
<body>
    <ul>
        <li>這是第1個li</li>
        <li>這是第2個li</li>
        <li>這是第3個li</li>
        <li>這是第4個li</li>
        <li>這是第5個li</li>
        <li>這是第6個li</li>
        <li>這是第7個li</li>
        <li>這是第8個li</li>
        <li>這是第9個li</li>
    </ul>
</body>
</html>

1 mode 的可選值

mode 節(jié)點的可選值有兩個,分別是:

① development

  • 開發(fā)環(huán)境
  • 不會對打包生成的文件進行代碼壓縮和性能優(yōu)化
  • 打包速度快,適合在開發(fā)階段使用

② production

  • 生產環(huán)境
  • 會對打包生成的文件進行代碼壓縮和性能優(yōu)化
  • 打包速度很慢,僅適合在項目發(fā)布階段使用

production的使用

  • webpack.config.js 修改
module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'production'
}
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev 

> change-rows-color@1.0.0 dev D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
> webpack
//注意這里的體積變?yōu)?5.5 KiB
asset main.js 85.5 KiB [emitted] [minimized] (name: main) 1 related asset
runtime modules 663 bytes 3 modules
cacheable modules 279 KiB
  ./src/index.js 315 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 278 KiB [built] [code generated]  
webpack 5.42.1 compiled successfully in 1778 ms

2 webpack.config.js 文件的作用

webpack.config.js 是 webpack 的配置文件。webpack 在真正開始打包構建之前,會先讀取這個webpack.config.js 配置文件,

從而基于給定的配置,對項目進行打包。

注意:由于 webpack 是基于 node.js 開發(fā)出來的打包工具,因此在它的配置文件中,支持使用 node.js 相關的語法和模塊進行 webpack 的個性化配置。

3 webpack 中的默認約定

在 webpack 4.x 和 5.x 的版本中,有如下的默認約定:

① 默認的打包入口文件為 src -> index.js ,如果改變src文件夾的名字和index.js的名字,然后使用npm run dev 命令會報錯

② 默認的輸出文件路徑為 dist -> main.js

注意:可以在 webpack.config.js 中修改打包的默認約定

4 自定義打包的入口與出口

在 webpack.config.js 配置文件中,通過 entry 節(jié)點指定打包的入口。通過 output 節(jié)點指定打包的出口。

先將index.js改為index1.js

示例代碼如下:

  • webpack.config.js
//導入path模塊
const path = require('path');


module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        filename: 'bundle.js'
    }
}

將dist文件夾刪除

  • 終端運行 npm run dev
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev 

> change-rows-color@1.0.0 dev D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
> webpack

asset bundle.js 319 KiB [emitted] (name: main)
runtime modules 937 bytes 4 modules
cacheable modules 279 KiB
  ./src/index1.js 315 bytes [built] [code generated]
  ./node_modules/jquery/dist/jquery.js 278 KiB [built] [code generated]
webpack 5.42.1 compiled successfully in 279 ms
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> 
  • 并改變index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <script src="./index.js"></script> -->
    <!-- <script src="../dist/main.js"></script> -->
    <script src="../dist/bundle.js"></script>
</head>
<body>
    <ul>
        <li>這是第1個li</li>
        <li>這是第2個li</li>
        <li>這是第3個li</li>
        <li>這是第4個li</li>
        <li>這是第5個li</li>
        <li>這是第6個li</li>
        <li>這是第7個li</li>
        <li>這是第8個li</li>
        <li>這是第9個li</li>
    </ul>
</body>
</html>

思考一個問題,此時當我們改變index1.js中的代碼,使奇數行變成金色 ,會不會影響頁面中的顏色

答案:不會,因為我們在index.js中導入的是webpage工程化之后的代碼;

想要看到奇數行變成金色 ,必須重新運行npm run dev

但是每次運行npm run dev 太麻煩了 下面來解決這個問題

1.3 webpack 中的插件

1.3.1 webpack 插件的作用

通過安裝和配置第三方的插件,可以拓展 webpack 的能力,從而讓 webpack 用起來更方便。最常用的

webpack 插件有如下兩個:

webpack-dev-server

  • 類似于 node.js 階段用到的 nodemon 工具
  • 每當修改了源代碼,webpack 會自動進行項目的打包和構建

html-webpack-plugin

  • webpack 中的 HTML 插件(類似于一個模板引擎插件)
  • 可以通過此插件自定制 index.html 頁面的內容

1.3.2 webpack-dev-server

webpack-dev-server 可以讓 webpack 監(jiān)聽項目源代碼的變化,從而進行自動打包構建。

1 安裝 webpack-dev-server

運行如下的命令,即可在項目中安裝此插件:

  • npm install webpack-dev-server@3.11.2 -D (只在開發(fā)階段用到的工具)
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm install webpack-dev-server@3.11.2 -D
//....一堆警告 只要不報錯就行

+ webpack-dev-server@3.11.2
added 374 packages from 227 contributors and updated 125 packages in 17.789s

41 packages are looking for funding
  run `npm fund` for details

2 配置 webpack-dev-server

① 修改 package.json -> scripts 中的 dev 命令如下:

這個是用來進行實時打包的,只要程序員保存代碼就是重新打包項目

  • 將package.json下的scripts屬性的dev改成如下
  "scripts": {
    "dev": "webpack serve",
  }

② 再次運行 npm run dev 命令,重新進行項目的打包 (又又又報錯)

PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev

> change-rows-color@1.0.0 dev D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
> webpack serve

[webpack-cli] Unable to load '@webpack-cli/serve' command
[webpack-cli] TypeError: options.forEach is not a function
    at WebpackCLI.makeCommand (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\webpack-cli\lib\webpack-cli.js:173:21)
    at ServeCommand.apply (D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color\node_modules\@webpack-cli\serve\lib\index.js:41:19)
//...省略
npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\86184\AppData\Roaming\npm-cache\_logs\2023-05-25T11_47_09_839Z-debug.log

解決方法沒有安裝 npm i --save-dev webpack-cli

PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm i --save-dev webpack-cli 
//.....
+ webpack-cli@4.10.0
removed 9 packages and updated 4 packages in 3.99s
34 packages are looking for funding
  run `npm fund` for details

//查看版是否安裝webpack-cli 
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npx webpack --version
webpack: 5.42.1
webpack-cli: 4.10.0
webpack-dev-server 3.11.2

//再次執(zhí)行
PS D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color> npm run dev
> change-rows-color@1.0.0 dev D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
> webpack serve
// 需要訪問http://localhost:8080 地址
i ?wds?: Project is running at http://localhost:8080/
// 我們在webpack.config.js中加入了output屬性 則說明更新的js代碼在http://localhost:8080/bundle.js中
i ?wds?: webpack output is served from /
i ?wds?: Content not from webpack is served from D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
//.....
webpack 5.42.1 compiled successfully in 447 ms
i ?wdm?: Compiled successfully.
//當看到光標在這里一閃一閃的就好了

注意這個不能用瀏覽器打開了需要訪問http://localhost:8080 地址

注意:我們重新打包的 是放在內存中,沒有放到磁盤中 因為反復讀寫磁盤慢還會造成磁盤損毀。

如果我們刪除dist文件夾 再去保存index.js中的代碼 ,你會發(fā)現不會生成dist文件夾,這正是因為我們存放的到內存中,并沒有在磁盤中生成dist文件夾

那么既然保存在內存中那我們index.js就不能在**<script src=“…/dist/bundle.js”></script>**中訪問到

在上面運行的指令中說明了是在http://localhost:8080/bundle.js中可以訪問

那么就是將**<script src=“…/dist/bundle.js”></script>換為<script src=“/bundle.js”></script>**

③ 在瀏覽器中訪問 http://localhost:8080 地址,查看自動打包效果

  • 打開網址如下:

注意:打開src文件夾打開index.html就可以看見

注意:webpack-dev-server 會啟動一個實時打包的 http 服務器

3 打包生成的文件哪兒去了?

① 不配置 webpack-dev-server 的情況下,webpack 打包生成的文件,會存放到實際的物理磁盤上

  • 嚴格遵守開發(fā)者在 webpack.config.js 中指定配置
  • 根據 output 節(jié)點指定路徑進行存放

② 配置了 webpack-dev-server 之后,打包生成的文件存放到了內存中

  • 不再根據 output 節(jié)點指定的路徑,存放到實際的物理磁盤上
  • 提高了實時打包輸出的性能,因為內存比物理磁盤速度快很多

4 生成到內存中的文件該如何訪問?

webpack-dev-server 生成到內存中的文件,默認放到了項目的根目錄中,而且是虛擬的、不可見的。

  • 可以直接用 / 表示項目根目錄,后面跟上要訪問的文件名稱,即可訪問內存中的文件
  • 例如 /bundle.js 就表示要訪問 webpack-dev-server 生成到內存中的 bundle.js 文件

1.3.3 html-webpack-plugin

上一節(jié)說到 ,如果我們一進入8080端口要打開src文件夾才能看到index.html頁面

如果我們想一進入8080端口就打開index.html頁面 就需要借助下面的插件

html-webpack-plugin 是 webpack 中的 HTML 插件,可以通過此插件自定制 index.html 頁面的內容。

需求:通過 html-webpack-plugin 插件,將 src 目錄下的 index.html 首頁,復制到項目根目錄中一份!

1 安裝 html-webpack-plugin

運行如下的命令,即可在項目中安裝此插件:

npm install html-webpack-plugin@5.3.2 -D

2 配置 html-webpack-plugin

代碼

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template:'./src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename:'./index.html'
})
module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    plugins: [htmlPlugin]
}
  • webpack.config.js
//導入path模塊
const path = require('path');

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template:'./src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename:'./index.html'
})

module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        filename: 'bundle.js'
    },
    // 3. 插件的數組,將來 webpack 在運行時,會加載并調用這些插件
    plugins: [htmlPlugin]
}

3 解惑 html-webpack-plugin

① 通過 HTML 插件復制到項目根目錄中的 index.html 頁面,也被放到了內存中。

② HTML 插件在生成的 index.html 頁面,自動注入了打包的 bundle.js 文件。

這句話的意思是,當運行后,我們把html中的導入的bundle.js文件個注釋。再去刷新頁面還能加載出來,右鍵查看網頁源代碼發(fā)現

<!DOCTYPE html>
<html lang="en">
<head>
   <!-- 這是注釋的-->
  <!-- <script src="/bundle.js"></script> -->
<!-- 這是自動注入了打包的 bundle.js 文件-->
<script defer src="bundle.js"></script></head>
<body>
    <ul>
        <li>這是第1個li</li>
    </ul>
</body>
</html>

4 devServer 節(jié)點

如果我們想在第一次打包時,就可以自動打開頁面,就要安裝webpack-dev-server 插件

在 webpack.config.js 配置文件中,可以通過 devServer 節(jié)點對 webpack-dev-server 插件進行更多的配置,

示例代碼如下:

devServer: {
        // 首次打包成功后,自動打開瀏覽器
        open: true,
        // 在 http 協(xié)議中,如果端口號是 80,則可以被省略
        port: 8080,
        // 指定運行的主機地址
        host: '127.0.0.1'
      },

注意:凡是修改了 webpack.config.js 配置文件,或修改了 package.json 配置文件,必須重啟實時打包的服

務器,否則最新的配置文件無法生效!

  • webpack.config.js
//導入path模塊
const path = require('path');

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template:'./src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename:'./index.html'
})



module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        filename: 'bundle.js'
    },
    // 3. 插件的數組,將來 webpack 在運行時,會加載并調用這些插件
    plugins: [htmlPlugin],

    devServer: {
        // 首次打包成功后,自動打開瀏覽器
        open: true,
        // 在 http 協(xié)議中,如果端口號是 80,則可以被省略
        port: 8080,
        // 指定運行的主機地址
        host: '127.0.0.1'
      }
}

1.4 webpack 中的 loader

1 loader 概述

在實際開發(fā)過程中,webpack 默認只能打包處理以 .js 后綴名結尾的模塊。其他非 .js 后綴名結尾的模塊,

webpack 默認處理不了,需要調用 loader 加載器才可以正常打包,否則會報錯!

loader 加載器的作用:協(xié)助 webpack 打包處理特定的文件模塊。比如:

  • css-loader 可以打包處理 .css 相關的文件
  • less-loader 可以打包處理 .less 相關的文件
  • babel-loader 可以打包處理 webpack 無法處理的高級 JS 語法

2 loader 的調用過程

3 打包處理 css 文件

  • src–>css–>index.css
li {
    list-style: none;
}

以前我們是在index.html中引用css,但是以后可以把css當作一個模塊來使用。如下

import './css/index.css'
  • src–>index1.js
// 1. 使用 ES6 導入語法,導入 jQuery
import $ from 'jquery'

// 導入樣式(在 webpack 中,一切皆模塊,都可以通過 ES6 導入語法進行導入和使用)
import './css/index.css'

// 2. 定義 jQuery 的入口函數
$(function () {
  // 3. 實現奇偶行變色
  // 奇數行為紅色odd
  $('li:odd').css('background-color', 'red')
  $('li:even').css('background-color', 'green')
  // 0 是偶數
  // 1 是奇數
})

此時運行會報錯

ERROR in ./src/css/index.css 1:3
Module parse failed: Unexpected token (1:3) --模塊解析失敗
You may need an appropriate loader to handle this file type  --你需要一個合適loder的文件去處理這個問題

① 運行 npm i style-loader@3.0.0 css-loader@5.2.6 -D 命令,安裝處理 css 文件的 loader

② 在 webpack.config.js 的 module -> rules 數組中,添加 loader 規(guī)則如下:

module: { //所有第三方文件模塊的匹配規(guī)則
    rules: [ // 文件后綴名的匹配規(guī)則
      // 定義了不同模塊對應的 loader
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
    ]
}

其中,test 表示匹配的文件類型, use 表示對應要調用的 loader

注意:

  • use 數組中指定的 loader 順序是固定的
  • 多個 loader 的調用順序是:從后往前調用 [‘style-loader’, ‘css-loader’]

工作原理

  1. webpack 默認只能打包處理.js 結尾的文件,處理不了其他后綴的文件
  2. 由于代碼中包含了index.js這個文件,因此webpack默認處理不了
  3. 當webpack發(fā)現某個文件處理不了,就會查早webpack.config.js 這個配置文件,看module.rules數組中,是否配置了對應的loader加載器
  4. webpack把index.css這個文件,先轉交給最后一個loader進行處理(先轉交給css-loader)
  5. 當 css-loader 處理完畢之后,會把處理的結果,轉交給下一個loader(轉交給 style-loader)
  6. 當style-loader處理完畢之后,發(fā)現沒有下一個loader了,于是就把處理的結果,轉交給webpack
  7. webpack 把style-loader處理的結果,合并到./dist/bundle.js 中,最終生成打包好的文件。

4 打包處理 less 文件

less和css

區(qū)別:

1、Less是一門CSS預處理語言,而css是一種用來表現HTML或XML等文件樣式的計算機語言;

2、less擴展了CSS語言,增加了css本身沒有的變量、函數等特性;

3、css可以被瀏覽器直接識別,less需要先編譯為css。

  • src–>css–>index.less
html,body,ul{
    margin: 0;
    padding: 0;
    li {
        line-height: 30px;
        padding-left: 20px;
        font-size: 12px;
    }
}
  • src–>index1.js
// 1. 使用 ES6 導入語法,導入 jQuery
import $ from 'jquery'

// 導入樣式(在 webpack 中,一切皆模塊,都可以通過 ES6 導入語法進行導入和使用)
import './css/index.css'
import './css/index.less'

// 2. 定義 jQuery 的入口函數
$(function () {
  // 3. 實現奇偶行變色
  // 奇數行為紅色odd
  $('li:odd').css('background-color', 'red')
  $('li:even').css('background-color', 'green')
  // 0 是偶數
  // 1 是奇數
})

① 運行 npm i less-loader@10.0.1 less@4.1.1 -D 命令

② 在 webpack.config.js 的 module -> rules 數組中,添加 loader 規(guī)則如下:

// 處理 .less 文件的 loader
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
  • webpack.config.js
//導入path模塊
const path = require('path');

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template:'./src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename:'./index.html'
})



module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        filename: 'bundle.js'
    },
    // 3. 插件的數組,將來 webpack 在運行時,會加載并調用這些插件
    plugins: [htmlPlugin],

    devServer: {
        // 首次打包成功后,自動打開瀏覽器
        open: true,
        // 在 http 協(xié)議中,如果端口號是 80,則可以被省略
        port: 8080,
        // 指定運行的主機地址
        host: '127.0.0.1'
    },
    module: { //所有第三方文件模塊的匹配規(guī)則
        rules: [ // 文件后綴名的匹配規(guī)則
            // 定義了不同模塊對應的 loader
            { test: /\.css$/, use: ['style-loader', 'css-loader',] },

            // 處理 .less 文件的 loader
            { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
            // 處理圖片文件的 loader
        ]
    }
}

5 打包處理樣式表中與url 路徑相關的文件

  • src–>image–>xunlei 放一個小圖標的圖片
  • src–>index.js 加上這句<img src=“” alt=“” class=“box”>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <script src="./index.js"></script> -->
    <!-- <script src="../dist/main.js"></script> -->
    <!-- <script src="../dist/bundle.js"></script> -->
      <!-- 加載和引用內存中的 bundle.js -->
    <script src="/bundle.js"></script>
</head>
<body>
    <ul>
        <li>這是第1個li</li>
        <li>這是第2個li</li>
        <li>這是第3個li</li>
        <li>這是第4個li</li>
        <li>這是第5個li</li>
        <li>這是第6個li</li>
        <li>這是第7個li</li>
        <li>這是第8個li</li>
        <li>這是第9個li</li>
    </ul>

    <!-- 需求:把 /src/images/logo.jpg 設置給 src 屬性 -->
    <img src="" alt="" class="box">
    
</body>
</html>

語法

// 1. 導入圖片,得到圖片文件
import logo from './image/XunLei.png'
// console.log(logo)
// 2. 給 img 標簽的 src 動態(tài)賦值   
$('.box').attr('src', logo)  //attr()方法設置或返回被選元素的屬性值
  • src–>index1.js
// 1. 使用 ES6 導入語法,導入 jQuery
import $ from 'jquery'

// 導入樣式(在 webpack 中,一切皆模塊,都可以通過 ES6 導入語法進行導入和使用)
import './css/index.css'
import './css/index.less'


// 1. 導入圖片,得到圖片文件
import logo from './image/XunLei.png'
// console.log(logo)  打印圖片得到了 圖片的base64的字符串
// 2. 給 img 標簽的 src 動態(tài)賦值   
$('.box').attr('src', logo)  //attr()方法設置或返回被選元素的屬性值


// 2. 定義 jQuery 的入口函數
$(function () {
  // 3. 實現奇偶行變色
  // 奇數行為紅色odd
  $('li:odd').css('background-color', 'red')
  $('li:even').css('background-color', 'green')
  // 0 是偶數
  // 1 是奇數
})

① 運行 npm i url-loader@4.1.1 file-loader@6.2.0 -D 命令

② 在 webpack.config.js 的 module -> rules 數組中,添加 loader 規(guī)則如下:

其中 ? 之后的是 loader 的參數項:

  • limit 用來指定圖片的大小,單位是字節(jié)(byte)
  • 只有 ≤ limit 大小的圖片,才會被轉為 base64 格式的圖片 ,如果大于則是路徑

樣式的轉換過程

注意在 webpack中 把 .css和.less結尾的樣式轉換成了bundle.js中 類似于js的方式去運行

6. 打包處理 js 文件中的高級語法

webpack 只能打包處理一部分高級的 JavaScript 語法。對于那些 webpack 無法處理的高級 js 語法,需要借

助于 babel-loader 進行打包處理。例如 webpack 無法處理下面的 JavaScript 代碼:

  • src–>index1.js
// 1. 使用 ES6 導入語法,導入 jQuery
import $ from 'jquery'

// 導入樣式(在 webpack 中,一切皆模塊,都可以通過 ES6 導入語法進行導入和使用)
// 如果某個模塊中,使用 from 接收到的成員為 undefined,則沒必要進行接收
import './css/index.css'
import './css/index.less'
// 這里沒有寫成  import a from './css/index.css'  console.log(a) 都是underfined
// 注意在 webpack中 把  .css和.less結尾的樣式轉換成了bundle.js中 類似于js的方式去運行


// 1. 導入圖片,得到圖片文件
import logo from './image/XunLei.png'
 console.log(logo)  //打印圖片得到了 圖片的base64的字符串
// 2. 給 img 標簽的 src 動態(tài)賦值   
$('.box').attr('src', logo)  //attr()方法設置或返回被選元素的屬性值


// 2. 定義 jQuery 的入口函數
$(function () {
  // 3. 實現奇偶行變色
  // 奇數行為紅色odd
  $('li:odd').css('background-color', 'red')
  $('li:even').css('background-color', 'green')
  // 0 是偶數
  // 1 是奇數
})


// 定義裝飾器函數
function info(target) {
  target.info = 'Person info.'
}

// 定義一個普通的類
@info
class Person {}

console.log(Person.info)

6.1 安裝 babel-loader 相關的包

運行如下的命令安裝對應的依賴包:

npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D

在 webpack.config.js 的 module -> rules 數組中,添加 loader 規(guī)則如下:

{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
  • webpack.config.js
//導入path模塊
const path = require('path');

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template: './src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename: './index.html'
})



module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        filename: 'bundle.js'
    },
    // 3. 插件的數組,將來 webpack 在運行時,會加載并調用這些插件
    plugins: [htmlPlugin],

    devServer: {
        // 首次打包成功后,自動打開瀏覽器
        open: true,
        // 在 http 協(xié)議中,如果端口號是 80,則可以被省略
        port: 8080,
        // 指定運行的主機地址
        host: '127.0.0.1'
    },
    module: { //所有第三方文件模塊的匹配規(guī)則
        rules: [ // 文件后綴名的匹配規(guī)則
            // 定義了不同模塊對應的 loader
            { test: /\.css$/, use: ['style-loader', 'css-loader',] },

            // 處理 .less 文件的 loader
            { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
            // 處理圖片文件的 loader
            // 如果需要調用的 loader 只有一個,則只傳遞一個字符串也行,如果有多個loader,則必須指定數組
            // 在配置 url-loader 的時候,多個參數之間,使用 & 符號進行分隔
            { test: /\.jpg|png|gif$/, use: 'url-loader?limit=4096&outputPath=images' },
            // 使用 babel-loader 處理高級的 JS 語法
            // 在配置 babel-loader 的時候,程序員只需要把自己的代碼進行轉換即可;一定要排除 node_modules 目錄中的 JS 文件
            // 因為第三方包中的 JS 兼容性,不需要程序員關心
            { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }

        ]
    }
}

6.2 配置 babel-loader

在項目根目錄下,創(chuàng)建名為 babel.config.js 的配置文件,定義 Babel 的配置項如下:

module.exports = {
    // 聲明 babel 可用的插件
    // 將來,webpack 在調用 babel-loader 的時候,會先加載 plugins 插件來使用
    plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]]
  }
  • babel.config.js
module.exports = {
    // 聲明 babel 可用的插件
    // 將來,webpack 在調用 babel-loader 的時候,會先加載 plugins 插件來使用
    plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]]
}

運行后在控制臺輸出 Person info.

注意:上面就是插件中的插件 babel-loader用到了插件plugin-proposal-decorators

詳情請參考 Babel 的官網 https://babeljs.io/docs/en/babel-plugin-proposal-decorators

1.5 打包發(fā)布

前面就是打包到了內存中但是我需要打包到磁盤中,就需要下面的打包發(fā)布,交給后端人員

1.5.1 為什么要打包發(fā)布

項目開發(fā)完成之后,需要使用 webpack 對項目進行打包發(fā)布,主要原因有以下兩點:

① 開發(fā)環(huán)境下,打包生成的文件存放于內存中,無法獲取到最終打包生成的文件

② 開發(fā)環(huán)境下,打包生成的文件不會進行代碼壓縮和性能優(yōu)化

為了讓項目能夠在生產環(huán)境中高性能的運行,因此需要對項目進行打包發(fā)布。

1.5.2 配置 webpack 的打包發(fā)布

在 package.json 文件的 scripts 節(jié)點下,新增 build 命令如下:

"scripts": {
    "dev": "webpack",
    "build": "webpack --mode production"
    //注意這里 要用 npm run build進行發(fā)布 ,前面使用npm run dev來進行實時保存到內存中
    // 注意build可以隨便命名 但是后面的webpack --mode production不能隨便寫
  },

–model 是一個參數項,用來指定 webpack 的運行模式。production 代表生產環(huán)境,會對打包生成的文件

進行代碼壓縮和性能優(yōu)化。

注意:通過 --model 指定的參數項,會覆蓋 webpack.config.js 中的 model 選項。

  • package.json
"scripts": {
    "dev": "webpack serve",
    "build": "webpack --mode production"
  }

注意這里說一下流程

我們在運行或者打包時 ,先進入webpack.config.js 再到package.json中

  • 在npm run dev 時我們要求的是速度快,所以不需要壓縮 而不需要壓縮則速度快,所以 在webpack.config.js 中修改 module.exports = {mode: production’'}
  • 在npm run build時 我們時發(fā)布 要求體積小 ,所以需要壓縮,而壓縮需要時間 所以 在webpack.config.js 中修改module.exports = {mode: ‘development’}

由上可知 我們在打包中就不需要 在 webpack.config.js 指定類型,而在package.json中 修改 “scripts”: {“build”: “webpack --mode production”}將mode的默認值development進行修改,改為production, 因為–mode選項的優(yōu)先級高于選項mode的優(yōu)先級 會進行覆蓋

當打包過后就可以發(fā)布到服務器了

1.5.3 把 JavaScript 文件統(tǒng)一生成到 js 目錄中

我們發(fā)現我們打包生成的東西比較亂,我們打包后希望圖片和圖片放一起,js和js放一起。那么我們就需要用到下面的知識。

在 webpack.config.js 配置文件的 output 節(jié)點中,進行如下的配置:

module.exports = {
		output: {//這個時指定打包時要放到的地方
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        //filename: 'bundle.js'
        //現在需要統(tǒng)一js
        filename: 'js/bundle.js'
   	 },
}

1.5.4 把圖片文件統(tǒng)一生成到 image 目錄中

修改 webpack.config.js 中的 url-loader 配置項,新增 outputPath 選項即可指定圖片文件的輸出路徑:

  • webpack.config.js
module.exports = {
    //前面的代碼省略
    module: { 
        rules: [ 
            // 處理圖片文件的 loader
            // 如果需要調用的 loader 只有一個,則只傳遞一個字符串也行,如果有多個loader,則必須指定數組
            // 在配置 url-loader 的時候,多個參數之間,使用 & 符號進行分隔
            // outputPath參數是指打包后存放的路徑 ,這里等于images表示打包生成的圖片放在dist-->images中 
            // 注意只有圖片大小超過limit的圖片才會放到dist-->images中
            { test: /\.jpg|png|gif$/, use: 'url-loader?limit=409&outputPath=images' },
        ]
    }
}

1.5.5 自動清理 dist 目錄下的舊文件

由于每次打包發(fā)布都需要刪除dist目錄比較麻煩。

為了在每次打包發(fā)布時自動清理掉 dist 目錄中的舊文件,可以安裝并配置 clean-webpack-plugin 插件:

首先找到npmjs.com進入官網,然后去點擊,文檔如下

安裝:-D的縮寫是–save-dev

Installation
npm install --save-dev clean-webpack-plugin

使用:由于叫clean-webpack-plugin,所以在webpack.config.js 使用

Usage
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const webpackConfig = {
    plugins: [
        /**
         * All files inside webpack's output.path directory will be removed once, but the
         * directory itself will not be. If using webpack 4+'s default configuration,
         * everything under <PROJECT_DIR>/dist/ will be removed.
         * Use cleanOnceBeforeBuildPatterns to override this behavior.
         *
         * During rebuilds, all webpack assets that are not used anymore
         * will be removed automatically.
         *
         * See `Options and Defaults` for information
         */
        new CleanWebpackPlugin(),
    ],
};

module.exports = webpackConfig;

上面的代碼可以簡化為

// 導入clean-webpack-plugin插件
// 下面這句話是解構賦值 
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// const obj = require('clean-webpack-plugin');
// console.log(obj);
// 結果為{ CleanWebpackPlugin: [class CleanWebpackPlugin] }
// 則const { CleanWebpackPlugin } = require('clean-webpack-plugin');相當于
// const { CleanWebpackPlugin } = { CleanWebpackPlugin: function () { } };這樣 CleanWebpackPlugin就可以直接使用了
// 這個CleanWebpackPlugin是構造函數,一般首字母大寫的都是構造函數
module.exportCleanWebpackPlugins = {
			plugins: [new CleanWebpackPlugin()],
}

webpack.config.js

//導入path模塊
const path = require('path');

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象,相當于實例化對象
const htmlPlugin = new HtmlPlugin({
    // 指定要復制哪個頁面
    template: './src/index.html',
    // 指定復制出來的文件名和存放路徑
    filename: './index.html'
})

// 導入clean-webpack-plugin插件
// 下面這句話是解構賦值 
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// const obj = require('clean-webpack-plugin');
// console.log(obj);
// 結果為{ CleanWebpackPlugin: [class CleanWebpackPlugin] }
// 則const { CleanWebpackPlugin } = require('clean-webpack-plugin');相當于
// const { CleanWebpackPlugin } = { CleanWebpackPlugin: function () { } };這樣 CleanWebpackPlugin就可以直接使用了


module.exports = {
    // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
    // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
    // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
    mode: 'development',
    // entry: '指定要處理哪個文件'
    //__dirname 相當于當前目錄 即D:\筆記之前端\筆記之Vue\筆記\code\第一章\change-rows-color
    entry: path.join(__dirname, './src/index1.js'),
    // 指定生成的文件要存放到哪里
    output: {//這個時指定打包時要放到的地方
        // 存放的目錄
        path: path.join(__dirname, 'dist'),
        // 生成的文件名
        //filename: 'bundle.js'
        //現在需要統(tǒng)一js
        filename: 'js/bundle.js'
    },
    // 3. 插件的數組,將來 webpack 在運行時,會加載并調用這些插件  
    // new CleanWebpackPlugin()是 打包時清除舊包 要用到的插件
    plugins: [htmlPlugin, new CleanWebpackPlugin()],

    devServer: {
        // 首次打包成功后,自動打開瀏覽器
        open: true,
        // 在 http 協(xié)議中,如果端口號是 80,則可以被省略
        port: 8080,
        // 指定運行的主機地址
        host: '127.0.0.1'
    },
    module: { //所有第三方文件模塊的匹配規(guī)則
        rules: [ // 文件后綴名的匹配規(guī)則
            // 定義了不同模塊對應的 loader
            { test: /\.css$/, use: ['style-loader', 'css-loader',] },

            // 處理 .less 文件的 loader
            { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
            // 處理圖片文件的 loader
            // 如果需要調用的 loader 只有一個,則只傳遞一個字符串也行,如果有多個loader,則必須指定數組
            // 在配置 url-loader 的時候,多個參數之間,使用 & 符號進行分隔
            // outputPath參數是指打包后存放的路徑 ,這里等于images表示打包生成的圖片放在dist-->images中 
            // 注意只有圖片大小超過limit的圖片才會放到dist-->images中
            { test: /\.jpg|png|gif$/, use: 'url-loader?limit=409&outputPath=images' },
            // 使用 babel-loader 處理高級的 JS 語法
            // 在配置 babel-loader 的時候,程序員只需要把自己的代碼進行轉換即可;一定要排除 node_modules 目錄中的 JS 文件
            // 因為第三方包中的 JS 兼容性,不需要程序員關心
            { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }

        ]
    }
}

// module.exports = {
//     // mode 代表 webpack 運行的模式,可選值有兩個 development 和 production
//     // 結論:開發(fā)時候一定要用 development,因為追求的是打包的速度,而不是體積;
//     // 反過來,發(fā)布上線的時候一定能要用 production,因為上線追求的是體積小,而不是打包速度快!
//     mode: 'production'
// }

1.6 Source Map

比如在src–>index1.js中 把第39行的console.log(Person.info)改為consle.log(Person.info)

在我們運行npm run dev時,如果我們代碼報錯,報錯提示的41行是我們在內存中生成的index1.js的行數,而不是我們代碼src–>index1.js中的行數

1.6.1 生產環(huán)境遇到的問題

前端項目在投入生產環(huán)境之前,都需要對 JavaScript 源代碼進行壓縮混淆,從而減小文件的體積,提高文件的

加載效率。此時就不可避免的產生了另一個問題:

對壓縮混淆之后的代碼除錯(debug)是一件極其困難的事情

  • 變量被替換成沒有任何語義的名稱
  • 空行和注釋被剔除

1.6.2 什么是 Source Map

Source Map 就是一個信息文件,里面儲存著位置信息。也就是說,Source Map 文件中存儲著壓縮混淆后的

代碼,所對應的轉換前的位置。

有了它,出錯的時候,除錯工具將直接顯示原始代碼,而不是轉換后的代碼,能夠極大的方便后期的調試。

1.6.3 webpack開發(fā)環(huán)境下的Source Map

在開發(fā)環(huán)境下,webpack 默認啟用了 Source Map 功能。當程序運行出錯時,可以直接在控制臺提示錯誤行

的位置,并定位到具體的源代碼:

3.1 默認 Source Map 的問題

開發(fā)環(huán)境下默認生成的 Source Map,記錄的是生成后的代碼的位置。會導致運行時報錯的行數與源代碼的行

數不一致的問題。示意圖如下:

3.2 解決默認 Source Map 的問題

開發(fā)環(huán)境下,推薦在 webpack.config.js 中添加如下的配置,即可保證運行時報錯的行數與源代碼的行數

保持一致:

module.exports = {
    // 在開發(fā)調試階段,建議大家都把 devtool 的值設置為 eval-source-map
    // devtool: 'eval-source-map',
    // 在實際發(fā)布的時候,建議大家把 devtool 的值設置為 nosources-source-map 或直接關閉 SourceMap
    devtool: 'eval-source-map',
}

1.6.4 webpack生產環(huán)境下的Source Map

在生產環(huán)境下,如果省略了 devtool 選項,則最終生成的文件中不包含 Source Map。這能夠防止原始代碼通

過 Source Map 的形式暴露給別有所圖之人。

4.1 只定位行數不暴露源碼

在生產環(huán)境下,如果只想定位報錯的具體行數,且不想暴露源碼。此時可以將 devtool 的值設置為

nosources-source-map。實際效果如圖所示:

4.2 定位行數且暴露源碼

在生產環(huán)境下,如果想在定位報錯行數的同時,展示具體報錯的源碼。此時可以將 devtool 的值設置為

source-map。實際效果如圖所示:

1.6.5 Source Map 的最佳實踐

① 開發(fā)環(huán)境下(development):

  • 建議把 devtool 的值設置為 eval-source-map
  • 好處:可以精準定位到具體的錯誤行

② 生產環(huán)境下(production):

  • 建議關閉 Source Map (也就是注釋掉)或將 devtool 的值設置為 nosources-source-map
  • 好處:防止源碼泄露,提高網站的安全性

實際開發(fā)中需要自己配置 webpack 嗎?

答案:不需要!

  • 實際開發(fā)中會使命令行工具(俗稱 CLI)一鍵生成帶有 webpack 的項目
  • 開箱即用,所有 webpack 配置項都是現成的!
  • 我們只需要知道 webpack 中的基本概念即可!

1.7webpack中@的原理和好處

當我們在導入模塊進行使用時有時需要往上翻 …/…/msg.js

比如新建src–>js,src–>js–>test,src–>js–>test–>info.js,msg.js

  • src–>js–>test–>info.js
import msg from '../../msg' //如果這個我們需要往上翻兩層,才能導入msg.js模塊

console.log(msg)
  • msg.js
export default {
  msg: 'hello Vue.'
}
  • src–>index1.js
// 導入 src/js/test/info.js
import './js/test/info.js'

執(zhí)行過程如下 先在src–>index1.js中導入src–>js–>test–>info.js,在從src–>js–>test–>info.js中導入msg.js

結果為{msg: ‘hello Vue.’} 為了不用…/…/而用@代表根目錄 ,進而實現從外往里找、

首先需要在webpack.config.js中進行配置

const path = require('path')

// 1. 導入 html-webpack-plugin 這個插件,得到插件的構造函數
const HtmlPlugin = require('html-webpack-plugin')

// 2. new 構造函數,創(chuàng)建插件的實例對象
const htmlPlugin = new HtmlPlugin({
  // 指定要復制哪個頁面
  template: './src/index.html',
  // 指定復制出來的文件名和存放路徑
  filename: './index.html'
})

// 注意:左側的 { } 是解構賦值
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

// 使用 Node.js 中的導出語法,向外導出一個 webpack 的配置對象
module.exports = {
  mode: 'development',
  resolve: {
    alias: {
      // 告訴 webpack,程序員寫的代碼中,@ 符號表示 src 這一層目錄
      '@': path.join(__dirname, './src/')
    }
  }
}

修改代碼

  • src–>js–>test–>info.js
// import msg from '../../msg' //如果這個我們需要往上翻兩層,才能導入msg.js模塊
import msg from '@/msg.js'

// 建議大家使用 @ 表示 src 源代碼目錄,從外往里查找;不要使用 ../ 從里往外查找
//     @/msg.js

console.log(msg)

  • msg.js 不變
export default {
  msg: 'hello Vue.'
}
  • src–>index1.js
// 導入 src/js/test/info.js
import '@/js/test/info.js'

總結

① 能夠掌握 webpack 的基本使用

  • 安裝、webpack.config.js、修改打包入口
  • 了解常用的 plugin 的基本使用
  • webpack-dev-server、html-webpack-plugin

③ 了解常用的 loader 的基本使用

  • loader 的作用、loader 的調用過程

④ 能夠說出 Source Map 的作用

  • 精準定位到錯誤行并顯示對應的源碼
  • 方便開發(fā)者調試源碼中的錯誤

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 詳解node child_process模塊學習筆記

    詳解node child_process模塊學習筆記

    這篇文章主要介紹了詳解node child_process模塊學習筆記,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Node.js中的HTTP請求與響應詳解

    Node.js中的HTTP請求與響應詳解

    本文詳細講解了Node.js中的HTTP請求與響應,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 淺探express路由和中間件的實現

    淺探express路由和中間件的實現

    這篇文章主要介紹了淺探express路由和中間件的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • cnpm安裝詳細步驟(附圖文!)

    cnpm安裝詳細步驟(附圖文!)

    由于npm軟件包管理器有時可能不太穩(wěn)定,安裝依賴包容易報錯,所以就有了cnpm,這篇文章主要給大家介紹了關于cnpm安裝的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • socket.io學習教程之深入學習篇(三)

    socket.io學習教程之深入學習篇(三)

    這篇文章更加深入的給大家介紹了socket.io的相關資料,之前已經介紹了socket.io的基本教程和應用,本文更為深入的來介紹下socket.io的使用,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • Nodejs初級階段之express

    Nodejs初級階段之express

    這篇文章主要介紹了Nodejs初級階段之express的相關資料,需要的朋友可以參考下
    2015-11-11
  • node?NPM庫增強版globby?Promise使用學習

    node?NPM庫增強版globby?Promise使用學習

    這篇文章主要為大家介紹了node?NPM庫增強版globby?Promise使用學習,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Node.js+Express配置入門教程

    Node.js+Express配置入門教程

    Node.js是一個Javascript運行環(huán)境(runtime)。本文給大家介紹Node.js+Express配置入門教程,值得推薦給大家,感興趣的朋友一起學習吧
    2016-05-05
  • NodeJS 實現手機短信驗證模塊阿里大于功能

    NodeJS 實現手機短信驗證模塊阿里大于功能

    這篇文章主要介紹了NodeJS 實現手機短信驗證模塊阿里大于功能,需要的朋友可以參考下
    2017-06-06
  • 使用Redis和Node.js來開發(fā)簡單的實時聊天功能

    使用Redis和Node.js來開發(fā)簡單的實時聊天功能

    在眾多實時通信的技術中,Redis和Node.js的結合是一種非常強大和流行的選擇,Redis是一種高性能的鍵值存儲數據庫,而Node.js是一個基于事件驅動的JavaScript運行時環(huán)境,兩者的結合可以輕松實現實時聊天功能,本文將指導您使用Redis和Node.js來開發(fā)一個簡單的實時聊天功能
    2024-08-08

最新評論