webpack入門

一.爲何要學習webpackcss

如今的前端網頁功能豐富,特別是SPA(single page web application 單頁應用)技術流行後,JavaScript的複雜度增長和須要一大堆依賴包,還須要解決SCSS,Less……新增樣式的擴展寫法的編譯工做。因此現代化的前端已經徹底依賴於WebPack的輔助了。html

如今最流行的三個前端框架,能夠說和webpack已經緊密相連前端

React.js+WebPackvue

Vue.js+WebPacknode

AngluarJS+WebPackreact

能夠看出,不管前端走哪條線,都要有很強的Webpack知識jquery

二. webpack是什麼webpack

其實說白了,webpack就是模塊打包機。es6

webpack看來,一切皆模塊。Webpack所作的事情就是:分析項目結構,找到js模塊以及其餘一些瀏覽器不能直接運行的語言,sass typeScript等,將其轉換打包成合適的格式。共瀏覽器使用。在3.0之後,webpack還有了優化項目的功能web

第一點:打包webpack多個js文件打包成一個文件。減小服務器壓力和下載帶寬。減小請求次數和壓縮js css img(對原始圖片進行壓縮處理、調整圖片的分辨率和尺寸;服務器開啓Gzip壓縮功能壓縮頁面文本)

第二點:轉換,可以把less,scss等擴展性語言,以及各類類型的js文件都轉換成標準的能被瀏覽器識別的語言

第三點:優化Webpack3.0之後,擔任着優化和提高性能的責任(好比第三方類庫的分離,提取公共代碼等)

總結起來,就是打包/轉換/優化。話很少說,咱們一塊兒來看下怎麼使用webpack。若是有不當的地方,歡迎你們糾正,一塊兒學習。

三. webpack基礎應用

1.安裝

webpack安裝的兩種方式

  1. 全局安裝:npm  install -g webpack

  2.本地安裝: npm install --save-dev webpack(@version)

webpack 版本查看 :webpack -v

