學習webpack一個案例就夠了

[TOC]javascript

webpack打包工具的使用

前言:css

webpack是前端目前最流行的打包工具,爲了節省學習webpack的時間,下面我將以一個案例的形式來介紹webpack的使用,畢竟學習webpack就是要知道怎麼使用,介紹案例的過程,遇到相關的知識點,我也會作相應的介紹,本案例使用的開發工具是vscodehtml

基礎知識前端

npm

只要你安裝了node環境,npm就自動安裝好vue

cnpm

在node裝完以後,全局就有一個npm命令可使用了,可是npm下載各類包默認的服務器在國外,下載速度大受影響,有時還會致使一些環境問題,所以咱們能夠選擇從國內的服務器下載包,這要感謝淘寶團隊的付出,爲國內開發者提供了npm各種包的鏡像java

執行如下命令,安裝淘寶npm包下載工具node

npm i -g cnpm --registry=https://registry.npm.taobao.org
複製代碼

在下載包時,使用如下命令,使用關鍵詞cnpm,如jquery

cnpm i  vue --save
複製代碼

注意:在使用cnpm下載包的過程可能會出現一些警告的信息,但並不影響實際包的使用,可是想要查看安裝完成以後的包的依賴信息時,可能查找不到,什麼是依賴?後面會介紹到webpack

因此建議使用包管理工具,來設置npm從哪一個服務器下載包程序員

nrm

執行如下命令安裝nrm

npm install nrm -g
複製代碼
  1. 查看可用的服務器列表 nrm ls

  2. 查看當前正在使用的服務器 nrm current

  3. 切換到指定的服務器 nrm use 服務器名稱

  4. 測速命令

    nrm test

    nrm test 指定的服務器名稱

經過上面的講解,npm的最優使用方案:

安裝nrm,將npm下載包的服務器設置爲淘寶

npm命令行工具的使用

  1. 下載包(本地安裝) 下載的包會放到當前項目中的node_modules文件夾中!
    npm install 包名 npm install 包名@版本號

    簡寫:

    npm i 包名 npm i 包名@版本號

    npm install 包名 包名1 包名2

  2. 卸載包 npm uninstall 包名

  3. 全局安裝

    當要使用一個包,這個包會提供一個全局命令的時候,這個包就須要被全局安裝!

    命令 npm install 包名 -g npm install 包名 --global

爲何要使用webpack?

