webpack的學習(7) ------- css-loader, style-loader的使用。

通常我們撰寫網頁一定會用上css來做美化的效果,但是在webpack中它本身只認的懂javascript files !那css要怎麼辦呢?-----這就要仰賴我們loader來幫我們處理 css, jpg .....等這些其他的靜態檔案囉!

CSS-Loader:

首先這邊我們會先介紹 webpack 上最多人用的 css-loader!他本身目的就是幫我們把css file透過@import 或是url()的方式載入到 Javascript 內,這樣webpack就可以認得css。其更多的詳細設定可以參考 css-loader的手冊。


Style-Loader:

當我們用了css-loader之後其實在browser那邊並不認得,所以需要一個可以將載入到Javascript內的css內容轉成browser看得懂的css 語法!這個任務就是Style-Loader在做的事情,否則只用css-loader 會發現頁面其實沒有真的去執行 css 裡面的設定。更多有關Style-loader的設定可以參考style-loader的手冊。


安裝CSS-Loader 與Style-Loader

當然首先我們要先安裝這兩個loader啦!透過npm 就可以很簡單的把這兩個loader裝起來啦!

~/mywebpack $  npm install  --save-dev  css-loader   style-loader

這邊因為這兩個loader只是開發的時候會用到,所以用 --save-dev的參數。


建立css 檔案:

接著我們在app這個資料夾下面建立一個名為 ' index.css' 的檔案來撰寫css內容。所以我們的專案結構就變成如下所示:

mywebpack/
|------------- app/
|                     |--------- index.css
|                     |--------- index.js
|
|-------------- node_modules/
|
|-------------- index.html
|-------------- package.json
|-------------- webpack.config.js

接著我們在index.css 內寫入下面的css 內容。
body{
  color: red;
}

上面程式碼就是讓我們的index.html的body的文字變成紅色,這樣就初步完成我們css的code。

設定webpack.config.js :

在我們原本的webpack.config.js內要加入關於loader的設定,告訴webpack 當看到副檔名是.css的時候請交給style-loadercss-loader來幫我們處理。在之前plugins的後面我們加上loader的設定。

/* ....... 
......之前的設定
*/
plugins: [                 // 之前設定chunk的內容
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'common.js'
    })
  ],       // 不要忘記加逗號
  // 我們主要的設定 css loader and style-loader
  module: {
    rules: [{
      test: /\.css$/,            // 遇到.css結尾的檔案
      use: ['style-loader', 'css-loader']       // 使用style-loader 與 css-loader來處理。
    }]
  }

載入index.css 

以往我們在網頁要引用css 檔案都是在html裡面使用<link>來引入,在這邊我們可以透過import的方式在index會用到的javascript內(也就是index.js) 直接把需要用到的css import進來。

開啟index.js在最上方加入import './index.css' 如下:

// ES6 feature. 從 jquery import $
import $ from 'jquery';

// 加入 css 檔         
import './index.css';  // <----我們主要引入css的設定

這樣子就完成了載入css的動作了。

這邊的重點就是 " css-loader" 會幫我們用 import的方式載入css檔案,但是對於browser那邊並不懂javascript裡面關於css的設定,因此style-loader會幫我們將載入的css轉到html內並且自動使用<style>來注入。

設定好了之後使用之前的$ npm run dev 我們就可以執行看看結果如何!
應該就會發現網頁上面的字全都變成紅色的了!



在這邊我們打開開發管理員(ctrl+shift+i) 可以看到在<head>那邊 style-loader 已經自動幫我們對html 注入 css的設定了。



不過在這邊官方說此方法有個缺點就是沒辦法利用browser的非同步與平行處理來載入css,整個頁面必須等到javascript bundle都載入完畢才會去套用css的內容。因此建議可以使用ExtractTextWebpackPlugin 將css分開bundle。

ExtractTextWebpackPlugin:

這個plugin主要就是把上述css必須inline到javascript的這個動作改成將css檔案獨立chunk成 style.css 這個檔案。而且就算你有多個css檔案,最後只會產出style.css這個檔案。
當然你會想說如果你有很多css檔案而且還不小的話會因為與javascript bundle平行載入提高瀏覽效率。

好處就是:

  1. 瀏覽更快。
  2. css會被browser cache住。
  3. css檔案可以被平行處理。
  4. 可以用sourceMap(這個目前我只知道除錯會用到 ><)。
  5. 使用更少的style tag在html上面
缺點就是:

  1. 需要更多的http request。
  2. 較長的compiler時間。
  3. 沒有hot module可以使用。
  4. .....等

安裝 ExtractTextWebpackPlugin:


很簡單只要 $ npm install --save-dev  extract-text-webpack-plugin 就可以安裝完畢。

修改webpack.config.js

1. 宣告:

首先要先把 ExtractTextWebpackPlugin   require進來。所以在開頭處module.exports外面加入
var ExtractTextPlugin = require('extract-text-webpack-plugin')
const path = require('path')    // nodejs core module
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')     // 1 <---這行就是要宣告ExtractTextPlugin

module.exports = {
  devServer: {
    contentBase: path.join(__dirname, '/'),
    compress: true,
    port: 9000,
.......
.......


2. plugins :

接著在 module.export內的plugins那邊new ExtractTextPlugin('style.css') 如下
plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'common.js'
    }),                      // 別忘了加逗點
    new ExtractTextPlugin('style.css'),       // 2. <--- 這行就是我們要加的
  ],

3. module:

最後在module那邊把原先的 use: ['style-loader',  'css-loader']  拿掉 改成如下
module: {
    rules: [{
      test: /\.css$/,
      // use: ['style-loader', 'css-loader']        // <----這邊我們註解掉
      use: ExtractTextPlugin.extract({              // <---- 新增的部份
        use: 'css-loader',
      })
    }]
  }

下面是整個設定的程式碼:
const path = require('path')    // nodejs core module
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  devServer: {
    contentBase: path.join(__dirname, '/'),
    compress: true,
    port: 9000,
    inline: true
  },
 entry: {
    app: ["./app/index.js"],
    vendor: ["jquery"]
  },
 output: {
  path: path.resolve(__dirname, 'dist'),
  filename: 'bundle.js',
    publicPath: 'dist',
 },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'common.js'
    }),
    new ExtractTextPlugin('style.css'),
  ],
  // css loader and style-loader
  module: {
    rules: [{
      test: /\.css$/,
      // use: ['style-loader', 'css-loader']
      use: ExtractTextPlugin.extract({
        use: 'css-loader',
      })
    }]
  }
}

4. 修改index.html:

由於我們把css chunk成一個名為" style.css"的檔案,所以要在index.html內將css用一般引入css的方式引入。

<html>
  <head>
    <title>webpack 2 demo</title>
    <link href="dist/style.css" rel="stylesheet">   <!-- 這是我們要加的 -->
  </head>
  <body>
    <script src='dist/common.js'></script>
    <script src='dist/bundle.js'></script>
  </body>
</html>

這樣就完成我們需要的程式碼了。回到頁面就可以看看是否有正確執行我們的css囉!


在瀏覽器開出“開發者工具”(shift+ctrl+i)可以看到在head那邊有把style.css載入並且頁面的字體顏色也變成紅色的了!

                                                       --------------待續
 Ref:

留言