webpack學習!lession3

加載 CSS

爲了從 JavaScript 模塊中 import 一個 CSS 文件,你須要在 module 配置中 安裝並添加 style-loader 和 css-loadercss

npm install --save-dev style-loader css-loader

webpack.config.jshtml

const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
+   module: {
+     rules: [
+       {
+         test: /\.css$/,
+         use: [
+           'style-loader',
+           'css-loader'
+         ]
+       }
+     ]
+   }
  };

webpack 根據正則表達式,來肯定應該查找哪些文件,並將其提供給指定的 loader。在這種狀況下,以 .css 結尾的所有文件,都將被提供給 style-loader 和 css-loadernode

這使你能夠在依賴於此樣式的文件中 import './style.css'。如今,當該模塊運行時,含有 CSS 字符串的 <style> 標籤,將被插入到 html 文件的 <head> 中。webpack

咱們嘗試一下,經過在項目中添加一個新的 style.css 文件,並將其導入到咱們的 index.js 中:git

projectgithub

webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- style.css
    |- index.js
  |- /node_modules

src/style.cssweb

.hello {
  color: red;
}

src/index.jsajax

import _ from 'lodash';
+ import './style.css';

  function component() {
    var element = document.createElement('div');

    // lodash 是由當前 script 腳本 import 導入進來的
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.classList.add('hello');

    return element;
  }

  document.body.appendChild(component());

如今運行構建命令:正則表達式

npm run build

Hash: 9a3abfc96300ef87880f
Version: webpack 2.6.1
Time: 834ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  560 kB       0  [emitted]  [big]  main
   [0] ./~/lodash/lodash.js 540 kB {0} [built]
   [1] ./src/style.css 1 kB {0} [built]
   [2] ./~/css-loader!./src/style.css 191 bytes {0} [built]
   [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [4] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [5] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [6] (webpack)/buildin/global.js 509 bytes {0} [built]
   [7] (webpack)/buildin/module.js 517 bytes {0} [built]
   [8] ./src/index.js 351 bytes {0} [built]

再次在瀏覽器中打開 index.html,你應該看到 Hello webpack 如今的樣式是紅色。要查看 webpack 作了什麼,請檢查頁面(不要查看頁面源代碼,由於它不會顯示結果),並查看頁面的 head 標籤。它應該包含咱們在 index.js 中導入的 style 塊元素。npm

請注意,在多數狀況下,你也能夠進行 CSS 分離,以便在生產環境中節省加載時間。最重要的是,現有的 loader 能夠支持任何你能夠想到的 CSS 處理器風格 - postcsssass 和 less 等。

加載圖片

假想,如今咱們正在下載 CSS,可是咱們的背景和圖標這些圖片,要如何處理呢?使用 file-loader,咱們能夠輕鬆地將這些內容混合到 CSS 中:

npm install --save-dev file-loader

webpack.config.js

const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
+       {
+         test: /\.(png|svg|jpg|gif)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };

如今,當你 import MyImage from './my-image.png',該圖像將被處理並添加到 output 目錄,_而且_ MyImage 變量將包含該圖像在處理後的最終 url。當使用 css-loader 時,如上所示,你的 CSS 中的 url('./my-image.png') 會使用相似的過程去處理。loader 會識別這是一個本地文件,並將 './my-image.png' 路徑,替換爲輸出目錄中圖像的最終路徑。html-loader 以相同的方式處理 <img src="./my-image.png" />

咱們向項目添加一個圖像,而後看它是如何工做的,你可使用任何你喜歡的圖像:

project

webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/index.js

import _ from 'lodash';
  import './style.css';
+ import Icon from './icon.png';

  function component() {
    var element = document.createElement('div');

    // Lodash,如今由此腳本導入
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

+   // 將圖像添加到咱們現有的 div。
+   var myIcon = new Image();
+   myIcon.src = Icon;
+
+   element.appendChild(myIcon);

    return element;
  }

  document.body.appendChild(component());

src/style.css

.hello {
    color: red;
+   background: url('./icon.png');
  }

讓咱們從新構建,並再次打開 index.html 文件:

npm run build

Hash: 854865050ea3c1c7f237
Version: webpack 2.6.1
Time: 895ms
                               Asset     Size  Chunks                    Chunk Names
5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
                           bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 242 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [6] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [7] (webpack)/buildin/global.js 509 bytes {0} [built]
   [8] (webpack)/buildin/module.js 517 bytes {0} [built]
   [9] ./src/index.js 503 bytes {0} [built]

若是一切順利,和 Hello webpack 文本旁邊的 img 元素同樣,如今看到的圖標是重複的背景圖片。若是你檢查此元素,你將看到實際的文件名已更改成像 5c999da72346a995e7e2718865d019c8.png 同樣。這意味着 webpack 在 src 文件夾中找到咱們的文件,併成功處理過它!

合乎邏輯下一步是,壓縮和優化你的圖像。查看 image-webpack-loader 和 url-loader,以瞭解更多關於若是加強加載處理圖片功能。

加載字體

那麼,像字體這樣的其餘資源如何處理呢?file-loader 和 url-loader 能夠接收並加載任何文件,而後將其輸出到構建目錄。這就是說,咱們能夠將它們用於任何類型的文件,包括字體。讓咱們更新 webpack.config.js 來處理字體文件:

webpack.config.js

const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(woff|woff2|eot|ttf|otf)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };

在項目中添加一些字體文件:

project

webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- my-font.woff
+   |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

經過配置好 loader 並將字體文件放在合適的地方,你能夠經過一個 @font-face 聲明引入。本地的 url(...) 指令會被 webpack 獲取處理,就像它處理圖片資源同樣:

