[webpack3.8.1]Guides-3-Asset Management(資源管理)

Asset Management

If you've been following the guides from the start, you will now have a small project that shows "Hello webpack". Now let's try to incorporate some other assets, like images, to see how they can be handled.css

       若是你一直跟着咱們的Guide來操做,你如今應該有一個叫"Hello webpack"的項目了。如今,讓咱們試着把它和其餘資源合併在一塊兒,就好比圖片一類的東西。html

Prior to webpack, front-end developers would use tools like grunt and gulp to process these assets and move them from their /src folder into their /dist or /build directory. The same idea was used for JavaScript modules, but tools like webpack will dynamically bundle all dependencies (creating what's known as a dependency graph). This is great because every module now explicitly states its dependencies and we'll avoid bundling modules that aren't in use.前端

       在webpack問世以前,前端的開發者們都是用grunt 啊,gulp 這樣的工具來處理和移動資源,他們將資源從他們的/src目錄移動到/dist或者/build目錄。JavaScript模塊使用了相同的想法,可是像webpack這樣的工具會動態地捆綁全部的依賴關係(建立所謂的依賴關係圖)這很好,由於如今每一個模塊都明確地聲明瞭它的依賴關係,咱們將避免捆綁未使用的模塊。node

One of the coolest webpack features is that you can also include any other type of file, besides JavaScript, for which there is a loader. This means that the same benefits listed above for JavaScript (e.g. explicit dependencies) can be applied to everything used in building a website or web app. Let's start with CSS, as you may already be familiar with that setup.webpack

       你知道webpack最酷的事情之一是什麼嗎?他不只能打包JS,還能夠打包任何其它類型的文件,只要你設定好了加載器。這意味着,上面列出的對於打包JavaScript的好處(例如明確的依賴關係)也能夠應用於構建網站或Web應用程序的全部內容。讓咱們從CSS開始,由於您可能已經熟悉了這個設置。web

Setup (起步)

Let's make a minor change to our project before we get started:ajax

       在咱們開始以前,讓咱們給咱們的項目作一個微小的改變吧!(* ̄︶ ̄)正則表達式

dist/index.html

<html>
    <head>
-    <title>Getting Started</title>
+    <title>Asset Management</title>
    </head>
    <body>
      <script src="./bundle.js"></script>
    </body>
  </html>

P.S.:這裏再解釋一次,代碼行左邊的+和-表示相比於原來的文件,增長了哪一行,減小了哪一行。express

Loading CSS (加載CSS)

In order to import a CSS file from within a JavaScript module, you need to install and add the style-loader and css-loader to your module configuration:npm

       爲了讓JavaScript模塊能夠獲取CSS文件,須要安裝style-loadercss-loader,並添加它們到您的module配置中:

npm install --save-dev style-loader css-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'
+         ]
+       }
+     ]
+   }
  };

P.S.:這裏我想爲基礎薄弱的朋友們解釋一下test: /\.css$/,這個是在寫正則表達式呢,它的意思是「以.css結尾」若是你想大體瞭解一下這個東西而不是很深刻地去研究,我推薦菜鳥教程-正則表達式

webpack uses a regular expression to determine which files it should look for and serve to a specific loader. In this case any file that ends with .css will be served to the style-loader and the css-loader.

       webpack使用正則表達式來肯定應該查找哪些文件並將其提供給特定的加載程序。在這種狀況下,任何以文件結尾的文件.css將被提供給style-loadercss-loader

This enables you to import './style.css' into the file that depends on that styling. Now, when that module is run, a <style> tag with the stringified css will be inserted into the <head> of your html file.

       這使您可以import './style.css'進入依賴於該樣式的文件。如今,當這個模塊運行時,<style>帶有字符串化CSS的標籤將被插入到<head>你的html文件中。

Let's try it out by adding a new style.css file to our project and import it in our index.js:

       讓咱們經過添加一個新的style.css文件到咱們的項目中,並將其導入到咱們項目中的index.js

project

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

src/style.css

.hello {
  color: red;
}

src/index.js

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

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

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

    return element;
  }

  document.body.appendChild(component());

