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

5分鐘打造簡易高效的webpack常用配置

 更新時間:2017年07月04日 16:14:20   作者:ssssyoki  
這篇文章主要介紹了5分鐘打造簡易高效的webpack配置,詳細的介紹了打包調(diào)試、提取公共代碼、壓縮、熱替換等配置,有興趣的可以了解一下

webpack給前端開發(fā)帶來了毋庸置疑的改變,它把JS,圖片,css都作為模塊處理,同時具有開發(fā)便捷,自動化,兼容AMD寫法等等諸多無須贅述的優(yōu)點,更令人稱道的是其插件社區(qū)非常強大,對于不同的業(yè)務(wù)需求和技術(shù)需求社區(qū)都有大量插件可供使用。

凡事都具有兩面性,許多人說:前端開發(fā)再也不能只需新建HTML文件和JS文件就可以開始寫代碼了。webpack帶來了更高級更規(guī)范的前端開發(fā)模式,由于其本身也在不斷完善中,從1到2再到發(fā)布不久的webpack3,頻繁的修改給新手帶來了許多困惑。而且網(wǎng)絡(luò)上各種教程魚目混雜,經(jīng)常出現(xiàn)別人的教程代碼copy下來在自己的環(huán)境卻跑不通的蛋疼問題。就拿 devtool 配置項來說,官方文檔提供了多達7種的配置方法,連react核心團隊成員Pete Hunt都在twitter上調(diào)侃:我分不清webpack的許多配置之間的區(qū)別。所以今天我們拋開那些琳瑯滿目的插件和令人煩躁的配置項,筆者和大家一起5分鐘從零搭建一個簡易高效的webpack開發(fā)環(huán)境。

首先我們明確一下需求:

  1. 打包調(diào)試
  2. 提取公共代碼
  3. 壓縮
  4. 熱替換

1.打包調(diào)試

第一步,我們在目標文件夾下安裝webpack(假設(shè)已有 package.json )

npm i webpack@ -g 
cnpm i webpack@ --save-dev 

(這里推薦大家安裝穩(wěn)定的2.x版本)

項目結(jié)構(gòu)如圖:

 

我們將編寫的js代碼和樣式文件放置在 app 文件夾內(nèi)(正常項目開發(fā)需要 js 文件和 less文件更規(guī)范的組織文件結(jié)構(gòu),此處僅為演示方便)。

第二步,我們在目標文件夾下新建 webpack.config.js

module.exports = {
  entry:{
    main:__dirname + '/app/main.js',
  },
  output:{
    path:__dirname + '/public',
    filename:'[name].[id].js',//此格式寫法后續(xù)會提到為什么
    publicPath:'/public/'
  }
}

我們已經(jīng)完成了webpack最基礎(chǔ)的部分:添加了文件的輸入和輸出。入口是 app 文件夾內(nèi)的 main.js 文件,出口為 public 文件夾。接下來我們來處理各種文件的解析,就是大名鼎鼎的 loader 的舞臺了。假設(shè)我們使用 es6 和 less 開發(fā),那么我們需要:

npm i babel-loader babel-core babel-preset-es2015 babel-preset-stage-0 --save-dev

npm i less less-loader css-loader style-loader --save-dev

接下來我們只需要在 modules 字段下把這些 loader 加進去:

module.exports = {
  devtool:'cheap-module-eval-source-map',//多種選擇,選擇最適合自己的
  entry:{
    main:__dirname + '/app/main.js',
  },
  output:{
    path:__dirname + '/public',
    filename:'[name].[id].js',
    publicPath:'/public/'
  },
  module:{
    loaders:[
      {
        test:/\.js$/, //解析文件類型
        exclude:/node_modules/, //排除node_modules文件
        loader:'babel-loader', //使用哪種loader解析
        query:{
          presets:['es2015','stage-0']//loader的配置項,解析es6
        }
      },
      {
        test:/\.less$/,
        exclude:/node_modules/,
        loader:'style-loader!css-loader!less-loader'//順序為從右向左
      }
    ]
  },
}

大功告成!

如果你在全局安裝有webpack的話,可以在終端敲入webpack并回車,幾秒鐘后, main.js 文件已經(jīng)在 public 打包出來了!

 

之后我們在 index.html 中引入 main.0.js 文件,再打開 index.html 就可以看到效果了。

以上步驟,我們已經(jīng)實現(xiàn)了文件的打包調(diào)試,但是現(xiàn)在有個問題擺在我們面前:第三方庫代碼和業(yè)務(wù)代碼打包到了同一個文件 main.0.js 內(nèi),每次更新代碼都要更新整個文件。那么接下來我們對代碼進行拆分。

2.提取公共代碼

引入 CommonsChunkPlugin 插件,在 webpack.config.js 添加如下內(nèi)容:

module.exports = {
  devtool:'cheap-module-eval-source-map',
  entry:{
    main:__dirname + '/app/main.js',
    vendor:'moment'
  },
  output:{
    path:__dirname + '/public',
    filename:'[name].[id].js',
    publicPath:'/public/'
  },
  module:{
    loaders:[
      {
        test:/\.js$/,
        exclude:/node_modules/,
        loader:'babel-loader',
        query:{
          presets:['es2015','stage-0']
        }
      },
      {
        test:/\.less$/,
        exclude:/node_modules/,
        loader:'style-loader!css-loader!less-loader'
      }
    ]
  },
  plugins:[
      new webpack.optimize.CommonsChunkPlugin({
        names:['vendor','manifest']
     })
   ]
}

我們看到向插件的構(gòu)造函數(shù)傳入了兩個參數(shù) vendor 和 manifest ,以及我們在 entry 也加入了新的入口 moment 。 moment 是常用的時間處理的第三方庫,我們可以通過 npm i moment --save-dev 進行安裝。而 entry 處的 vendor 將成為 output 字段 filename 中 [name] 的值,也就是說將打包出 main.x.js 和 vendor.x.js 兩個文件, main.x.js 文件將保存我們的業(yè)務(wù)代碼, vendor.x.js 將保存 moment 的代碼,這樣我們將公共代碼和業(yè)務(wù)代碼進行了初步分離。

在新添加的 CommonmChunkPlugin 插件中,我們添加了 manifest 值,這是為什么呢?如果你不添加這個值,你在打包時會發(fā)現(xiàn), main.x.js 有更新, vendor.x.js 還是有更新,并未真正實現(xiàn)"分離"。官方文檔對此的解釋是:

The issue here is that on every build, webpack generates some webpack runtime code, which helps webpack do it's job. When there is a single bundle, the runtime code resides in it. But when multiple bundles are generated, the runtime code is extracted into the common module, here the vendor file.

大致的意思就是說,webpack每次編譯時運行的代碼會影響到 hash 值的變化,當只有一個打包文件時這部分代碼會塞進去,當有多個打包文件時,這部分代碼會進入公共的 vendor 。所以解決辦法是使用 manifest 字段把這部分代碼從 vendor 中作為一個公共模塊抽出來,從而不會影響 vendor 。

將以上的配置寫入 webpack.config.js ,運行webpack命令,我們發(fā)現(xiàn)業(yè)務(wù)代碼和公共庫代碼成功分離,改寫 main.1.js 文件的內(nèi)容,再次打包,發(fā)現(xiàn) vendor 文件并沒有變化,成功!

 

當我們再進行打包時,發(fā)現(xiàn)又會多出了新的 main.x.js 等文件,打包三次就會出現(xiàn)三個 main.x.js 文件,此時該怎么辦呢?我們可以使用 clean-webpack-plugin 插件:

npm i clean-webpack-plugin --save-dev

然后在 webpack.config.js 中引入:

var CleanWebpackPlugin = require('clean-webpack-plugin');
  new CleanWebpackPlugin(
      ['public/main.*.js','public/manifest.*.js'],//要刪除的文件目錄匹配
      {
        root:__dirname,
        verbose:true,
        dry:false
      }
    ),

這樣我們每次在打包新的代碼時,舊文件就會刪除,不會再出現(xiàn)同一份文件存在多份的情況。

3.壓縮

在webpack中,圖片,css,js等等其他資源皆可壓縮,本文僅以壓縮js為例。

安裝插件:

npm i uglifyjs-webpack-plugin --save-dev

在 webpack.config.js 中引入:

var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
new UglifyJsPlugin({
  beautify:true,
  exclude:['/node_modules/'],
  compress:{
    warnings:false
  },
  output:{
    comments:false
  }
})

我們指定了壓縮的方法,排除了不需要壓縮的 node_modules 部分,同時我們?nèi)コ?comments 部分( comments 為@license等注釋,是可觀的壓縮空間)。再次在終端輸入打包命令,可見js打包后的體積有令人滿意的減小。

4.熱替換

webpack總是繞不開熱替換的話題。熱替換的功能配置和原理是一大話題,三天三夜也說不完,也并非本文重點,本文只提供簡易高效的配置方法。

熱替換存在兩種使用方式, cli 和 node 。 cli 方式無需添加新的熱替換插件,且無需在入口處添加 webpack-dev-server 等入口,故本文采用 cli 使用方式。

在 webpack.config.js 中添加 devServer 字段,加入如下代碼:

