webpack 靜態資源管理

garynan發表於2019-03-14

webpack 靜態資源管理

GitHub 學習 Demo。

對於 js 資源,基於JavaScript模組,webpack 將動態捆綁所有依賴項(建立所謂的依賴圖)。 這很好,因為現在每個模組都明確宣告瞭它的依賴關係,這樣可以避免捆綁未使用的模組。

webpack 的 loader 可以給專案的靜態資源帶來同樣的功能。
以配置 css 資源為起點,來展開 webpack 對靜態資源的配置。

載入 CSS 資源

修改一下之前的專案:

# dist/index.html

  <!doctype html>
  <html>
    <head>
-    <title>Getting Started</title>
+    <title>Asset Management</title>
    </head>
    <body>
-     <script src="./main.js"></script>
+     <script src="./bundle.js"></script>
    </body>
  </html>
  
# webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
-     filename: 'main.js',
+     filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };
Loadi
複製程式碼

配置 loader

  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使用正規表示式來確定它應該查詢哪些檔案並提供給特定的載入器。 在這種情況下,任何以.css結尾的檔案都將被提供給 style-loadercss-loader

這使您可以將./style.css匯入到依賴於該樣式的檔案中。 現在,當執行bundle.js時,會將對應的 css 通過<style>標籤將插入到html檔案的<head>中。

安裝依賴

npm install --save-dev style-loader css-loader
複製程式碼

新增 css 程式碼到專案中

  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());
複製程式碼

編譯

npm run build
# npx webpack
複製程式碼

請檢查頁面(不要檢視頁面源,因為它不會顯示結果)並檢視頁面的head標籤。 它應該包含我們在index.js中匯入的樣式塊。

tips:
請注意,您可以(在大多數情況下)最小化css,以便在生產中獲得更好的載入時間。 最重要的是,載入器幾乎存在於你能想到的任何CSS風格 - postcsssass, less等等。

載入 images 資源

安裝依賴

npm install --save-dev file-loader
複製程式碼

修改一下之前的專案

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

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

# 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());

# 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'
+         ]
+       }
      ]
    }
  };
複製程式碼

現在,當您從./my-image.png匯入 MyImage 時,該影象將被處理並新增到您的輸出目錄中,並且 MyImage 變數將包含處理後該影象的最終 URL。 當使用css-loader時,如上所示,CSS 中的url('./ my-image.png')將發生類似的過程。 載入程式將識別這是一個本地檔案,並將./my-image.png路徑替換為輸出目錄中影象的最終路徑。 html-loader以相同的方式處理<img src =“./ my-image.png”/>

編譯

npm run build
# npx webpack
複製程式碼

如果一切順利,您現在應該將您的圖示視為重複背景,以及我們的Hello webpack文字旁邊的img元素。 如果檢查此元素,您將看到實際檔名已更改為5c999da72346a995e7e2718865d019c8.png。 這意味著webpack在src資料夾中找到了我們的檔案並進行了處理!

tips :
下一步是縮小和優化您的影象。 檢視image-webpack-loaderurl-loader,瞭解有關如何增強影象載入過程的更多資訊。

載入 Fonts

那麼像字型這樣的其他資產呢? 檔案和URL載入器將獲取您通過它們載入的任何檔案,並將其輸出到您的構建目錄。 這意味著我們可以將它們用於任何型別的檔案,包括字型。 讓我們更新我們的webpack.config.js來處理字型檔案:

修改專案

  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

# 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'
+         ]
+       }
      ]
    }
  };
複製程式碼

載入 Data

可以載入的另一個有用資產是資料,如JSON檔案,CSV,TSV和XML。 對JSON的支援實際上是內建的,類似於 NodeJS,這意味著import Data from'./data.json'匯入資料預設情況將起作用。 要匯入CSV,TSV和XML,您可以使用csv-loader和xml-loader。 讓我們處理所有三個:

安裝依賴

npm install --save-dev csv-loader xml-loader
複製程式碼

修改專案

  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>

# 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());

# 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'
+         ]
+       }
      ]
    }
  };
複製程式碼

現在,您可以匯入這四種型別的資料中的任何一種(JSON,CSV,TSV,XML),並且匯入它的Data變數將包含已解析的JSON以便於使用。

全域性資源 Global Assets

上述所有內容中最酷的部分是,以這種方式載入資產允許您以更直觀的方式將模組和資產組合在一起。 您可以使用它們的程式碼對資產進行分組,而不是依賴包含所有內容的全域性/資產目錄。 例如,像這樣的結構非常有用:

修改專案

- |- /assets
+ |– /components
+ |  |– /my-component
+ |  |  |– index.jsx
+ |  |  |– index.css
+ |  |  |– icon.svg
+ |  |  |– img.png
複製程式碼

這種設定會更加的方便,因為現在元件所有內容都緊密耦合。 假設你想在另一個專案中使用/ my-component,只需複製或移動到那裡的/ components目錄即可。 只要有相同的 webpack 配置和 依賴就可以了。

但是,假設您已陷入舊方式,或者您擁有多個元件(檢視,模板,模組等)之間共享的資產。 仍然可以將這些資產儲存在基本目錄中,甚至可以使用別名來使它們更容易匯入。

NEXT

對於下一個指南,我們不會使用我們在本指南中使用的所有不同資產,所以讓我們做一些清理,以便我們為下一部分指南輸出管理做好準備:

修改專案

  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());
複製程式碼

相關文章