在網頁中會引用哪些常見的靜態資源?

  • JS
  • .js .jsx .coffee .ts(TypeScript 類 C# 語言)
  • CSS
  • .css .less .sass .scss
  • Images
  • .jpg .png .gif .bmp .svg
  • 字體文件(Fonts)
  • .svg .ttf .eot .woff .woff2
  • 模板文件
  • .ejs .jade .vue【這是在webpack中定義組件的方式,推薦這麼用】

若是咱們按照傳統的方式引入這些文件會形成什麼問題?

  1. 網頁加載速度慢, 由於 咱們要發起不少的二次請求;
  2. 要處理錯綜複雜的依賴關係

下面正式開始咱們的第一個打包案例

一.搭建目錄結構

注意:

  • 目錄中不要出現中文的文件命名,最外層的文件名字不要使用webpack,我上面是爲了做爲反面教材
  • 其中main.js爲入口文件,bundle.js爲出口文件,後面會講到

二.設置npm下載包的服務器爲淘寶

開客戶端中打開

執行命令:

npm install nrm -g
複製代碼

切換到指定的服務器

nrm use taobao
複製代碼

三.初始化目錄

npm init
複製代碼

這時文件的目錄結構變成了這樣

下面介紹一下目錄中的一些文件類型

package.json文件:

package.json文件就是用來描述一個包的信息的!

只要一個文件夾中有一個合格的pacakge.json文件,那麼這個文件夾就能夠被稱爲是一個包!

合格的定義: 必須包含兩個屬性 name version

版本號說明

通常的版本號都會包含3個數字,中間用.隔開 格式: 主版本號.次版本號.修訂版本號

主版本號: 當代碼功能更新,更新以後,不兼容以前的版本了,那麼須要更新主版本號! 此版本號: 當代碼功能更新,更新以後,依然兼容以前的版本,只是新增了某些功能,那麼須要更新次版本號 修訂版本號: 當代碼更新,更新的只是修復了某些BUG,或者優化了某些功能,那麼這個時候只須要更新 修訂版本號就能夠了

jquery: 1.x 2.x 3.x 1.10.1 1.12.4 1.12.1 1.12.4

dependencies 和 devDependencies 的說明

這兩個屬性中保存的都是當前包全部的依賴信息。

dependencies: 運行時依賴項,在將代碼上傳到服務器時,這個包仍被須要 devDependencies: 開發時依賴項,這個依賴項只須要在開發時時候,上傳到服務器的時候不須要!

問題: 爲何要將依賴項信息存儲起來呢??? 主要目的是爲了代碼共享的時候,比較方便!

在進行代碼分享的時候,不須要分享node_modules,只須要分享本身的代碼和pacakge.json便可,另外的程序員拿到代碼以後,本身根據pacakge.json下載全部的依賴項便可!

npm install 這條命令會自動根據package.json中保存的包信息進行下載 (devDependencies+dependencies)

只下載運行時依賴項可使用命令npm install --production

如何將依賴項的信息保存到dependencies 和 devDependencies中

在早期版本的npm中,依賴項信息不會自動保存!

  1. 將依賴項的信息保存到dependencies npm install 包 --save npm install 包 -S
  2. 將依賴項的信息保存到devDependencies npm install 包 --save-dev npm install 包 -D

通過初始化的目錄,會生成package.json文件,該文件會記錄本文件夾的一些相關的信息,好比入口文件,項目名,安裝了哪些依賴包等,注意項目名不能爲webpack,搭建目錄結構那步我已經講了,不然,在以後的安裝打包工具會報錯

四.書寫index.html,main.js文件

index.html

<ul>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>
        <li>測試專用</li>

    </ul>
複製代碼

main.js

//導入jQuery包
    import $ from 'jquery'//這裏須要安裝庫類
    // 設置偶數行背景色,索引從0開始,0是偶數
    $('li:even').css('backgroundColor','lightblue');
    // 設置奇數行背景色
    $('li:odd').css('backgroundColor','pink');
複製代碼

五.安裝jquery類庫

cnpm i jquery --save
複製代碼

這時咱們按照常規的方法在index.html頁面引入main.js文件,是會報錯的,由於,main.js文件中的import $ from 'jquery'是屬於高級語法,瀏覽器是沒法識別的,因此要使用打包工具來對main.js文件進行處理,編譯成另外一個文件,再在頁面中引入編譯後的文件,便可

六.安裝打包工具

npm i webpack  webpack-cli  -g

npm i webpack webpack-cli  -D
複製代碼

七.新建webpack.config.js文件

新建一個與package.json同級的配置文件webpack.config.js,設置打包模式

module.exports={
    mode:"development"
}
複製代碼

運行,打包代碼

webpack src/main.js dist/bundle.js
複製代碼

上面代碼的是對main.js進行打包,變成bundle.js文件,在頁面中引入該文件,瀏覽器就不存在高級語法不識別的問題了,可是在本案例中,對main.js進行打包後變成的是dist/main.js,而不是dist/bundle.js文件,因此在頁面中引入的是dist/main.js,這是咱們就能看到main.js起做用了

注意,到了這一步,每次修改js文件都要從新執行上面的打包代碼,這樣才能生效,十分麻煩,爲了解決這個問題,咱們能夠採用實時打包,方法見後面

八.使用webpack的配置文件簡化打包時候的命令

  1. 因爲運行webpack命令的時候,webpack須要指定入口文件和輸出文件的路徑,因此,咱們須要在webpack.config.js中配置這兩個路徑:
// 導入處理路徑的模塊
    var path = require('path');

    // 導出一個配置對象,未來webpack在啓動的時候,會默認來查找webpack.config.js,並讀取這個文件中導出的配置對象,來進行打包處理
    module.exports = {
        entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
       
        output: { // 配置輸出選項
            path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
            filename: 'bundle.js' // 配置輸出的文件名
        },
        mode: 'development'
    }
複製代碼

注意:

  • 上面代碼中咱們設置了項目的入口文件的路徑,在此以前案例中的項目入口文件main.js並非在js目錄下的,這是咱們要手動將入口文件main.js移到js目錄下
  • 通過這一步的設置,每次修改main.js文件,只須要執行webpack命令便可從新打包
  • 可是在頁面中你會發現修改的main.js文件好像沒有效果,那是由於咱們在webpack.config.js指定了出口文件是:dist/bundle.js,因此咱們要在index.html中將以前引入的 打包編譯後的文件dist/main.js改成dist/bundle.js便可看到效果

這裏補充一個知識點:

node 的path模塊中 path.resolve()和path.join()的區別

1、path模塊的引入。
直接引用。node中自帶的模塊
const path = require('path');

2、path.join(path1,path2,path3.......)
做用:將路徑片斷使用特定的分隔符(window:\)鏈接起來造成路徑,並規範化生成的路徑。若任意一個路徑片斷類型錯誤,會報錯。
const path = require('path');
let myPath = path.join(__dirname,'/img/so');
let myPath2 = path.join(__dirname,'./img/so');
let myPath3=path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
 
 
console.log(__dirname);//__dirname,文件路徑 
console.log(myPath);    
console.log(myPath2);   
console.log(myPath3); 


3、path.resolve([from...],to)

做用:把一個路徑或路徑片斷的序列解析爲一個絕對路徑。至關於執行cd操做。

/被解析爲根目錄。

let myPath = path.resolve(__dirname,'/img/so');
let myPath2 = path.resolve(__dirname,'./img/so');
let myPath3=path.resolve('/foo/bar', './baz');
let myPath4=path.resolve('/foo/bar', '/tmp/file/');
 
console.log(__dirname);           
console.log(myPath);    
console.log(myPath2);   
console.log(myPath3);  
console.log(myPath4);
複製代碼

即便是咱們簡化了打包工具,可是每次修改了main.js,仍是要從新輸入命令webpack來進行打包,爲了解決這一麻煩,下面咱們裝一個插件來進行實時打包,每次修改後,自動進行打包,多好

九.實現webpack的實時打包構建

  1. 運行cnpm i webpack-dev-server --save-dev安裝到開發依賴

  2. 安裝完成以後,在命令行直接運行webpack-dev-server來進行打包,發現報錯,報錯內容爲:'webpack-dev-server' 不是內部或外部命令,也不是可運行的程序或批處理文件。

  3. 此時須要藉助於package.json文件中的指令,來進行運行webpack-dev-server命令,在scripts節點下新增"dev": "webpack-dev-server"指令

  4. 執行該條命令:npm run dev發現能夠進行實時打包,可是dist目錄下並無生成bundle.js文件,這是由於webpack-dev-server將打包好的文件放在了內存中,把bundle.js放在內存中的好處是:因爲須要實時打包編譯,因此放在內存中速度會很是快

  1. 這個時候訪問webpack-dev-server啓動的http://localhost:8080/網站,發現是一個文件夾的面板,須要點擊到src目錄下,才能打開咱們的index首頁,

  2. 此時引用不到bundle.js文件,須要修改index.html中script的src屬性爲:<script src="../bundle.js"></script>,由於bundle.js文件在內存中

  3. 爲了能在執行npm run dev訪問http://localhost:8080/的時候直接訪問到index首頁,修改dev指令爲"dev": "webpack-dev-server --contentBase src --open",指定啓動的根目錄

  4. 同時修改index頁面中script的src屬性爲<script src="bundle.js"> </script>

十.使用html-webpack-plugin插件配置啓動頁面

爲何要安裝這個插件:去掉index頁中對js文件的請求

因爲使用--contentBase指令的過程比較繁瑣,須要指定啓動的目錄,同時還須要修改index.html中script標籤的src屬性,因此推薦你們使用html-webpack-plugin插件配置啓動頁面.

  1. 運行cnpm i html-webpack-plugin --save-dev安裝到開發依賴
  2. 修改webpack.config.js配置文件以下:
// 導入處理路徑的模塊
    var path = require('path');
    // 導入自動生成HTMl文件的插件
    var htmlWebpackPlugin = require('html-webpack-plugin');

    module.exports = {
        entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
        output: { // 配置輸出選項
            path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
            filename: 'bundle.js' // 配置輸出的文件名
        },
        plugins:[ // 添加plugins節點配置插件
            new htmlWebpackPlugin({
                template:path.resolve(__dirname, 'src/index.html'),//模板路徑
                filename:'index.html'//自動生成的HTML文件的名稱
            })
        ]
    }
複製代碼
  1. 修改package.jsonscript節點中的dev指令以下:
"dev": "webpack-dev-server --open"
複製代碼
  1. 將index.html中script標籤引入的編譯後的文件註釋掉,由於html-webpack-plugin插件會自動把bundle.js注入到index.html頁面中!

好了,到了這一步,咱們在打開一個項目文件,啓動服務端,執行:npm run dev命令,便可自動打開index.html,每次修改入口文件,在保存以後變回自動打包,頁面自動刷新,下面繼續介紹,webpack是如何打包其餘類型的文件的

十一.實現自動打開瀏覽器、熱更新和配置瀏覽器的默認端口號

注意:熱更新在JS中表現的不明顯,能夠從一下子要講到的CSS身上進行介紹說明!

方式一:

  • 修改package.json的script節點以下,其中--open表示自動打開瀏覽器,--port 4321表示打開的端口號爲4321,--hot表示啓用瀏覽器熱更新:
"dev": "webpack-dev-server --hot --port 4321 --open"
複製代碼

方式二:

  1. 修改webpack.config.js文件,新增devServer節點以下:
devServer:{
        hot:true,
        open:true,
        port:4321
    }
複製代碼
  1. 在頭部引入webpack模塊:
var webpack = require('webpack');
複製代碼
  1. plugins節點下新增:
new webpack.HotModuleReplacementPlugin()
複製代碼

十二.使用webpack打包css文件

  1. 運行cnpm i style-loader css-loader --save-dev
  2. 修改webpack.config.js這個配置文件:
module: { // 用來配置第三方loader模塊的  
        rules: [ // 文件的匹配規則 
            { test: /\.css$/, use: ['style-loader', 'css-loader'] }//處理css文件的規則
        ]
    }
複製代碼
  1. 注意:use表示使用哪些模塊來處理test所匹配到的文件;use中相關loader模塊的調用順序是從後向前調用的;
  2. 將該css文件引入到入口文件(js文件)中,路徑實際爲主
import "./css/index.css"
複製代碼

十三.使用webpack打包less文件

index.less

ul{
  padding: 0;
  margin: 0;
}
複製代碼
  1. 運行cnpm i less-loader less -D
  2. 修改webpack.config.js這個配置文件:
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
複製代碼

十四.使用webpack打包sass文件

index.scss//注意後綴爲scss

html, body{
  margin: 0;
  padding: 0;

  li{
    font-size: 12px;
    line-height: 30px;
  }
}

複製代碼
  1. 運行cnpm i sass-loader node-sass --save-dev
  2. webpack.config.js中添加處理sass文件的loader模塊:
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
複製代碼

十五.使用webpack處理css中的路徑

  1. 運行cnpm i url-loader file-loader --save-dev
  2. webpack.config.js中添加處理url路徑的loader模塊:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }
複製代碼
  1. 能夠經過limit指定進行base64編碼的圖片大小;只有小於指定字節(byte)的圖片纔會進行base64編碼:
{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },
複製代碼

十六.使用babel處理高級JS語法

  1. 運行cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev安裝babel的相關loader包
  2. 運行cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev安裝babel轉換的語法
  3. webpack.config.js中添加相關loader模塊,其中須要注意的是,必定要把node_modules文件夾添加到排除項:
{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
複製代碼
  1. 在項目根目錄中添加.babelrc文件,並修改這個配置文件以下:
{
    "presets":["es2015", "stage-0"],
    "plugins":["transform-runtime"]
}
複製代碼
  1. 注意:語法插件babel-preset-es2015能夠更新爲babel-preset-env,它包含了全部的ES相關的語法;

後言:

以上就是webpack打包工具應用的案例了,這個案例也能夠做爲一個項目的基本打包模板,你們在學習這一塊內容的時候,要掌握一些基礎的知識,不然,遇到了報錯問題,可能就無從下手解決了,webpack還有其餘的一些難懂的知識點,建議你們看官方文檔

相關文章
相關標籤/搜索