webpack3.0小案例webpack初體驗

bs123發表於2017-11-27

寫在前面

這篇文章是自己在整理webpack相關的東西時候突發奇想,想整理出一套由淺入深的博文以此鞭策自己學習,也希望能夠幫助想學習webpack的同學,目前都是入門級別的,大佬請出門右轉。

學習完本篇文章,我希望您能夠掌握以下幾點:

  • webpack是什麼
  • webpack有什麼有點
  • webpack.config.js配置項中,出口(entry)、入口(output)、外掛(plugins)的基本作用和配置方法。
  • html-webpack-plugin、 clean-webpack-plugin 外掛的作用和使用方法。

統一說明,本文中所用到的npm包管理工具均採用淘寶映象(cnpm),原因你懂得。

webpack版本基於3.0版本,本文中具體是3.8.1版本。

什麼是webpack

webpack是一個用以對現代Javascript應用程式模組打包工具,它和gulp、grunt的不同之處在於webpack提供了一整套前端模組化開發的解決法案;webpack把資源作為模組來處理,這裡的資源不止於javascript,還包括html、css、圖片、字型等等。

webpack的優點

  1. 程式碼分割(code splitting),在開發過程中,webpack允許我們將程式碼按照不同職能分割成不同模組進行開發,並且在載入中可以按需載入,減少載入時間。
  2. 外掛化,webpack提供了豐富的外掛介面,通過配置不同的外掛,可以實現我們想要的效果,非常靈活。
  3. 裝載機制,webpack中,我們可以通過提供的loaders預處理專案檔案,包括js、css、html、image等。
  4. 高效能,webpack使用非同步I/O流載入模組,並具有多個快取級別,在漸進式編譯中,速度表現很棒。
  5. 開發方便,weback提供sourceMap和sourceUrl,方便開發者定位除錯,並且通過中介軟體可以實現專案的熱更新,這個在開發中很有作用。

webpack使用

構建專案結構

1、初始化, 新建一個資料夾,取名叫webpackDemo,通過控制檯或者git bash定位到當前檔案下面,執行命令:

    npm init //淘寶映象用 cnpm init複製程式碼

然後一路enter,初始化後,會在該資料夾下面生成一個package.json檔案,然後,再次在命令列內執行:

    npm install //淘寶映象用 cnpm install複製程式碼

2、專案結構搭建, 在webpackDemo資料夾下:

  • 新建src目錄,用於存放開發相關的資原始檔;
    • 在src目錄下新建js、css、views等不同型別的資料夾,以此存放相對應的開發檔案。
  • 新建dist目錄,用於存放打包後生成的檔案;
    • 和src目錄下一樣,新建js、css、views等資料夾,存放打包後的檔案(案例中,先新建一個js資料夾,因為我們現在只用js來體驗webpack)。
  • 新建index.html檔案。
  • 新建webpack.config.js,這是webpack預設關於打包相關的配置檔案。
  • 新建.babelrc檔案,放置babel相關配置,和webpack.config.js一樣,babel的配置檔名稱,也是固定的,即:.babelrc

    注意: webpack預設會讀取webpack.config.js 中的相關配置,如果更換其他名字,webpack預設是找不到配置資訊的。(當然我們也可以去指定webpack讀取的配置檔案,在現階段,我們暫不考慮);

    最終的專案結構如下:

    專案結構
    專案結構

初體驗

1、程式碼編寫,開啟根目錄下的index.html,引入webpack最後編譯的的js檔案,我麼定義js名稱叫做bundle.js。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>webpack demo</title>
    </head>
    <body>
        <!-- 我們給最終編譯出的js叫做bundle.js-->
        <script src="./dist/js/bundle.js"></script>
    </body>
    </html>複製程式碼

2、在src/js資料夾下面,新建app.js,作為webpack編譯的入口檔案,並新增一個方法,在控制檯列印出hello world

    // app.js
    function Hello() {
        console.log('hello world')
    }
    Hello()複製程式碼

3、接下來,我們開啟webpack.config.js,給webapck編譯指定規則:

    // webpack.config.js
    var path = require('path');
    module.exports = {
    entry: path.resolve(__dirname, './src/js/app.js'),//指定webpack打包的入口是app.js
    output: {
        path: path.resolve(__dirname, './dist/js'),//指定打包後js檔案放置的位置
        filename: 'bundle.js'//指定打包後的js名稱,這個就是index.html最終引入的js的名稱
        }
    }複製程式碼

