前端項(xiàng)目自動(dòng)化構(gòu)建工具——Webpack入門教程

參考資料:https://www.webpackjs.com/(中文文檔) https://www.webpackjs.com/(官方文檔)

首先有必要說明一下,本文側(cè)重講解webpack基本配置屬性,不附帶實(shí)例,將會(huì)以通俗易懂的形式地講解;如若需要實(shí)例進(jìn)行相關(guān)練習(xí),可將本文作為理論基礎(chǔ);

Webpack是前端項(xiàng)目自動(dòng)化構(gòu)建工具,本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。(官網(wǎng)定義)。

那么用我們?nèi)嗽拋碚f:webpack是一個(gè)前端模塊化的解決方案,更側(cè)重點(diǎn)打包,可以把開發(fā)中的資源文件(圖片、js文件、css文件等)看成是一個(gè)個(gè)的模塊,然后通過webpack提供的loader(加載器)和plugins(插件)來進(jìn)行處理、合并以及壓縮,打包成符合生產(chǎn)環(huán)境、體積更小的文件資源,以方便提升瀏覽器的渲染速度;

首先我們要理解一下webpack的四大核心概念:

入口(entry)

出口(output)

loader(加載器)

plugins(插件)

  入口(entry): 

webpack入口指的是通過配置來指示webpack的入口文件,即從哪里開始,我們可以在webpack中配置entry屬性,來指定入口文件的路徑;

我們可以看一個(gè)簡單的案例:

//必須將模塊拋出webpack才能訪問得到
module.exports = {
  //entry屬性指定入口文件    值為相對路徑  
  entry: './src/app.js'
}

出口(output):

出口即告訴webpack在哪里輸出它所創(chuàng)建的bundles,以及如何命名這些文件,輸出的文件目錄路徑;也就是說在你用webpack打包的時(shí)候可以通過添加output屬性,來設(shè)置最終經(jīng)過webpack打包輸出后的文件名以及輸出路徑;

//引入node的path模塊
const path = require('path');

module.exports = {
  // webpack執(zhí)行入口文件
  entry: './src/app.js',
   //出口 
  output: {
    // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
    filename: 'bundle.js',
    // 輸出文件都放到 dist 目錄下
   //__dirname是node環(huán)境中全局變量,表示當(dāng)前目錄
    path: path.resolve(__dirname, './dist'),
  }
};

加載器(loader):

loader是讓webpack能夠去處理一些非Javscript類型的文件(webpack自身只能夠識(shí)別原生JS和ES5),loader可以將所有類型的文件轉(zhuǎn)為webpack能處理的有效模塊,然后就可以通過webpack的打包能力,對這些文件進(jìn)行處理;loader的配置有兩個(gè)選項(xiàng):

test:一般都是正則表達(dá)式,用于匹配文件類型;

use:可以是key:value的形式也可以是數(shù)組,用來告訴webpack使用什么loader來加載文件

//引入node的path模塊
const path = require('path');

module.exports = {
  // webpack執(zhí)行入口文件
  entry: './src/app.js',
   //出口 
  output: {
    // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
    filename: 'bundle.js',
    // 輸出文件都放到 dist 目錄下
   //__dirname是node環(huán)境中全局變量,表示當(dāng)前目錄
    path: path.resolve(__dirname, './dist'),
  }
    //模塊關(guān)鍵字,加載器需要在這里進(jìn)行配置
    module:{
        //rules為數(shù)組,保存每個(gè)加載器的配置
        rules:[
            {
                //test屬性必須配置,值為正則表達(dá)式,用于匹配文件
                test:/\.css$/,
                // 對同一個(gè)文件引入多個(gè)loader的方法
                use:[
                    //loader為loader加載器的名稱,必須配置,值為字符串
                    {loader:"style-loader"},
                    {loader:"css-loader"}
                ],
                
                //過濾,排除node_module目錄下的文件
                exclude:/node_module/,
                //指定匹配文件的范圍   指定/demo/目錄下的.css文件進(jìn)行匹配
                include:/demo/
            }
        ]
    }
    

};

webpack中規(guī)定,在webpack中定義loader時(shí),需要定義在module.rules中,否則會(huì)報(bào)錯(cuò);test和use兩個(gè)屬性分別指定了匹配文件的規(guī)則和用什么loader來處理,這兩個(gè)屬性都是必選的,exclude、include分別表示過濾(不處理)某個(gè)文件中的文件和指定(處理)某個(gè)文件夾中的文件,這兩個(gè)屬性都是可選項(xiàng);

插件(plugins):

loader 被用于轉(zhuǎn)換某些類型的模塊,而插件則可以用于執(zhí)行范圍更廣的任務(wù)。插件的范圍包括,從打包優(yōu)化和壓縮,一直到重新定義環(huán)境中的變量。插件接口功能極其強(qiáng)大,可以用來處理各種各樣的任務(wù)。要使用某個(gè)插件,你需要require(引入)插件,然后添加到plugins數(shù)組中,多數(shù)插件可以通過選項(xiàng)option來自定義

