switching to webpack -- 初探webpack

假設咱們如今有以下文件結構css

index.html
master.css
rotate.js

index.html 咱們就引入了剩餘兩個文件。如今,咱們想利用 webpack 來進行打包。把 css 和 js 放入一個文件中,這樣咱們在 index.html 中就只須要引入一個文件即可以了。html

index.html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>wp</title>
  <link rel="stylesheet" href="master.css">
  <script src="rotate.js" charset="utf-8" defer></script>
</head>

怎麼作呢?首先咱們建立一個入口文件 entry.js ,在這個文件中咱們把 css 和 js 引入,然後只須要在 index.html 只引入一個文件 entery.js 。在 entery.js 怎麼引入 js 和 css 呢?前端

index.html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>wp</title>
  <script src="bundle.js" charset="utf-8" defer></script>
</head>
//entry.js
require('./rotate.js');
require('./master.css');

先安裝 npm install webpack --save-dev 運行 webpack entry.js bundle.js 。報錯:構建 master.css 的任務失敗了。這是由於在 node 的模塊系統中,只有 js 文件可使用 require 語法引入,因此 css 引入就是失敗的。怎麼辦呢?在 webpack 中有一個東西專門處理除 js 之外文件的引入 -- loader工具。就像名字所表達的, loader 負責加載處理其它格式的文件, CoffeeScript、 JSX、 LESS、JSON 等等。若是你寫的是 SASS,一樣引入到 enter.js 後, index.html 是沒法識別的,而 loader 還能夠先把你寫好的 SASS 轉換成 css 而後再引入。這樣你就沒必要在寫好 SASS 後再經過 gulp 或 grunt 等工具把他們轉換成 css ,而後再用loader引入了。node

好了,怎麼寫呢,首先使用 npm 下載 css 和 style 的 loader。 npm install style-loader css-loader 而後在 entry.js 就能夠這樣引入css了。jquery

//entry.js
require('./rotate.js');
require('!style!css!./master.css');

運行 webpack entry.js bundle.js 構建成功,咱們刷新頁面發現, css、 js 都被引入了。ok, 因此當咱們有不少須要引入的文件時均可以先在entry.js中引入,而後在index.html中引入一個entry.js就能夠了。
這麼算下來, webpack只是把咱們本來須要在 head 中引入的文件放到了 entry.js 中引入而已,那它到底有什麼優點呢?webpack

正如咱們前面所說, webpack 能夠利用 loader 引入各類文件,咱們只須要下載相應的 loader 即可以實現這些步驟。這些都須要更詳細地配置,因此咱們如今對 webpack 任務進行配置新建一個 webpack.config.js 配置以下git

module.exports = {
  entry: '/entry.js', //全部入口文件
  output: {
    path: __dirname,
    filename: 'bundle.js' //自動生成的打包文件
  },

  module: {              //全部加載器都在一個module中
    loaders: [
      { test: /\.css$/,       //正則匹配
        loader: 'style!css',  //樣式和css加載器
        include: paths        //限制匹配路徑,不然會匹配全部符合test的文件,增長打包時間
      }
    ]
  }
}

配置好 webpack.config.js 後,咱們只須要輸入 webpack 就作到了咱們之前輸入 webpack entry.js bundle.js 同樣的效果。並且在 entry.js 中咱們對 css 的引用也能夠寫爲像引入 js 文件同樣再也不須要加 !style!css! 這樣的前綴了。es6

//entry.js
require('./rotate.js');
require('./master.css');

值得一提的是,若是咱們在 rotate.js 中還導入了另外一個 js 文件或模塊, webpack 也會把它引入。意思是說, webpack 不只只導入了 require 的文件,還能解析那些在 require 文件裏全部的依賴。例如,我在 rotate.js 中使用了 jquery ,我只須要在 rotate.js 中再 require('./jquery.js') 就能夠了。省心省力。github

上面咱們簡單瞭解了 webpack 在普通開發中用到的技巧,你會發現這些技巧利用其餘構建工具也能夠實現。也並無增長多少效率。是的,在簡單文件結構中,還體現不出 webpack 的優點。但在複雜的項目中文件層級嵌套很深,管理起來依賴會很是麻煩,對各類庫的引用層出不窮,而此時 webpack 帶來的這種模塊構建模式將會很是有用。咱們不須要手動計算每一個文件的依賴,使用時只須要 require 一下就 ok 了。web