src/style.css

+ @font-face {
+   font-family: 'MyFont';
+   src:  url('./my-font.woff2') format('woff2'),
+         url('./my-font.woff') format('woff');
+   font-weight: 600;
+   font-style: normal;
+ }

  .hello {
    color: red;
+   font-family: 'MyFont';
    background: url('./icon.png');
  }

如今讓咱們從新構建來看看 webpack 是否處理了咱們的字體:

npm run build

Hash: b4aef94169088c79ed1c
Version: webpack 2.6.1
Time: 775ms
                                Asset     Size  Chunks                    Chunk Names
 5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
11aebbbd407bcc3ab1e914ca0238d24d.woff   221 kB          [emitted]
                            bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 420 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./src/MyFont.woff 83 bytes {0} [built]
   [6] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [7] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [8] (webpack)/buildin/global.js 509 bytes {0} [built]
   [9] (webpack)/buildin/module.js 517 bytes {0} [built]
  [10] ./src/index.js 503 bytes {0} [built]

從新打開 index.html 看看咱們的 Hello webpack 文本顯示是否換上了新的字體。若是一切順利,你應該能看到變化。

加載數據

此外,能夠加載的有用資源還有數據,如 JSON 文件,CSV、TSV 和 XML。相似於 NodeJS,JSON 支持其實是內置的,也就是說 import Data from './data.json' 默認將正常運行。要導入 CSV、TSV 和 XML,你可使用 csv-loader 和 xml-loader。讓咱們處理這三類文件:

npm install --save-dev csv-loader xml-loader

webpack.config.js

const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(csv|tsv)$/,
+         use: [
+           'csv-loader'
+         ]
+       },
+       {
+         test: /\.xml$/,
+         use: [
+           'xml-loader'
+         ]
+       }
      ]
    }
  };

給你的項目添加一些數據文件:

project

webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- data.xml
    |- my-font.woff
    |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/data.xml

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Mary</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Call Cindy on Tuesday</body>
</note>

如今,你能夠 import 這四種類型的數據(JSON, CSV, TSV, XML)中的任何一種,所導入的 Data 變量將包含可直接使用的已解析 JSON:

src/index.js

import _ from 'lodash';
  import './style.css';
  import Icon from './icon.png';
+ import Data from './data.xml';

  function component() {
    var element = document.createElement('div');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

    // Add the image to our existing div.
    var myIcon = new Image();
    myIcon.src = Icon;

    element.appendChild(myIcon);

+   console.log(Data);

    return element;
  }

  document.body.appendChild(component());

當你打開 index.html 並查看開發者工具中的控制檯,你應該可以看到你導入的數據被打印在了上面!

在使用 d3 等工具來實現某些數據可視化時,預加載數據會很是有用。咱們能夠不用再發送 ajax 請求,而後於運行時解析數據,而是在構建過程當中將其提早載入並打包到模塊中,以便瀏覽器加載模塊後,能夠當即從模塊中解析數據。

全局資源

上述全部內容中最出色之處是,以這種方式加載資源,你能夠以更直觀的方式將模塊和資源組合在一塊兒。無需依賴於含有所有資源的 /assets 目錄,而是將資源與代碼組合在一塊兒。例如,相似這樣的結構會很是有用:

- |- /assets
+ |– /components
+ |  |– /my-component
+ |  |  |– index.jsx
+ |  |  |– index.css
+ |  |  |– icon.svg
+ |  |  |– img.png

這種配置方式會使你的代碼更具有可移植性,由於現有的統一放置的方式會形成全部資源緊密耦合在一塊兒。假如你想在另外一個項目中使用 /my-component,只需將其複製或移動到 /components 目錄下。只要你已經安裝了任何擴展依賴(external dependencies),而且你已經在配置中定義過相同的 loader,那麼項目應該可以良好運行。

可是,假如你沒法使用新的開發方式,只能被固定於舊有開發方式,或者你有一些在多個組件(視圖、模板、模塊等)之間共享的資源。你仍然能夠將這些資源存儲在公共目錄(base directory)中,甚至配合使用 alias 來使它們更方便 import 導入

回退處理

對於接下來的指南,咱們無需使用本指南中全部用到的資源,所以咱們會進行一些清理工做,以便爲下一部分指南中的管理輸出章節作好準備:

project

webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
-   |- data.xml
-   |- my-font.woff
-   |- my-font.woff2
-   |- icon.png
-   |- style.css
    |- index.js
  |- /node_modules

webpack.config.js

const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
-   module: {
-     rules: [
-       {
-         test: /\.css$/,
-         use: [
-           'style-loader',
-           'css-loader'
-         ]
-       },
-       {
-         test: /\.(png|svg|jpg|gif)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(woff|woff2|eot|ttf|otf)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(csv|tsv)$/,
-         use: [
-           'csv-loader'
-         ]
-       },
-       {
-         test: /\.xml$/,
-         use: [
-           'xml-loader'
-         ]
-       }
-     ]
-   }
  };

src/index.js

import _ from 'lodash';
- import './style.css';
- import Icon from './icon.png';
- import Data from './data.xml';
-
  function component() {
    var element = document.createElement('div');
-
-   // Lodash,如今經過 script 標籤導入
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
-   element.classList.add('hello');
-
-   // 將圖像添加到咱們已有的 div 中。
-   var myIcon = new Image();
-   myIcon.src = Icon;
-
-   element.appendChild(myIcon);
-
-   console.log(Data);

    return element;
  }

  document.body.appendChild(component());
相關文章
相關標籤/搜索