//引入node的path模塊
const path = require('path');
//引入extract-text-webpack-plugin插件
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
 // webpack執(zhí)行入口文件
 entry: './src/app.js',
  //出口 
 output: {
   // 把所有依賴的模塊合并輸出到一個(gè) bundle.js 文件
   filename: 'bundle.js',
   // 輸出文件都放到 dist 目錄下
  //__dirname是node環(huán)境中全局變量,表示當(dāng)前目錄
   path: path.resolve(__dirname, './dist'),
 }
   //模塊關(guān)鍵字,加載器需要在這里進(jìn)行配置
   module:{
       //rules為數(shù)組,保存每個(gè)加載器的配置
       rules:[
           {
               //test屬性必須配置,值為正則表達(dá)式,用于匹配文件
               test:/\.css$/,
               // 對同一個(gè)文件引入多個(gè)loader的方法
               use:[
                   //loader為loader加載器的名稱,必須配置,值為字符串
                   {loader:"style-loader"},
                   {loader:"css-loader"}
               ],
               
               //過濾,排除node_module目錄下的文件
               exclude:/node_module/,
               //指定匹配文件的范圍   指定/demo/目錄下的.css文件進(jìn)行匹配
               include:/demo/
           }
       ]
   }
   //配置插件
   plugins: [
   new ExtractTextPlugin({
     //自定義配置插件選項(xiàng)
     // 從 .js 文件中提取出來的 .css 文件的名稱
     filename: `[name]_[md5:contenthash:hex:8].css`,
   }),
]
};

上面就是webpack的四大核心概念,下面我們來介紹一些常用的插件:

loader處理css和Sass:

默認(rèn)情況下webpack是處理不了CSS的代碼的,但是我們可以通過webpack的loader加載器來處理;

module.exports = {
 entry: './src/app.js',
 output: {
   path: __dirname + '/dist',
   filename: 'app.bundle.js'
 },
 module: {
   rules: [
     {
       test: /\.css$/,
       use: [ 'style-loader', 'css-loader' ]
     }
   ]
 }
};

在日常開發(fā)中,我們只需要在webpack.config.js文件中寫上上面的配置代碼即可讓webpack來處理CSS代碼和Sass代碼;
  webpack-dev-server:
      webpack-dev-server是webpack的一個(gè)常用插件,可以用來在本地上開啟服務(wù)、啟動(dòng)瀏覽器并且可以實(shí)時(shí)監(jiān)聽文件修改;

module.exports = {
  entry: './src/app.js',
  ...
    //進(jìn)行webpack-dev-server插件配置
  devServer: {
    //端口號(hào),默認(rèn)8080,可以自定義修改
    port: 9000,
   //運(yùn)行webpack-dev-server的時(shí)候自動(dòng)打開瀏覽器
    open: true
  },
  ...
};

source-map調(diào)試:

開發(fā)總是離不開調(diào)試,但是我們用webpack給項(xiàng)目打包了之后,我們是很不方便找到錯(cuò)誤或者問題所在的,當(dāng)然webpack也想到了這一點(diǎn),因此webpack給我們提供了source-map來進(jìn)行調(diào)試;

devtool選項(xiàng)

source-map

配置結(jié)果

在一個(gè)單獨(dú)的文件中產(chǎn)生一個(gè)完整且功能完全的文件。這個(gè)文件具有最好的source map,但是它會(huì)減慢打包速度;

devtool選項(xiàng)

cheap-module-source-map

配置結(jié)果

在一個(gè)單獨(dú)的文件中生成一個(gè)不帶列映射的map,不帶列映射提高了打包速度,但是也使得瀏覽器開發(fā)者工具只能對應(yīng)到具體的行,不能對應(yīng)到具體的列(符號(hào)),會(huì)對調(diào)試造成不便;

devtool選項(xiàng)

eval-source-map

配置結(jié)果

使用eval打包源文件模塊,在同一個(gè)文件中生成干凈的完整的source map。這個(gè)選項(xiàng)可以在不影響構(gòu)建速度的前提下生成完整的sourcemap,但是對打包后輸出的JS文件的執(zhí)行具有性能和安全的隱患。在開發(fā)階段這是一個(gè)非常好的選項(xiàng),在生產(chǎn)階段則一定不要啟用這個(gè)選項(xiàng);

devtool選項(xiàng)

cheap-module-eval-source-map

配置結(jié)果

這是在打包文件時(shí)最快的生成source map的方法,生成的Source Map會(huì)和打包后的JavaScript文件同行顯示,沒有列映射,和eval-source-map選項(xiàng)具有相似的缺點(diǎn);

綜上所述,從上到下打包速度越來越快,不過同時(shí)帶來的副作用也越多,較快的打包速度的后果就是對打包后的文件的的執(zhí)行有一定影響。在中小型項(xiàng)目中,eval-source-map是一個(gè)比較不錯(cuò)的選擇;

cheap-module-eval-source-map方法構(gòu)建速度更快,但是不利于調(diào)試,推薦在大型項(xiàng)目考慮時(shí)間成本時(shí)使用。

module.exports={
   devtool:"eval-source-map",
}

在webpack打包之后,如果報(bào)錯(cuò)我們是看不到源文件的,因?yàn)榇藭r(shí)文件已經(jīng)被webpack打包了,這很不方便我們的開發(fā)調(diào)試,source-map就是用來解決這個(gè)問題的,通過添加配置devtool:"eval-source-map"這一行簡單的代碼,我們即可在調(diào)試的時(shí)候看到我們的源文件進(jìn)行調(diào)試;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容