Với xu hướng lập trình mà business và phần lớn xử lý đều nằm ở tầng phía front-end với gánh nặng càng ngày càng đè lên vai chàng dũng sĩ javascript tội nghiệp, thì các công cụ hỗ trợ cho anh ấy (ahihi) như typing, task runner, test tools,... tè le tà la hết, nói chung là không thể thiếu được với 1 front-end dev. Hôm nay mình muốn giới thiệu Webpack một module loader cho javascript một cách cơ bản nhất.
Webpack hiện đang là module loader được sử dụng rộng rãi nhất hiện nay với cộng động support to lớn và những chức năng vô cùng mạnh mẽ.
Một cách đơn giản là ngày xưa chúng ta thường add những thư viện (3th parties) như jquery, moment, select2, dtpicker,sticky,... vào thẻ script để khi web load lên xong thì những thư viện này sẽ được execute và xử lý. Nhưng không còn như những ngày xưa chỉ vài dòng jquery là đủ dùng, sau này do việc code dưới front-end càng ngày càng phìng to nên việc quản lý code = javascript càng ngày càng tõ rõ sự quan trọng nên từ đó khái niệm module loader ra đời.
Có khá nhiều thư viện từ nhỏ đến to ra đời cho việc này: Tiny Loaders (curl, LABjs, almond), RequireJS, Browserify, SystemJs, Webpack và gần đây đang nổi lên là RollupJs.
Nếu bạn nào có xài SystemJs, Browserify rồi thì thấy thật ra Webpack ra đời từ thừa hưởng những thành quả và kinh nghiệm từ những thư viện đó và phát triển lền một tầm mới tốt hơn cho công việc quản lý module.
Yêu cầu: NodeJS, Chúng ta sẽ có 2 file .js
xinchao.js
export default function xinchao(name){ ^console.log('Xin chao '+ name); }
index.js
import xinchao from './xinchao'; xinchao('Bao Nguyen');
Tạo file webpack.config.js để config cho Webpack.
module.exports = { ^entry: './index.js', ^output: { ^^filename: 'bundle.js' ^} }
- entry: là file mà chúng ta sẽ bắt đầu chạy bằng webpack. Nói chung nó là bắt nguồn của chiến tranh. Nó import từ thằng khác rồi thằng khác import từ thằng khác khác nữa từ đó sẽ kéo theo một chuỗi có hệ thống việc load các js module. Ở đây là file index.js ở trên.
- output-filename: là đầu ra của file sau khi webpack làm việc xong.
Gõ webpack để run. Chúng ta sẽ thấy file bundle.js được tạo ra và sau khi chạy file index.html sẽ xuất ra dòng log xin chao Bao Nguyen. Chúng ta cùng xem trong file bundle.js có gì và webpack đã làm gì nhé.
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 1); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (immutable) */ __webpack_exports__["a"] = xinchao; function xinchao(name) { console.log('Xin chao ' + name); } /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__xinchao__ = __webpack_require__(0); __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__xinchao__["a" /* default */])('Bao Nguyen'); /***/ }) /******/ ]);
Khá loằng nhoằng nhưng chúng ta có thể hiểu webpack đang làm cái gì. Như ta thấy Module /* 0 */ là file xinchao.js và module /* 1 */ chính file index.js.
var __WEBPACK_IMPORTED_MODULE_0__xinchao__ = __webpack_require__(0); __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__xinchao__["a" /* default */])('Bao Nguyen');
Đoạn này có thể thấy webpack require function trong module xinchao và call nó ở index.js. Những function mặc định trên của webpack như ta thấy dùng để như:
Nguyên bài này là những phần hết sức căn bản trong việc sử dụng Webpack - module loader được sử dụng rỗng rãi nhất hiện nay.