devServer:{
  inline:true,
  hot:true
},

保存后運行 webpack-dev-server --inline --hot --progress ,再修改下 main.less 文件的樣式,會發(fā)現(xiàn)瀏覽器并沒有刷新,但頁面已經(jīng)發(fā)生了變化,我們的熱替換功能也成功加入了!

tips:

在實際項目打包時,可以將 filename 字段的值換為 [name].[chunkhash].js ,其中 [chunkhash] 為webpack每次打包后給每個模塊的標識值,這個值每次打包后都會更換。為什么在此處我們使用 [id] 呢,因為 chunkhash 與熱替換存在沖突,終端會有報錯,那么使用 id 可以算作一個解決方案。這就引申出另一話題,我們可以使用兩套webpack配置分別用于生產(chǎn)環(huán)境和開發(fā)環(huán)境,通過webpack指定config來進行打包。例如我們在開發(fā)環(huán)境使用 id ,在生產(chǎn)環(huán)境去掉熱替換并使用 hash 的方式。而且,一些壓縮插件也沒必要在開發(fā)環(huán)境過度使用,兩套配置能讓webpack發(fā)揮最大的威力。

另外, chunkhash 和 hash 有區(qū)別, chunkhash 顧名思義是模塊的標識,而 hash 是webpack每次編譯的標識值,不同的資源如js和css存在 chunkhash 解耦的問題,此處不進行過多討論。

5.運行

我們知道,每次打包后,都會有新的 main.x.js 文件生成,其hash值每次打包后都會發(fā)生變化,難道我們的 index.html 文件需要每次打包后都手動修改 main.x.js 的路徑嗎?還好社區(qū)提供了 html-webpack-plugin 插件,可以在已有html模板的條件下自動為我們生成帶有最新代碼的html文件:

npm i html-webpack-plugin --save-dev

在 webpack.config.js 中引入:

var HtmlWebpackPlugin = require('html-webpack-plugin');
new HtmlWebpackPlugin({
  title:'demo',
  template:'index.html'
}),

在終端運行打包命令,我們看到 public 文件夾下生成了新的 index.html 文件:

 

以后我們再進行調(diào)試時,以本文為例,則需要打開 localhost:8080/public/index.html ,因為每次webpack的 HtmlWebpackPlugin 都會把新的js文件加入到這個html文件內(nèi)。在開發(fā)全部完成后,我們可以將js路徑寫死,添加到原有的 index.html 文件中。

以下是我們 webpack.config.js 全部的配置;

var webpack = require('webpack');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  devtool:'cheap-module-eval-source-map',
  entry:{
    main:__dirname + '/app/main.js',
    vendor:'moment'
  },
  output:{
    path:__dirname + '/public',
    filename:'[name].[id].js',
    publicPath:'/public/'
  },
  devServer:{
    inline:true,
    hot:true
  },
  module:{
    loaders:[
      {
        test:/\.js$/,
        exclude:/node_modules/,
        loader:'babel-loader',
        query:{
          presets:['es2015','stage-0']
        }
      },
      {
        test:/\.less$/,
        exclude:/node_modules/,
        loader:'style-loader!css-loader!less-loader'
      }
    ]
  },
  plugins:[
    new CleanWebpackPlugin(
      ['public/main.*.js','public/manifest.*.js'],
      {
        root:__dirname,
        verbose:true,
        dry:false
      }
    ),
    new webpack.optimize.CommonsChunkPlugin({
      names:['vendor','manifest']
    }),
    new HtmlWebpackPlugin({
      title:'demo',
      template:'index.html'
    }),
    new UglifyJsPlugin({
      beautify:true,
      exclude:['/node_modules/'],
      compress:{
        warnings:false
      },
      output:{
        comments:false
      }
    })
  ]
}

整個項目,我們在 app 文件下的 main.js 內(nèi)寫業(yè)務(wù)代碼, main.less 寫樣式,在 public/index.html 下使用熱替換進行調(diào)試,打包后的壓縮文件在 public 文件夾下,并且對業(yè)務(wù)代碼,第三方代碼進行了清晰地區(qū)分。

使用這份webpack配置,我們實現(xiàn)了:

  1. 工程的打包調(diào)試
  2. 公共代碼提取,提高開發(fā)效率
  3. 資源壓縮
  4. 熱替換

這份配置麻雀雖小,五臟俱全。本文還有許多不完善之處,比如一些插件的使用方法,原理沒有與大家講清楚,但webpack實在太龐大了,一個插件的使用方法和原理都可以寫上千字的文章了,學(xué)習(xí)不可淺嘗輒止,但也不能太鉆牛角尖,與大家共勉~

相關(guān)文章

最新評論