全局安裝就是安裝到全局目錄下(經過 npm config set prefix 「目錄路徑」 來設置。經過 npm config get prefix 來獲取當前設置的目錄

可是對於大多數項目咱們推薦安裝到本地,緣由是可防止不一樣項目依賴不一樣版本的 Webpack 而致使衝突。

安裝好以後,咱們就能夠在項目進行webpack的配置了

2. webpack基本配置-webpack.config.js

module.exports={

       entry:{},  // 入口文件的配置項

       output:{}, // 出口文件的配置項

       module:{}, // 模塊:例如解讀CSS,圖片如何轉換,壓縮

       plugins:[],  // 插件,用於生產模版和各項功能

       devServer:{}  // 配置webpack開發服務功能

}

單入口:

module.exports={

       entry:{

    entry1: './src/entry.js

       },  

       output: {
     path: path.resolve(__dirname, 'dist'),

        filename: ‘bundle.js'
       }

}

多入口:

output.path對應一個絕對路徑,path.resolve主要是用於設置絕對路徑,而且輸出文件夾建議是要使用絕對路徑的.

module.exports={

       entry1:{

                    entry1: './src/entry.js',  

                     entry2: './src/entry.js

        },  

      output: {

                  path: path.resolve(__dirname, 'dist'),

                  filename: ‘[name].js

      },

       ……

}

3. 所見即所得之熱更新-- devServer

devServer: {
    //設置基本目錄結構,使用絕對目錄
    contentBase:path.resolve(__dirname,‘dist’),
    //服務器的IP地址,可使用IP也可使用localhost
    host:‘localhost’,
    //服務端壓縮是否開啓(自行學習)
    compress:true,
    //配置服務端口號
    port:1717
}

 

npm run server  啓動後,它是有一種監控機制的(也叫watch)。它能夠監控到咱們修改源碼,並當即在瀏覽器裏給咱們更新。

Webpack打包以後,運行npm run server 發現只有js 可是能夠說明咱們的js打包成功了,可是沒有html,新建html,而且將html打包址dist文件夾。這須要藉助於一個插件html-webpack-plugin

4. Html打包-- html-webpack-plugin

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

使用:

const htmlPlugin = require('html-webpack-plugin')

plugins: [
 new htmlPlugin({
        minify: { removeAttributeQuotes: true },
        hash: true,
        template: './src/index.html'
    })
],

 

藉助於插件-- html-webpack-plugin,能夠將咱們的html打包址dist文件夾,在使用以前咱們須要先npm安裝

1.require引入插件

2.由於它是一款插件因此咱們須要在plugins中進行這個插件的相關配置。

在配置的時候,須要new一個對象,傳入一些參數,minify:對html文件進行壓縮,removeAttributeQuotes去掉屬性的雙引號,hash爲true是在js後面增長一段hash值,主要是爲了不瀏覽器緩存的,template打包的模版文件

執行webpack,查看發現script有後綴,而且屬性雙引號去掉了。

經過這個插件咱們不只能將html文件打包到dist文件夾還能壓縮html,那麼咱們的js文件怎麼壓縮呢?

5. Js壓縮--uglifyjs-webpack-plugin

若是沒有webpack或gulp的話,可能咱們還須要找一個壓縮軟件或者在線進行壓縮,而在webpack中使用默認已經集成的uglifyjs-webpack-plugin插件輕鬆實現js代碼的壓縮,因爲已經集成,不須要再次安裝。用法:

const uglify = require('uglifyjs-webpack-plugin'); 

plugins:[

        new uglify()

 ],

執行webpack打包,npm run server發現報錯了,爲何呢?這就涉及到了生產環境和開發環境的區別

由於咱們在開發環境是不須要壓縮js的,可是在生產環境中須要,因此uglifyjs適用於生產環境下的,

因此若是咱們在開發環境中作了生產環境作的事情,就會報錯了

 

6. Css文件打包-- style-loader,css-loader

安裝:npm install --save-dev css-loader style-loader

使用:

      module:{       

       rules: [{            

  test: /\.css$/,        

      use: [ ‘style-loader’, ‘css-loader] 

        }]   

 }, 

Css-loader: css文件打包到js中,經常配合style-loader一塊兒使用,將css文件打包並插入到頁面中

Style-loader: 使用<style>css-loader內部樣式注入到HTML頁面

 

Loaders是Webpack最重要的功能之一,這也是Webpack如此盛行的緣由。經過使用不一樣的Loader,從而對不一樣的文件格式進行特定處理。

好比說能夠把SASS文件的寫法轉換成CSS,而不在使用其餘轉換工具;把ES6或者ES7的代碼,轉換成大多瀏覽器兼容的JS代碼;把React中的JSX轉換成JavaScript代碼。須要注意的是:全部的Loaders都須要在npm中單獨進行安裝,並在webpack.config.js裏進行配置。Loaders的配置型簡單梳理:

  test:用於匹配處理文件的擴展名的表達式,這個選項是必須進行配置的;

  use:loader名稱,就是你要使用模塊的名稱,這個選項也必須進行配置,不然報錯;

  include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不須要處理的文件(文件夾)(可選);

  query:爲loaders提供額外的設置選項(可選)

7.Css中的圖片處理-- url-loader

css中添加背景圖,執行webpack,圖片路徑錯誤

安裝:npm install --save-dev file-loader url-loader

使用:{
    test: /\.(png|jpg|gif|jpeg|bmp)/i,
    use: [{
        loader: 'url-loader',
        options: {
            limit: 500000
        }
    }]
}

test:/\.(png|jpg|gif)/是匹配圖片文件後綴名稱

use:是指定使用的loader和loader的配置參數

limit:是把小於500000B的文件打成Base64的格式,寫入JS

 

url-loader會將引入的圖片編碼,生成dataURl。DataURI是一種提供讓外置資源的直接內嵌在頁面中的方案。至關於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。固然,若是圖片較大,編碼會消耗性能。所以url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。File-loader能夠解析項目中的url引入(不只限於css),根據咱們的配置,將圖片拷貝到相應的路徑,而且修改打包後文件的引用路徑,使之指向正確的文件。

四. webpack優化

8. Css分離--extract-text-webpack-plugin

步驟:

1.安裝 npm install --save-dev extract-text-webpack-plugin

2. require引入const extractTextPlugin = require("extract-text-webpack-plugin")

3.Plugins設置: new extractTextPlugin("/css/index.css")

4. 修改css-loader{

              test: /\.css$/,

              use: extractTextPlugin.extract({

                fallback: "style-loader",

                use: "css-loader"

              })

            }

8.Css分離致使圖片路徑錯誤-- publicPath

publicPath:是在webpack.config.js文件的output選項中,主要做用就是處理靜態文件路徑的。

webpack.config.js中聲明對象
var website ={    

publicPath:http://127.0.0.1:9090/

}

Output配置

output:{           

  path:path.resolve(__dirname,'dist'), 

filename:'[name].js',      

  publicPath:website.publicPath    

}

publickPath是用來存放靜態文件的,它的值是咱們的本機ip或者devServer配置的IP和端口

9. img標籤添加圖片-- html-withimg-loader

1)在img標籤中直接引入圖片,執行wbbpack命令 —-- 報錯