Now run your build command:

       來吧,執行編譯命令:

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]

Open up index.html in your browser again and you should see that Hello webpack is now styled in red. To see what webpack did, inspect the page (don't view the page source, as it won't show you the result) and look at the page's head tags. It should contain our style block that we imported in index.js.

       在你的瀏覽器中再一次打開index.html吧,而後你應該能看見"Hello webpack"如今已經變成紅色的了。若是你想知道webpack都幹了些啥,實現了這種效果,請監聽這個頁面的加載吧,看一看頁面的頭部標籤都寫了些啥。確定包含了咱們的樣式塊在咱們導入進index.js的時候。

Note that you can also split your CSS for better load times in production. On top of that, loaders exist for pretty much any flavor of CSS you can think of -- postcss, sass, and less to name a few.

       注意,你還能夠拆分您的CSS文件以得到更好的加載時間。最重要的是,不管你對於CSS的口味有多刁,都存在相應的加載器——就像postcsssass,還有其它幾種,都能加載的。

Loading Images (加載圖片)

So now we're pulling in our CSS, but what about our images like backgrounds and icons? Using the file-loader we can easily incorporate those in our system as well:

       那麼好,如今咱們正在搞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'
+         ]
+       }
      ]
    }
  };

Now, when you import MyImage from './my-image.png', that image will be processed and added to your output directory and the MyImage variable will contain the final url of that image after processing. When using the css-loader, as shown above, a similar process will occur for url('./my-image.png') within your CSS. The loader will recognize this is a local file, and replace the './my-image.png' path with the final path to the image in your output directory. The html-loader handles <img src="./my-image.png" /> in the same manner.

       如今,當你須要從./my-image.png導入MyImage ,那張圖片將會被處理而後添加到你的輸出目錄中,而且MyImage 變量將會包含一個該圖片處理後的url常量。當咱們使用CSS加載器的時候,好比把./my-image.png打包到你的CSS文件裏,就像上面展示出來的那樣,是一個跟上面圖片加載差很少的過程。加載器會發現這是一個本地文件,而後把./my-image.png路徑替換爲output目錄中映像的最終路徑。HTML加載器也會相同的方式來處理<img src="./my-image.png" />

P.S.:這裏說一個小知識點,URL不是URI,這是兩個抽象概念,不少人混爲一談。URL指的是統一資源定位符,而URI指的是統一資源標識符。URL是URI的子集。

Let's add an image to our project and see how this works, you can use any image you like:

       讓咱們給咱們的項目添加一張圖片,而後看看這是怎麼工做的吧,你可使用任意一張你喜歡的圖片哦。

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, 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);

    return element;
  }

  document.body.appendChild(component());

src/style.css

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

Let's create a new build and open up the index.html file again:

       讓咱們再一次編譯項目,而後打開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]

If all went well, you should now see your icon as a repeating background, as well as an img element beside our Hello webpack text. If you inspect this element, you'll see that the actual filename has changed to something like 5c999da72346a995e7e2718865d019c8.png. This means webpack found our file in the src folder and processed it!

       若是一切順利,你如今應該看到你的圖標鋪滿了背景,並且一個圖片元素就在你的文本「Hello webpack」的一邊。若是你監聽了這個元素,你將會看到真實的圖片名稱已經被更換了,更換成相似於5c999da72346a995e7e2718865d019c8.png的名字。這就意味着,webpack已經在src目錄下找到了咱們的文件並且處理了它。

Loading Fonts (加載字體)

So what about other assets like fonts? The file and url loaders will take any file you load through them and output it to your build directory. This means we can use them for any kind of file, including fonts. Let's update our webpack.config.js to handle font files:

       那麼,其它的資源呢?就好比說字體?文件加載器和url加載器將會處理任何你想處理的文件並輸出它們到你的編譯路徑。這就意味着咱們可使用它們來處理各類各樣的文件,固然包含字體文件。讓咱們升級一下咱們的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

With the loader configured and fonts in place, you can use incorporate them via an @font-face declaration. The local url(...) directive will be picked up by webpack just as it was with the image:

       就在加載器配置和字體的地方,你合併他們經過使用@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');
  }

