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

5分鐘打造簡(jiǎn)易高效的webpack常用配置

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

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

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

首先我們明確一下需求:

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

1.打包調(diào)試

第一步,我們?cè)谀繕?biāo)文件夾下安裝webpack(假設(shè)已有 package.json )

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

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

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

 

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

第二步,我們?cè)谀繕?biāo)文件夾下新建 webpack.config.js

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

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

接下來(lái)我們只需要在 modules 字段下把這些 loader 加進(jìn)去:

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的配置項(xiàng),解析es6
        }
      },
      {
        test:/\.less$/,
        exclude:/node_modules/,
        loader:'style-loader!css-loader!less-loader'//順序?yàn)閺挠蚁蜃?
      }
    ]
  },
}

大功告成!

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

 

之后我們?cè)?index.html 中引入 main.0.js 文件,再打開(kāi) index.html 就可以看到效果了。

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

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ù)傳入了兩個(gè)參數(shù) vendor 和 manifest ,以及我們?cè)?entry 也加入了新的入口 moment 。 moment 是常用的時(shí)間處理的第三方庫(kù),我們可以通過(guò) npm i moment --save-dev 進(jìn)行安裝。而 entry 處的 vendor 將成為 output 字段 filename 中 [name] 的值,也就是說(shuō)將打包出 main.x.js 和 vendor.x.js 兩個(gè)文件, main.x.js 文件將保存我們的業(yè)務(wù)代碼, vendor.x.js 將保存 moment 的代碼,這樣我們將公共代碼和業(yè)務(wù)代碼進(jìn)行了初步分離。

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

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.

大致的意思就是說(shuō),webpack每次編譯時(shí)運(yùn)行的代碼會(huì)影響到 hash 值的變化,當(dāng)只有一個(gè)打包文件時(shí)這部分代碼會(huì)塞進(jìn)去,當(dāng)有多個(gè)打包文件時(shí),這部分代碼會(huì)進(jìn)入公共的 vendor 。所以解決辦法是使用 manifest 字段把這部分代碼從 vendor 中作為一個(gè)公共模塊抽出來(lái),從而不會(huì)影響 vendor 。

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

 

當(dāng)我們?cè)龠M(jìn)行打包時(shí),發(fā)現(xiàn)又會(huì)多出了新的 main.x.js 等文件,打包三次就會(huì)出現(xiàn)三個(gè) main.x.js 文件,此時(shí)該怎么辦呢?我們可以使用 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'],//要?jiǎng)h除的文件目錄匹配
      {
        root:__dirname,
        verbose:true,
        dry:false
      }
    ),

這樣我們每次在打包新的代碼時(shí),舊文件就會(huì)刪除,不會(huì)再出現(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 部分,同時(shí)我們?nèi)コ?comments 部分( comments 為@license等注釋,是可觀的壓縮空間)。再次在終端輸入打包命令,可見(jiàn)js打包后的體積有令人滿意的減小。

4.熱替換

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

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

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

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

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

tips:

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

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

5.運(yùn)行

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

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

在 webpack.config.js 中引入:

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

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

 

以后我們?cè)龠M(jìn)行調(diào)試時(shí),以本文為例,則需要打開(kāi) localhost:8080/public/index.html ,因?yàn)槊看蝫ebpack的 HtmlWebpackPlugin 都會(huì)把新的js文件加入到這個(gè)html文件內(nèi)。在開(kā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
      }
    })
  ]
}

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

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

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

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

相關(guān)文章

最新評(píng)論