安裝:npm install --save  html-withimg-loader

使用:Webpack.config.js

{
    test: /\.(htm|html)$/i,
    use: ['html-withimg-loader']
}

2)將圖片打包至image文件夾

options: {
    limit: 80000,
    outputPath: 'images/'
},

10.消除未使用的CSS --- PurifyCSS

安裝:npm i -D purifycss-webpack purify-css

使用:

        1)const PurifyCSSPlugin = require("purifycss-webpack")

        2)配置plugins

       new PurifyCSSPlugin({

         paths: glob.sync(path.join(__dirname, 'src/*.html')),

         })

注意:

1. purifycss-webpack 安裝依賴於purify-css,因此須要都安裝

2.這裏咱們用到了glob,glob是node中的模塊,引入glob主要是用來根據某些規則匹配文件的

3.必須要配合extract-text-webpack-plugin(css分離)插件使用

purifycss-webpack 依賴於 purify-css

paths,主要是需找html模板,purifycss根據這個配置會遍歷你的文件,查找哪些css被使用了

Glob:由於咱們須要同步檢查html模板,因此咱們須要引入node的glob對象使用。在webpack.config.js文件頭部引入glob

 

11. Less文件的打包和分離-- less-loader

即:將less轉換成css文件進行打包和分離(同css文件分離)

安裝less npm install –save-dev less

使用

{
    test: /\.less$/,
    use: extractTextPlugin.extract({
        fallback: "style-loader",
        use: ["css-loader", "less-loader"]
    })
}

對於less文件的打包和分離和css文件也是幾乎同樣,只是多了把less轉換成css這一步,下載好less-loader 以後就能夠了。

webpack的強大除了能夠轉換less sass以外還可使用babel轉換es6 es7 jsx等爲普通的js

 

12支持babel

 

安裝:npm install --save-dev babel-core babel-loader babel-preset- env 

使用: webpack.config.js配置