上一節咱們從實際開發的小項目出發,瞭解了 webpack 帶來的一些變化。這一節咱們深刻挖掘 loader,看看 loader 究竟能爲咱們帶來什麼。

就如上節所瞭解的,在 webpack 中能夠像 nodejs 同樣以模塊的形式引入各種 js 文件,但在一個前端項目裏,不只僅有 js 文件,有多是 CoffeeScript、 JSX、 LESS、JSON、SCSS、JPG、PNG 這些文件利用 node 的模塊系統是沒法引入的,loader 就是來解決這類問題的--讓其它種類的文件像是 js 同樣被導入,這就須要各式各樣的 loader 了。 loader 本質上也是一個模塊,它的功能就是轉換各類資源爲 nodejs 中可導入的模塊 -- 把其餘資源搞成統一的模塊。

假設咱們如今的工做目錄以下

index.html
master.scss
rotate.js
entry.js

由於有 scss 文件的存在,html 沒法解析 scss 咱們須要對 scss 進行編譯。傳統的方法是使用 gulp 或 grunt 先對 master.scss 進行編譯壓縮,再被 index.html引入,而 loader 的存在即是簡化了這些步驟,當咱們能夠把 scss 文件以模塊的形式導入後,咱們即可以以模塊的形式對其進行編譯,就像在 gulp 中的 .pipe(sass()) 同樣,但這更符合流的思想,沒有中間的斷層 -- 咱們不須要dest文件儲存咱們編譯爲 css 的 scss 文件。文件仍是這三個文件,但通過 loader 便省去了不少鏈接工做。 ok ,下面開始。

首先咱們須要下載 sass 的 sass-loader, npm install sass-loader node-sass --save-dev , entry.js 中這樣寫

require('!style-loader!css-loader!sass-loader! ./master.scss');
require('./rotate.js')

咱們發現咱們不能像引入css同樣再在 entry.jsrequire(./scss) 了 ( sass-loader 文檔中沒有提出這種更簡潔的寫法)。在 webpack.config.js 中配置 sass-loader

{test: /\.scss$/, loader: [ 'style', 'css', 'sass' ]},

ok,執行 webpack ,打開 index.html 咱們發現 scss 中寫的樣式被成功解析了。就這麼簡單。

在 js 裏咱們使用了ES6語法,也須要被編譯爲ES5,怎麼辦呢?仍是loader。 babel-loader, npm install babel-loader babel-core babel-preset-es2015 --save-dev ,在 webpack.config.js 中配置

{  test: /\.js$/,
   exclude: /(node_modules|bower_components)/,
   loader: 'babel-loader',
   query: {
     presets: ['es2015']
   }
}

ok, scss 和 es6 都被編譯引入了。啥,你還須要壓縮?(loader的功能正如其名,主要是把資源搞成模塊同樣的) 壓縮、lint、拼接圖片等等這種活須要另外一個工具來完成-- plugins


這一節咱們一塊兒來探究 webpack 中的plugins ,它主要負責完成 loader 完成後的剩餘任務。 webpack 其實已經內置了一些插件,你們常見的如 uglifyjs 壓縮js文件,它是webpack內置的插件,咱們能夠不配置 plugins 而直接運行 webpack -p 來對 bundle.js 進行壓縮,也能夠先配置plugins再運行 webpack 執行壓縮。

如今,咱們在 webpack.config.js 文件中導入 webpack const webpack = require('webppack') 配置 plugins 選項。 執行 webpack 會發現文件大小被縮小了。

plugins: [
  new webpack.optimize.UglifyJsPlugin({
    compress: {
        warnings: false  //默認 true 在輸出臺輸出一些警告
    },
    mangle: true      //默認 true 在壓縮過程當中壓縮變量名
  })
]

基本的操做步驟就是這些,咱們從手邊的小項目開始,由之前的各類構建方式切換到了 webpack 模式。 工做流的思想更加明確了,相比 gulp 而言 webpack 也更加流暢。固然這只是一個簡單的開始,對於 模塊按需加載, 懶加載, 熱更新、發佈等等這些高級技巧還須要多多實踐才能體會。 相信隨着更多的實踐你對 「webpack 究竟給咱們帶來的什麼?」 會有本身更明確的答案。

學些資源:

webpack 中文簡介

webpack 官方插件列表

webpack 單頁面應用實戰

相關文章
相關標籤/搜索