Now run a new build and let's see if webpack handled our fonts:

       如今,讓咱們運行一個新的編譯,來看看咱們的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]

Open up index.html again and see if our Hello webpack text has changed to the new font. If all is well, you should see the changes.

       再一次打開咱們的index.html,咱們將看到咱們的文本換成了新的字體,若是一切進展順利,你就應當可以看到這改變。

Loading Data (加載數據)

Another useful asset that can be loaded is data, like JSON files, CSVs, TSVs, and XML. Support for JSON is actually built-in, similar to NodeJS, meaning import Data from './data.json' will work by default. To import CSVs, TSVs, and XML you could use the csv-loader and xml-loader. Let's handle loading all three:

       另外,有用的資源還多是須要加載的數據,就比方說JSON文件、CSV文件、TSV文件、XML文件……對JSON的支持其實是內置的,相似於NodeJS,就是說從./data.json導入數據是會被默認執行的。要導入CSVTSVXML,您可使用csv-loaderxml-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'
+         ]
+       }
      ]
    }
  };

Add some data files to your project:

       還有一些屬於這個項目的數據文件:

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>

Now you can import any one of those four types of data (JSON, CSV, TSV, XML) and the Data variable you import it to will contain parsed JSON for easy consumption:

       如今,你能夠導入JSON、CSV、TSV、XML中任意一種數據文件,而且數據將導入到變量幷包含已解析的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());

When you open index.html and look at your console in your developer tools, you should be able to see your imported data being logged to the console!

       當你打開index.html的時候,請觀察你的開發工具的控制檯輸出,你應該可以看到導入的數據已經被打印到控制檯上了。

This can be especially helpful when implementing some sort of data visualization using a tool like d3. Instead of making an ajax request and parsing the data at runtime you can load it into your module during the build process so that the parsed data is ready to go as soon as the module hits the browser.

       這在使用像D3這樣的工具來進行數據可視化的時候是很是有用的。你能夠在編譯進行的期間將數據加載到你的模塊裏,而不是使用一個ajax請求而後解析數據,這樣,只要模塊一運行在瀏覽器中,解析後的數據就已經準備好了。

Global Assets (全局資源)

The coolest part of everything mentioned above, is that loading assets this way allows you to group modules and assets together in a more intuitive way. Instead of relying on a global /assets directory that contains everything, you can group assets with the code that uses them. For example, a structure like this can be very useful:

       上面提到的全部的事情中最酷的部分是,經過這種方式加載資源可讓您以更直觀的方式將模塊和資源組織在一塊兒。根據資源和代碼之間的使用關係來對資源進行分組,而不是將它們包含在一個全局的資源文件夾下。例如,像這樣的結構可能很是有用:

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

This setup makes your code a lot more portable as everything that is closely coupled now lives together. Let's say you want to use /my-component in another project, simply copy or move it into the /components directory over there. As long as you've installed any external dependencies and your configuration has the same loaders defined, you should be good to go.

       這個設置使得你的代碼更加輕便,由於如今全部緊密耦合的東西都在一塊兒了。假設您想讓/my-component在另外一個項目中使用,只需將其複製或移動到/components那裏的目錄便可。只要你已經安裝了任何外部的依賴關係,而且你的配置已經定義了相同的loader

However, let's say you're locked into your old ways or you have some assets that are shared between multiple components (views, templates, modules, etc.). It's still possible to store these assets in a base directory and even use aliasing to make them easier to import.

       然而,假設您已經被舊的方式束縛,或者您擁有一些在多個組件(視圖,模板,模塊等)之間共享的資源。仍然能夠將這些資源存儲在基本目錄中,甚至可使用別名來使它們更容易導入。

Wrapping up (收尾)

For the next guides we won't be using all the different assets we've used in this guide, so let's do some cleanup so we're prepared for the next piece of the guides Output Management:

       對於下一個指南,咱們將不會使用咱們在本指南中使用過的全部不一樣資源,因此咱們來作一些清理工做,以便爲下一部分指南作好準備。輸出管理:

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, 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());
相關文章
相關標籤/搜索