1、配置路徑用path.resolve()處理,是為了確保路徑是從根目錄開始絕對定位到指定位置,webpack3.0要求我們在配置路徑相關的時候使用絕對路徑;
2、path模組是nodejs內建的處理路徑相關的模組。

現在讓我們開啟命令列,執行webpack編譯

    //如果還未安裝webpack,則先執行安裝
    cnpm i webpack --save-dev

    // 安裝完成後執行編譯
    webpack複製程式碼

編譯執行完成後,控制檯輸出以下則表示執行成功。

webpack 編譯
webpack 編譯

此時檢視dist/js目錄,會發現新增了一個bundle.js的檔案,在瀏覽器中開啟index.html,再開啟控制檯,成功輸出hello world。

webpack 編譯
webpack 編譯

看到這裡,估計有人要打人了,就這玩意有啥用,浪費我青春!我要輸出的hello world要你這麼麻煩幹啥。額!騷年,先放下你手上的磚頭,有話好好說。

大名鼎鼎的webpack當然不止這就完了,接下來,讓我們一步一步真正開始認識webpack。

webpack 編譯
webpack 編譯

webpack配置---生成帶hash值的js檔案

現在,我們來看一下webpack配置檔案中的output選項的相關配置,細心的你也許發現,我們最終生成的的bundle.js是我們設定好的,每次打包後生成的名字是不會改變的,但是在實際專案中,為了確保程式碼更改前後無衝突以及版本回退等一系列問題,每次打包後的包檔案,我們會給他打上一個獨一無二的標記,用以區分版本,這又是怎麼實現的呢?

實際上,webpack在打包編譯的時候,會把不同模組的程式碼分別指定一個chunkhash值,最後整體打包後的js會生成一個hash值 (需要注意chunkhash和hash是不一樣的),我們只需要在output配置項中給filename屬性一個填寫hash的佔位符,這樣在每次編譯的時候,就會生成帶有hash值得js檔案:

  var path = require('path')
  module.exports = {
    entry: path.resolve(__dirname, './src/js/app.js'),
    output: {
        path: path.resolve(__dirname, './dist/js'),
        filename: 'bundle-[hash].js'//[hash]為編譯時填寫hash的佔位符,也可以填寫chunkhash等
    }
  }複製程式碼

再次執行編譯,我們會發現,新生成的檔案已經帶有hash值了:

webpack 編譯
webpack 編譯

webpack配置---根據模板動態生成Html

上面我們已經動態生成了帶有不同hash值得js了,那麼問題又來了,既然每次生成的js檔案都不一樣,我們如何去載入生成的js呢,要知道,在index.html裡面,我們寫的是bundle.js啊!

為了解決這個問題,我們就想,如果每次webpack打包編譯後自動將生成的js注入到我們的index.html模板中,這樣我們就不用在我們的index.html中手動新增bundle.js了,不就解決了這個問題麼。

實際上!這種思想正是webpack為我們提供的解決方案-- html-webpack-plugin

首先,我們通過命令列安裝這個外掛

    cnpm install html-webpack-plugin --save-dev複製程式碼

html-webpack-plugin
html-webpack-plugin

然後,我們在配置檔案裡新增對html-webpack-plugin的相關配置

    var path = require('path');
    //引入html-webpack-plugin模組
    var htmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: path.resolve(__dirname, './src/js/app.js'),
        output: {
            path: path.resolve(__dirname, './dist/js'),
            filename: 'bundle-[hash].js'
        },
        //初始化外掛
        plugins:[
            new htmlWebpackPlugin({
                template:'index.html',//定義外掛讀取的模板檔案是根目錄下的index.html
                filename:'index.html'//定義通過模板檔案新生成的頁面名稱
            })
        ]
    }複製程式碼

在配置檔案中,我們新增了plugins這個配置屬性,並初始化html-webpack-plugin外掛,現在我們去index.html中刪除js的引用。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>webpack demo</title>
    </head>
    <body>
       <!--  <script src="./dist/js/bundle.js"></script>-->
    </body>
    </html>複製程式碼

再次執行webpack命令,編譯成功後!再看看我們的dist目錄下,果然生成了index.html。

html-webpack-plugin
html-webpack-plugin

提醒一

