Giới thiệu

Khi làm một trang web, bạn luôn muốn cho trang web của mình trả lời người dùng một cách nhanh nhất có thể. Nó giúp tăng hiệu năng người dùng và cũng giúp cho SEO của web được tốt hơn.

Một trong những lý do lớn nhất khiến cho một website phản hồi chậm chính là thời gian của http request lớn. Mỗi lần website lấy các tài nguyên(css, js, images) từ server nó đều phải gửi http request tới, thời gian của http request này chính là thời gian mà đa số người dùng phải chờ cho browser load xong.

Để giảm thiểu số lượng các http request tới server thì việc giảm thiểu các file tài nguyên(css, js, images) càng nhiều càng tốt. Hiện nay các website đều gói các file js, css vào một vài file để hạn chế browser phải load nhiều file.

Webpack là một trong số những thư viện giúp chúng ta gói các file tài nguyên lại.

Trong laravel, laravel-mix là một wrapper của webpack giúp người dùng sử dụng webpack một cách dễ dàng hơn.

Mục tiêu

Giả sửa project có cấu trúc thư mục như sau:

/myproject
  /app
  /public
    /css
      bootstrap.min.css
      custom.css
    /dist
    /js
      create-post.js
      view-post.js
    /plugins
      jquery.min.js
      bootstrap.min.js
  /resources
    /views
      /layouts
        base.blade.php
      /blog
        create-post.blade.php
        view-post.blade.php
  package.json
  • Ta cần tách ra 2 file js, một file là file chứa tất cả code js cố định của thư viện như jquery, boostrap...(VD đặt tên là vendor.js) ; một file chứa code js của bạn (VD đặt tên là custom.js). Nếu bạn không thường xuyên sửa code js của mình thì có thể ném hết vào 1 file cũng được vì browser sẽ cache file cho chúng ta, còn nếu bạn thường xuyên sửa file js của mình thì bạn nên tách file chứa code của thư viện ra vì nếu không browser sẽ load lại toàn bộ file rất nặng. Tương tự với các file css.
  • Bạn đặt file vendor.js vào layout của html vì hầu như tất cả các trang đều dùng nó. Và đặt file custom.js vào màn nào cần dùng nó. Vì browser sẽ cache file vendor.js nên bạn cứ đặt vào html layout.

Nếu làm như trên bạn chỉ cần biết gắn thẻ script của một file duy nhất custom.js

Cách cài đặt trong laravel

  • Sửa file package.json như sau:
// myproject/package.json

{
  "private": true,
  "scripts": {
    "dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "hot": "NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
  },
  "dependencies": {
    "laravel-mix": "^2.1.11"
  }
  ...
}

rồi chạy npm install  để cài đặt laravel-mix

  • Copy file webpack.mix.js từ `node_modules/laravel-mix/setup/webpack.mix.js`
cp -r node_modules/laravel-mix/setup/webpack.mix.js ./
  • Cấu hình file webpack.mix.js 
// myproject/webpack.mix.js


let mix = require('laravel-mix');

mix.scripts([
	'public/plugins/jquery.min.js',
	'public/plugins/bootstrap.min.js',
        ...
], 'public/dist/vendor.js')

mix.js([
	'public/js/view-post.js',
	'public/js/create-post.js',
        ...
], 'public/dist/custom.js')

mix.styles([
	'public/css/bootstrap.min.css',
        ...
], 'public/dist/vendor.css')

mix.styles([
	'public/css/custom.css',
        ...
], 'public/dist/custom.css')
.....

Các hàm mix.scriptsmix.js, mix.styles nhận các file input và tạo các file output cho ta. Như ở trên ta tạo 2 file js và 2 file css.

Hàm mix.scripts sẽ tạo file js cho chúng ta và không sử dụng babel, hàm mix.js sử dụng babel để convert code từ ES2015 thành code js mà browser cũ đọc được. 

  • Chạy câu lệnh build webpack trên môi trường dev
npm run dev

Nếu muốn tự động build mỗi khi bạn sửa file js css thì chạy câu lệnh sau:

npm run watch

Khi deploy thì bạn cần phải build với MT production để code được build ra chỉ nằm trên một dòng khiến file nhẹ hơn rất nhiều:

npm run prod

Sẽ có 4 file mới dc tạo ra tại: public/dist/vendor.js, public/dist/custom.js, public/dist/vendor.css, public/dist/custom.css 

  • Cuối cùng là gắn thẻ script vào các file html cần thiết.
// myapp/resources/views/layouts/base.blade.php
<!DOCTYPE html>

<html lang="en">
    <head>
        ...
        <link href="{{asset('dist/vendor.css')}}" type="text/css" rel="stylesheet" media="all">
        <link href="{{asset('dist/custom.css')}}" type="text/css" rel="stylesheet" media="all">
        @yield('css')
        <script src="{{asset('dist/vendor.js')}}" type="text/javascript"></script>
        @yield('header-js')
        ...
    </head>
</html>
<body id="body">
    ...
</body>

 

// myproject/resources/views/blog/create-post.blade.js
// và myproject/resources/views/blog/view-post.blade.js

@extends('layouts.base')

@section('header-js')
    <script src="{{asset('dist/custom.js')}}" type="text/javascript" defer></script>
@endsection('header-js')

 

Bình thường khi đặt thẻ script của js bạn phải đặt phía sau html body để cho html load xong thì script mới được chạy. Nhưng làm thế thì phải chờ html load xong thì mới load được file js . Có một cách hay hơn là vừa khiến html js load cùng khi bằng cách đặt thẻ script có thuộc tính defer vào html header (Xem thêm về Cơ chế browser load html và js).