基於webpack的模塊化構建

寫在前面

模塊化構建會讓項目的拓展性、代碼複用性和可維護性大大提高,初期可能會增加一些管理的工作量。但是對長遠來說絕對是值得的,一個良好的模塊化方案會讓維護工作變得輕鬆,這個好處項目越進展到後來越明顯。而且模塊化構建的框架和工具很多,RequireJSSeaJSGruntGulp等,這些雖然成熟穩定但並不是我們今天的主題,既然是採用react開發webApp,那麼模塊化當然是選webpack

webpack的優勢

1、支持CommonJs和AMD模塊,意思也就是我們基本可以無痛遷移舊項目
2、支持模塊加載器和插件機制,可對模塊靈活定製。babel-loader更是有效支持ES6。
3、可以通過配置,打包成多個文件。有效利用瀏覽器的緩存功能提升性能。
4、將樣式文件和圖片等靜態資源也可視爲模塊進行打包。配合loader加載器,可以支持sass,less等CSS預處理器。
5、內置有source map,即使打包在一起依舊方便調試。

這裏寫圖片描述

webpack入門

首先介紹webpack的配置文件webpack.config.js

  var webpack=require('webpack');

  module.exports={
    entry:[
      'webpack/hot/onlu-dev-server',
      './js/app.js'
    ],
    output:{
      path:'./build',
      filename:'bundle.js'
    },
    module:{
      leaders:[
        {test:/\.js?$/,leaders:['react-hot','babel'],exclude:/node_modules/},
        {test:/\.js$/,exclude:/node_modules/,loader:/'babel-loader'},
        {test:/\.css$/,loader:'style!css'},
        {test:/\.less/,loader:'style-loader!css-loader!less-loader'}
      ],
    },
    resolve:{
      extensions:['','.js','.json']
    },
    plugins:[
      new webpack.NoErrorsPlugin()
    ]
  }

webpack.config.js 文件通常放在項目的根目錄裏,它本身也是一個標準的Common.js規範的模塊。在導出的配置對象中有幾個關鍵的參數:

entry

entry可以說個字符串或數組或者是對象。當entry是個字符串的時候用來定義入口文件。

  entry:'./js/main.js'

entry是個數組的時候,裏面同樣包含入口文件,另外一個參數可以用來配置webpack提供的一個靜態資源服務器如webpack-dev-server,它會監控項目中每一個文件的變化,實時進行構建,並且自動刷新頁面,

  entry:[
    'webpack/hot/only-dev-server',
    './js/app.js'
  ]

entry是一個對象的時候,我們可以將不同的文件構建成不同的文件,按需使用,比如:

  entry:{
    hello:'./js/hello.js',
    form:'./js/form.js'
  }

output

output是個對象,用戶定義構建後的文件的輸出。其中包含pathfilename:

  output:{
    path:'./build',
    filename:'bundle.js'
  }

當我們在entry中定義構建多個文件時,filename可以對應地更改爲[name].bundle.js

module

關於模塊的加載相關,我們就定義在module.loaders中,這裏通過正則表達式去匹配不同後綴的文件名。然後它們定義不同的加載器,比如說給less文件定義三個串聯的加載器(用!連接)

moudle:{
  loaders:[
    {test:/\.js?$/,loaders:['react-hot','babel'],exclude:/node_modules/},
    {test:/\.js$/,exclude:/node_modules/,loader:'babel-loader'},
    {test:/\.css$/,loader:'style!css'},
    {test:/\.less$/,loader:'style-loader!css-loader!less-loader'}
  ]
}

除此之外,我們還可以用來定義 pngjpg這樣的圖片資源在小於10k時自動處理爲base64圖片的加載器。

  {test:/\.(png|jpg)$/,loader:'url-loader?limit=10000'}

cssless還有圖片添加了loader之後,我們不僅可以像在node中那樣require進來了。就像這樣:

require('./bootstrap.css');
require('./myapp.less');
var img=document.createElement('img');
img.src=require('./glyph.png');

注意: 這樣require進來的文件會內聯到 [name].bundle.js中。如果我們需要把保留 require寫法又想把css文件單獨拿出來,可以使用extract-text-webpack-plugin插件。

$ npm install extract-text-webpack-plugin --save-dev
var ExtractTextPlugin =require('extract-text-webpack-plugin');
module.exports={
  plugins:[
    new ExtractTextPlugin("[name].css");
  ]   
}

在上面的示例代碼中配置的第一個loaderreact-hot的加載器,它可以實現react組件的熱替換,我們已經在entry參數中配置了webpack/hot/only-dev-server,所以我們只要啓動 webpack時開啓-hot參數既可以使用react-hot-loader了,在package.json中這樣定義:

  "script":{
    "start":"webpack-dev-server --hot --progress --colors",
    "build":"webpack --progress --colors"
  }

resolve

webpack在構建包的時候會按目錄的文件進行查找,resolve屬性中的extensions數組中用於配置程序可有自動替換哪些文件的後綴,比如:

  resolve:{
    extensions:['','.js','.json']
  }

然後我們想要加載一個js文件時,只要require('common')就可以加載common.js文件了。

plugin

webpack提供了豐富的組件來滿足不同的需求,當然如果你足夠牛也可以自己編寫插件。這裏介紹比較常用的 NoErrorsPlugin,它能跳過編譯時出錯的代碼並記錄,是編譯後運行的包不會發生錯誤。

  plugins:[
    new webpack.NoErrorsPlugin()
  ]

externals

當我們想在項目中require一些其他的類庫或者API,而又不想讓這些類庫的源碼構建到運行時的文件中,就可以通過配置externals參數來解決這個問題,比如jQuery類庫

  externals:{
    "jquery":'jQuery'
  }

這樣我們就可以放心在項目中使用這些API了

  var jQuery=require('jquery');

context

當我們在require一個模塊的時候,如果require中包含變量,想這樣:

  require("./mods/"+name+".js");

那麼在編譯的時候是不能知道具體的模塊的。但這個時候webpack也會幫我們分析:
1. 分析目錄:'./mods';
2. 提取正則表達式:/^.*\.js$/;
於是這個時候爲了更好地配合webpack進行編譯,我們可以給它指明路徑,像在cake-webpack-config中所做的那樣:

  var currentBase=progress.cwd();
  var context=abcOptions.options.context?abcOptions.options.context:path.isAbsolute(entryDir)?enentryDir:path.join(currentBase,entryDir);

讓webpack和gulp強強聯手

webpackgulp並不矛盾,甚至一起使用會得到最大化的效益。大致的思路是這樣:
使用webpack進行assets編譯,使用gulp的流快速對其他資源進行打包。

關於工具的定位

webpack的定位是module bundler,作爲模塊化工具,它的競爭對手其實是browserify,而不是gulp

功能和使用方式上的不同

webpack 提供了一些非常使用的功能,像我們之前用到的那些,如圖片的處理、resolve的處理、分開構建等,配置相當簡單。gulp想要使用這些功能的時候我們可以在webpack裏先配置好,做到強強聯手!


寫在後面

@參考 推酷 webpack前端模塊加載工具
@參考 博客園 前端模塊化工具-webpack
@我的技術博客 Jafeney.com

發佈了95 篇原創文章 · 獲贊 202 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章