{
    test: /\.(jsx|js)$/,
    use: {
    loader: babel-loader’,
    options: {  // 選項
         presets: [  // 渲染器
        env", "react"]}
    },
   exclude: /node_modules/
}

注意:後期隨着項目的增大可能會有不少渲染器,這是這麼寫的話可讀性不太好了,咱們能夠將選項寫在.babelrc文件中。

.webpack.config.js

{
    test: /\.(jsx|js)$/,
    use: {
    loader: ‘babel-loader
    },
   exclude: /node_modules/
}

.babelrc

{
  "presets": [
    "react",
    」env"
  ]
}

 

11. 抽離第三方類庫

 

Webpack.config.js

entry:{    

entry:'./src/entry.js',    

jquery:'jquery',   

vue:'vue

'},

new webpack.optimize.CommonsChunkPlugin({

name:[‘jquery’,‘vue’],

filename:"assets/js/[name].js",  

minChunks:2

}),

 

 

12. 提取公共代碼--CommonsChunkPlugin

 

步驟:

 

1.將全部頁面都依賴的庫好比:vue react react-dom等提取到一個單獨的文件,通常叫作base.js(基礎運行環境)

 

2.剔除各個頁面中的base.js以後的代碼,再找出它們以來的公共部分的代碼,放到common.js

 

3.將各個頁面生成單獨的文件,這些文件將不包含base.js,common.js中的部分,只包含個頁面單獨須要的部分代碼

 

具體實現須要藉助於Webpack 內置的用於提取多個 Chunk 中公共部分的插件 CommonsChunkPlugin

 

 

 

大型網站一般會由多個頁面組成,沒個頁面都是一個獨立的單頁應用。可是因爲全部頁面採用的都是相同的技術棧,可能就會致使有不少重複的代碼。若是每一個頁面的代碼都把這些公共的部分包含進去,會形成一些問題。

 

1)相同資源重複加載,浪費用戶流量和服務器成本;2)頁面須要加載的資源太大,致使頁面首屏加載緩慢,影響用戶體驗

 

那麼若是咱們能將公共的代碼提取出來,那麼用戶在訪問其中一個網頁的時候,頁面的公共代碼文件就已經被瀏覽器緩存起來,用戶再訪問其餘頁面的時候,公共代碼不會從新加載而是從緩存中獲取。如此,雖然首屏訪問得不到優化,可是後續頁面速度大大提高,而且減小了網絡流量和服務器成本。那麼怎麼提取公共代碼呢???

 

1.將全部頁面都依賴的庫好比:vue react react-dom等提取到一個單獨的文件,通常叫作base.js(基礎運行環境)

 

2.剔除各個頁面中的base.js以後的代碼,再找出它們以來的公共部分的代碼,放到common.js

 

3.將各個頁面生成單獨的文件,這些文件將不包含base.js,common.js中的部分,只包含個頁面單獨須要的部分代碼

 

 

 

在線上文件中,對靜態文件的文件名都附加根據文件內容計算出的hash值,好比base_123a.js,以長期緩存,只要不升級基礎庫的版本,base的內容就不會變化,hash就不會更新,緩存也不會更新,每次更新代碼common.js和js會因文件內容變化而致使hash值被更新。

 

每次發佈瀏覽器都會使用被緩存的 base.js 文件,而不用去從新下載 base.js 文件。 因爲 base.js 一般會很大,這對提高網頁加速速度能起到很大的效果。

 

const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
new CommonsChunkPlugin({ 

 

chunks: [‘a’, ‘b’], // 從哪些 Chunk 中提取,默認從全部已知chunk獲取

 

name: 'common’ // 提取出的公共部分造成一個新的 Chunk

 

 })

 

require('webpack/lib/optimize/CommonsChunkPlugin');
new CommonsChunkPlugin({ 

 

chunks: [‘a’, ‘b’], // 從哪些 Chunk 中提取,默認從全部已知chunk獲取

 

name: 'common’ // 提取出的公共部分造成一個新的 Chunk

 

 })

 

以上是將a,b的公共代碼提取到了common中,接下來咱們還須要從common中,提取出基礎運行庫。

 

須要如下操做:

 

1)首先須要在項目中寫一個base.js來描述項目因此來的模塊,好比:

 

// 全部頁面都依賴的基礎庫

 

 import 'react';

 

 import 'react-dom';

 

 // 全部頁面都使用的樣式

 

 import './base.css';

 

2)再修改webpack

 

module.exports = {

 

entry: { 

 

base: './base.js' 

 

},

 

 };

 

 

 

new CommonsChunkPlugin({ 

 

// 從 common 和 base 兩個現成的 Chunk 中提取公共的部分 

 

chunks: ['common', 'base'], // 把公共的部分放到 base 中 name: 'base' 

 

})

 

 

 

<script src="base.js"></script> 

 

<script src="common.js"></script> 

 

<script src="a.js"></script>

 

13.打包後如何調試

 

主要有如下幾種方式:

 

1)source-map:生成獨立map文件,包含行列信息(信息最詳細完整)

 

2)cheap-module-source-map:生成獨立map文件,只包含行信息

 

3)eval-source-map:js文件內生成sourcemap,包含行列信息

 

4)cheap-module-eval-source-map:就是文件內生成sourcemap,只包含行信息

 

注意:1)source-map模式下會輸出質量最高最詳細的source Map ,可是會形成構建速度緩慢,在開發過程當中若是頻繁修改,會增長等待時間;

 

2)source Map會被暴漏出去,因此在生產環境下不建議使用source-map;

 

3)建議在開發環境下使用cheap-module-eval-source-map或者eval-source-map,開發環境下使用hidden-source-map,可生成最詳細的source Map,但不會暴漏源碼

相關文章
相關標籤/搜索