html-webpack-plugin外掛執行的時候,需要在專案安裝webpack,如果是全域性安裝的webpack,在此處執行會報錯:Cannot find module 'webpack/lib/node/NodeTemplatePlugin'

html-webpack-plugin
html-webpack-plugin

html-webpack-plugin
html-webpack-plugin

解決辦法就是在本地安裝webpack,定位到專案的根目錄下執行以下命令即可。

    cnpm install webpack複製程式碼

提醒二

細心的你可能又發現,生成的index.html也在dist/js資料夾下面,這和我們想要的結果不一樣,因為我們想要在dist資料夾下把html、js以及後面的css都分開來,為了解決這個問題,我們須將配置檔案的output選項更改一下:

    var path = require('path')
    var htmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
        entry: path.resolve(__dirname, './src/js/app.js'),
        output: {
            // path: path.resolve(__dirname, './dist/js'),
            path: path.resolve(__dirname, './dist'),//將輸出的路徑定位到dist一級就好,然後再filename配置項中,指定二級目錄。
            //filename: 'bundle-[hash].js'
            filename: 'js/bundle-[hash].js'
        },
        plugins: [
            new htmlWebpackPlugin({
                template: 'index.html',
                filename:'index.html'
            })
        ]
    }複製程式碼

在配置中,我們將output中的path路徑指定到dist一級就好,至於生成的js路徑,我們就將js放置在filename選項下,配置完成後,我們再次在命令列執行"webpack"命令,最終發現,dist目錄下新生成了index.html頁面,而js,則依然在js資料夾下生成。

html-webpack-plugin
html-webpack-plugin

webpack配置---清除dist資料夾下面的重複檔案

到目前為止,我們的案例可以動態的生成帶有自己hash命名的js檔案,但是我們發現檔案在一直增加,新生成編譯檔案之前並沒有刪除上一次編譯的檔案,這會讓專案原來越大。為了解決這個問題,我們需要再次引入一個外掛---clean-webpack-plugin

老規矩,首先是安裝,在命令列執行:

    cnpm install clean-webpack-plugin --save-dev複製程式碼

然後在配置檔案中引入外掛並例項化

    var path = require('path');
    var htmlWebpackPlugin = require('html-webpack-plugin');
    //引入外掛模組
    var cleanWebpackPlugin = require('clean-webpack-plugin');
    module.exports = {
        entry: path.resolve(__dirname, './src/js/app.js'),
        output: {
            path: path.resolve(__dirname, './dist'),
            filename: 'js/bundle-[hash].js'
        },
        plugins: [
            new htmlWebpackPlugin({
                template: 'index.html'
            }),
            //初始化外掛配置項
            new cleanWebpackPlugin(
                ['dist'], //匹配要刪除的檔案,這裡則指定每次對dist資料夾進行清理
                {
                    root: __dirname,//指定外掛根目錄位置
                    verbose: true, //開啟在控制檯輸出資訊
                    dry: false //啟用刪除檔案
                }
            )
        ]
    }複製程式碼

在配置中,我們將引入的clean-webpack-plugin例項化,並設定了要刪除檔案的目錄和一些顯示設定,再次在命令列執行"webpack"命令,發現之前的檔案被刪除了,只剩下最新生成的相關檔案。

clean-webpack-plugin
clean-webpack-plugin
;

寫在最後

這一節,我們向大家初步介紹了webpack的使用,並且從頭開始搭建了一個webpack執行的編譯環境,初次體驗了一下webpack,當然,webpack的功能遠遠不止於此,它的最重要的功能loader我們還沒開始,目前筆者所展示的這些,只是webpack很小很小的一部分。

再次提醒讀者盆友,讀完本篇文章您應該瞭解以下內容:

  • webpack是什麼
  • webpack有什麼有點
  • webpack.config.js配置項中,出口(entry)、入口(output)、外掛(plugins)的作用和基本配置方法。
  • html-webpack-plugin、 clean-webpack-plugin 外掛的作用和使用方法。

下一節,我們將在此基礎上學習webpack的載入器用法,包括babel編譯es6、css預處理、autoprefixer用法、css與js檔案分割等,歡迎大家提出寶貴意見,一起學習。

這是前端最好的時代,也是前端最壞的時代,前端不止,學習不停,願各位讀者努力向前,早日成為前端高手。

pix
pix

相關文章