+5

Webpack 5: Webpack File Loader

Webpack từ A đến Á cùng kentrung

Trong bài trước chúng ta đã biết cách thiết lập Webpack để sử dụng hình ảnh trong ứng dụng của bạn thông qua url-loader. Bài hôm nay cũng tương tự như vậy nhưng lại sử dụng file-loader, nó giúp chúng ta giải quyết các vấn đề liên quan đến import - require một file, file-loader có nhiệm vụ phân tích và ouput ra trong thư mục dist.

1. Chuẩn bị file

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Webpack từ A đến Á cùng kentrung</title>
</head>
<body>
  <div id="root"></div>
  <script src="main.js"></script>
</body>
</html>

Trong folder src ta để ảnh muốn import bên trong folder assets như cấu trúc bên dưới

webpack-demo
  ...
  |- src/
        |- assets/
        |   |- images/
        |      - img_webpack.png
        |- index.js 

2. Webpack file-loader

file-loader giúp chúng ta giải quyết các vấn đề liên quan đến import - require một file. Nó có nhiệm vụ phân tích và ouput ra trong thư mục dist.

Link thư viện: https://www.npmjs.com/package/file-loader

npm install file-loader --save-dev

Sau khi cài đặt xong chúng ta chỉnh sửa lại cấu hình file webpack.config.js. Các tài nguyên hình ảnh có đuôi là png|jpg|gif sẽ được load thông qua file-loader.

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'file-loader',
          },
        ],
      },
    ],
  },
}
import imgWebpack from './assets/images/img_webpack.png'

function createImgElement() {
  const imgElement = document.createElement('img')
  imgElement.src = imgWebpack
  imgElement.alt = 'Webpack từ A đến Á cùng kentrung'
  return imgElement
}

document.getElementById('root').appendChild(createImgElement())

Ý nghĩa đoạn code trên là tạo ra một thẻ img có src là đường dẫn bức ảnh ở phần import, alt là mô tả bức ảnh. Sau khi tạo xong thì chèn ảnh này vào trong thẻ HTML có id là root

Thế là xong phần cấu hình giờ chúng ta chạy webpack xem thế nào: npm run dev

Khi chạy xong câu lệnh chúng ta thấy trong folder dist đã tự động có thêm ảnh và file js như cấu trúc bên dưới

webpack-demo
  ...
  |- dist/
    |- 5ab50ccadbd858c94b26bfc82375d89d.png
    |- index.html
    |- main.js

Bây giờ chúng ta chạy file dist/index.html và xem code trong F12

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Webpack từ A đến Á cùng kentrung</title>
</head>
<body>
  <div id="root">
    <img src="5ab50ccadbd858c94b26bfc82375d89d.png" alt="Webpack từ A đến Á cùng kentrung">
  </div>
  <script src="main.js"></script>
</body>
</html>

Ta thấy đường dẫn bức ảnh lúc này là gọi trực tiếp file ảnh nằm ngang hàng với file html.

3. Options Name

Với Option Name thì chúng ta có thể thay đổi được đường dẫn bức ảnh output. Ví dụ dưới đây chúng ta sẽ gom ảnh và để trong folder dist/images/

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'images/[name].[ext]',
            },
          },
        ],
      },
    ],
  },
}

Khi chạy xong câu lệnh chúng ta thấy trong folder dist đã tự động có thêm ảnh như cấu trúc bên dưới

webpack-demo
  ...
  |- dist/
    |- index.html
    |- main.js
    |- images/
      - img_webpack.png

Với Option Name thứ hai thì chúng ta có thể thay đổi được đường dẫn bức ảnh dựa theo đúng cấu trúc folder mình đã đặt trong src.

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        loader: 'file-loader',
        options: {
          name: '[path][name].[ext]',
        },
      },
    ],
  },
}

Khi chạy xong câu lệnh chúng ta thấy trong folder dist đã tự động có thêm ảnh như cấu trúc bên dưới

webpack-demo
  ...
  |- dist/
    |- index.html
    |- main.js
    |- src/
        |- assets/
            |- images/
                - img_webpack.png

Ngoài option này ra thì trong webpack còn nhiều các option khác hay ho lắm mà mình chưa dùng hết được.


Bài viết đến đây là hết, hi vọng với bài viết này các bạn đã thêm được nhiều kiến thức bổ ích. Hẹn gặp lại các bạn ở bài viết tiếp theo!


All rights reserved

Bình luận

Đăng nhập để bình luận
Avatar
@maicaotri
thg 4 10, 2021 1:03 SA

Việc file-loader này làm giống như coppy ra file mới rồi bỏ vào thư mục build thôi chứ không có encode gì như url-loader đúng không anh?

Avatar
@trungnt256
thg 4 10, 2021 6:50 SA

@maicaotri đúng rồi, sau mình có thể sử dụng những tài nguyên đã tách này cho các mục đích khác

Avatar
@laudaikinhdi
thg 9 12, 2021 1:43 CH

[webpack-cli] Error: Prevent writing to file that only differs in casing or query string from already written file. This will lead to a race-condition and corrupted files on case-insensitive file systems. /Applications/Source/tanmnt/laravel/public/images/1.jpg /Applications/Source/tanmnt/laravel/public/images/1.jpg

Em bị lỗi này khi tên file giống nhau. Có cách nào fix k a

Avatar
@trungnt256
thg 9 13, 2021 4:29 SA

Em thử khi output các file ảnh thì thêm chuỗi hash độ dài 6 kí tự vào sau tên ảnh như này xem được không?

module: {
  rules: [
    {
      test: /\.(png|jpe?g|gif)$/i,
      use: [
        {
          loader: 'file-loader',
          options: {
            name: 'images/[name]-[hash:6].[ext]'
          }
        }
      ]
    }
  ]
}
Avatar
@laudaikinhdi
thg 10 17, 2021 5:03 CH

@trungnt256 image.png Ảnh gốc nó vẫn được build ra a. Có cách nào mình giữ ảnh đã hash k a? Em cảm ơn

Avatar
+5
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí