Webpack v4 beta is out now. Let's try some new features!

Webpack v4 beta mới vừa được release mấy hôm trước. Mình mới thử qua một vài tính năng được quảng cáo.

Install

Tất nhiên vì mới chỉ là bản beta nên chúng ta cần cài từ branch next. Ngoài ra cần cài thêm webpack-cli vì bây giờ nó là một package riêng rồi.

npm install --save-dev [email protected] webpack-cli

Hoặc là với yarn

yarn add --dev [email protected] webpack-cli

Performance

Đầu tiên là nodejs v4 đã không còn được hỗ trợ nữa. Version yêu cầu thấp nhất của Node.js bây giờ là 6.11.5. Version Node.js cao hơn sẽ có thêm vài tính năng native mới mà không cần polyfill nữa, sẽ cải thiện performance chút ít.

UglifyJS cũng được nâng cấp để có thể cache và build parallel để tăng tốc build, nhất là các lần build sau. Bây giờ sau khi build bạn sẽ thấy có thêm folder .cache được tạo ra trong node_modules. Đây đều là những tính năng cũng được quảng cáo trong bundler mới nổi Parcel.

Mình chưa thử với project lớn nào cả vì có vẻ vài plugin bị lỗi với webpack v4. Thử qua với một cái project bé tẹo thì có vẻ build time khi có cache nhanh hơn thật.

Build lần đầu

Khi đã có cache

Zero configuration setup

Đây có lẽ là phần thú vị nhất của bản update lần này. Có thể bạn đã nghe về một web bundler mới nổi gần đây đó là Parcel với điểm nổi bật chính là khả năng bundle mà không cần tí config nào hết. Bây giờ thì webpack cũng làm được thế. Webpack sẽ mặc định file entry là index.js trong folder sec. File output mặc định sẽ là main.js trong folder dist.

Bạn chỉ cần tạo một file index.js trong folder src, thêm build script trong file package.json nữa

  "build": "webpack"

Rồi giờ chạy

npm run build

là sẽ thấy file main.js được build trong folder dist.

Ngoài ra bạn sẽ thấy có một warning thế này

The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.

Bây giờ webpack sẽ có thêm một option mode để bạn set bằng development hoặc production. Webpack sẽ tự động bật các plugin cần thiết cho mỗi mode. Ví dụ chúng ta vẫn hay phải thêm cái này trong file webpack.config.js

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

Thì bây giờ webpack sẽ tự động bật hết mấy cái plugin đấy cho bạn. Vậy build script trong file package.json của chúng ta sẽ sửa thành thế này.

  "dev": "webpack --mode development",
  "build": "webpack --mode production",

Bây giờ nếu chạy npm run build thì chúng ta sẽ được một file đã minify luôn, không cần làm gì thêm cả.

Side-effects-free module

Có thể bạn không cần quan tâm đến cái này, trừ khi bạn đang viết một package thì có thể bạn sẽ quan tâm đến.

lodash có lẽ là package đã quen thuộc với nhiều bạn rồi. Nó là một package khá là lớn (khoảng 50kB sau khi đã minify). Trong đó có cả tỉ function mà chắc chẳng ai dùng hết toàn bộ chỗ đấy trong một project cả.

Nhưng mà lodash lại export function theo kiểu này

    lodash.after = after;
    lodash.ary = ary;
    lodash.assign = assign;
    // ...

Nên nếu bạn import thế này thì tất cả chỗ function trong lodash đều bị import vào luôn.

import { map } from 'lodash'

Có một package tên là lodash-es. Nó export tất cả function của lodash với ES2015 module syntax để bạn có thể import từng function một

    export { default as add } from './add.js';
    export { default as after } from './after.js';
    export { default as ary } from './ary.js';

Nhưng nếu bạn đã từng thử tìm đến nó với hi vọng tree-shaking sẽ hoạt động thì chắc bạn cũng đã thấy nó vô dụng đến thế nào. Cả webpackrollup đều không thể làm được gì với lodash. Lí do là vì trong lodash có những đoạn code trông có vẻ như có thể gây ra side effect nhưng thật ra lại không phải. Vì thế webpack hay rollup buộc phải thêm gần như toàn bộ package vào bundle dù cho phần lớn code không được dùng đến. Detect mấy cái side effect này thì lại không dễ dàng, vậy nên webpack đã thêm một option có thể được viết trong file package.json để cho biết rằng package này chắc chắn không có side effect.

Để thử cái này bạn có thể cài package lodash-es

npm install --save lodash-es

Xong trong file index.js viết thêm dòng này

import { map } from 'lodash-es';

Rồi build nó ra sẽ thấy file bundle nặng hơn 8 chục kB

Bây giờ mở file package.json trong node_modules/lodash-es và thêm dòng này

  "sideEffects": false

Rồi build lại giờ sẽ thấy file bundle chỉ còn có hơn chục kB

JSON tree-shaking

Lại thêm một improvement nữa cho phần tree-shaking. Bây giờ file JSON cũng có thể được tree-shaking giống như js module. Ví dụ bạn có file data.json thế này

{
    "a": "Some text",
    "b": "Some other text that never get used"
}

Nếu bạn chỉ import một phần của file JSOM

import { a } from './data.json'

Thì chỉ có phần được import mới được thêm vào file bundle cuối cùng thôi.

function(r){r.exports={a:"Some text"}}

Trên đây mới là vài tính năng mới mình nghĩ là nổi bật của webpack v4. Vẫn còn những tính năng khác nữa, bạn hãy thử tìm hiểu xem nhé.