Trình đóng gói mô-đun JavaScript có thể làm được nhiều việc, nhưng một trong những tính năng hữu ích nhất của chúng là khả năng thêm và sử dụng thư viện bên ngoài trong cơ sở mã của bạn. Trình đóng gói mô-đun đọc các đường dẫn nhập trong mã của bạn và kết hợp (gói) mã dành riêng cho ứng dụng với mã thư viện đã nhập.
Từ phiên bản 9 trở lên, API mô-đun JavaScript của Firebase được tối ưu hoá để hoạt động với các tính năng tối ưu hoá của trình đóng gói mô-đun nhằm giảm lượng mã Firebase có trong bản dựng cuối cùng.
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';
const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });
/**
* getRedirectResult is unused and should not be included in the code base.
* In addition, there are many other functions within firebase/auth that are
* not imported and therefore should not be included as well.
*/
Quá trình loại bỏ mã không dùng đến khỏi thư viện được gọi là rung cây (tree shaking). Việc xoá mã này theo cách thủ công sẽ mất rất nhiều thời gian và dễ xảy ra lỗi, nhưng trình đóng gói mô-đun có thể tự động xoá mã này.
Có nhiều trình đóng gói mô-đun chất lượng cao trong hệ sinh thái JavaScript. Hướng dẫn này tập trung vào việc sử dụng Firebase với webpack, Rollup và esbuild.
Bắt đầu
Hướng dẫn này yêu cầu bạn phải cài đặt npm trong môi trường phát triển. npm dùng để cài đặt và quản lý các phần phụ thuộc (thư viện). Để cài đặt npm, hãy cài đặt Node.js. Thao tác này sẽ tự động cài đặt npm.
Hầu hết nhà phát triển đều thiết lập đúng cách sau khi cài đặt Node.js. Tuy nhiên, có một số vấn đề thường gặp mà nhiều nhà phát triển gặp phải khi thiết lập môi trường. Nếu gặp lỗi, hãy đảm bảo môi trường của bạn có npm CLI và bạn đã thiết lập các quyền thích hợp để không phải cài đặt các gói với tư cách là quản trị viên bằng lệnh sudo.
package.json và cài đặt Firebase
Sau khi cài đặt npm, bạn cần tạo một tệp package.json
ở gốc của dự án cục bộ. Tạo tệp này bằng lệnh npm sau:
npm init
Thao tác này sẽ đưa bạn đến một trình hướng dẫn để cung cấp thông tin cần thiết. Sau khi tạo, tệp sẽ có dạng như sau:
{
"name": "your-package-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
}
}
Tệp này chịu trách nhiệm cho nhiều việc khác nhau. Đây là một tệp quan trọng mà bạn cần làm quen nếu muốn tìm hiểu thêm về việc gói mô-đun và tạo mã JavaScript nói chung. Phần quan trọng của hướng dẫn này là đối tượng "dependencies"
. Đối tượng này sẽ chứa một cặp khoá-giá trị của thư viện bạn đã cài đặt và phiên bản mà thư viện đó đang sử dụng.
Bạn có thể thêm phần phụ thuộc thông qua lệnh npm install
hoặc npm i
.
npm i firebase
Khi bạn chạy npm i firebase
, quá trình cài đặt sẽ cập nhật
package.json
để liệt kê Firebase dưới dạng phần phụ thuộc:
"dependencies": {
"firebase": "^9.0.0"
},
Khoá là tên của thư viện và giá trị là phiên bản cần sử dụng. Giá trị phiên bản linh hoạt và có thể chấp nhận nhiều giá trị. Đây được gọi là phiên bản ngữ nghĩa hoặc semver. Để tìm hiểu thêm về semver, hãy xem hướng dẫn của npm về việc tạo phiên bản ngữ nghĩa.
Thư mục nguồn so với thư mục bản dựng
Mã bạn viết được trình gói mô-đun đọc và xử lý, sau đó xuất dưới dạng một tệp hoặc tập hợp tệp mới. Bạn cần phân tách hai loại tệp này. Mã mà trình đóng gói mô-đun đọc và xử lý được gọi là mã "nguồn". Các tệp mà chúng tạo ra được gọi là mã đã tạo hoặc mã "dist" (phân phối).
Một cách thiết lập phổ biến trong cơ sở mã là lưu trữ mã nguồn trong thư mục có tên src
và mã đã tạo trong thư mục có tên dist
.
- src
|_ index.js
|_ animations.js
|_ datalist.js
- dist
|_ bundle.js
Trong cấu trúc tệp mẫu ở trên, hãy xem xét rằng index.js
nhập cả animations.js
và datalist.js
. Khi trình gói mô-đun xử lý mã nguồn, trình này sẽ tạo tệp bundle.js
trong thư mục dist
. bundle.js
là sự kết hợp của các tệp trong thư mục src
và mọi thư viện nhập.
Nếu bạn đang sử dụng các hệ thống kiểm soát nguồn như Git, thường thì bạn sẽ bỏ qua thư mục dist
khi lưu trữ mã này trong kho lưu trữ chính.
Điểm truy cập
Tất cả trình gói mô-đun đều có khái niệm về điểm truy cập. Bạn có thể coi ứng dụng của mình là một cây tệp. Một tệp nhập mã từ một tệp khác, v.v. Điều này có nghĩa là một tệp sẽ là gốc của cây. Tệp này được gọi là điểm truy cập.
Hãy xem lại ví dụ về cấu trúc tệp trước đó.
- src
|_ index.js
|_ animations.js
|_ datalist.js
- dist
|_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';
// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
animate(theList);
});
Tệp src/index.js
được coi là điểm truy cập vì tệp này bắt đầu nhập tất cả mã cần thiết cho ứng dụng. Tệp điểm truy cập này được trình gói mô-đun sử dụng để bắt đầu quá trình gói.
Sử dụng Firebase với webpack
Bạn không cần phải thiết lập cấu hình cụ thể nào cho ứng dụng Firebase và webpack. Phần này cung cấp thông tin về cấu hình webpack chung.
Bước đầu tiên là cài đặt webpack từ npm dưới dạng phần phụ thuộc phát triển.
npm i webpack webpack-cli -D
Tạo một tệp ở thư mục gốc của dự án cục bộ có tên là webpack.config.js
rồi thêm mã sau.
const path = require('path');
module.exports = {
// The entry point file described above
entry: './src/index.js',
// The location of the build folder described above
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
// Optional and for development only. This provides the ability to
// map the built code back to the original source format when debugging.
devtool: 'eval-source-map',
};
Sau đó, hãy đảm bảo bạn đã cài đặt Firebase dưới dạng phần phụ thuộc.
npm i firebase
Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập, đồng thời sử dụng Firestore Lite để tải tài liệu "thành phố".
// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';
const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);
async function loadCity(name) {
const cityDoc = doc(db, `cities/${name}`);
const snapshot = await getDoc(cityDoc);
return {
id: snapshot.id,
...snapshot.data(),
};
}
Bước tiếp theo là thêm tập lệnh npm để chạy bản dựng webpack. Mở tệp package.json
và thêm cặp khoá-giá trị sau vào đối tượng "scripts"
.
"scripts": {
"build": "webpack --mode=development"
},
Để chạy webpack và tạo thư mục bản dựng, hãy chạy lệnh sau.
npm run build
Cuối cùng, hãy kiểm tra thư mục bản dựng dist
. Tệp này phải chứa một tệp có tên bundle.js
chứa ứng dụng và mã phần phụ thuộc được đóng gói.
Để biết thêm thông tin về cách tối ưu hoá bản dựng webpack cho bản phát hành chính thức, hãy xem tài liệu chính thức của họ về chế độ cài đặt cấu hình "mode".
Sử dụng Firebase với tính năng Rollup
Bạn không cần phải thiết lập cấu hình cụ thể nào cho ứng dụng Firebase và tính năng Tổng hợp. Phần này trình bày cấu hình Rollup chung.
Bước đầu tiên là cài đặt Rollup và một trình bổ trợ dùng để liên kết các tệp nhập với các phần phụ thuộc được cài đặt bằng npm.
npm i rollup @rollup/plugin-node-resolve -D
Tạo một tệp ở thư mục gốc của dự án cục bộ có tên là rollup.config.js
rồi thêm mã sau.
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default {
// the entry point file described above
input: 'src/index.js',
// the output for the build folder described above
output: {
file: 'dist/bundle.js',
// Optional and for development only. This provides the ability to
// map the built code back to the original source format when debugging.
sourcemap: 'inline',
// Configure Rollup to convert your module code to a scoped function
// that "immediate invokes". See the Rollup documentation for more
// information: https://rollupjs.org/guide/en/#outputformat
format: 'iife'
},
// Add the plugin to map import paths to dependencies
// installed with npm
plugins: [nodeResolve()]
};
Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập, đồng thời sử dụng Firestore Lite để tải tài liệu "thành phố".
// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';
const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);
async function loadCity(name) {
const cityDoc = doc(db, `cities/${name}`);
const snapshot = await getDoc(cityDoc);
return {
id: snapshot.id,
...snapshot.data(),
};
}
Bước tiếp theo là thêm tập lệnh npm để chạy bản dựng cuộn lên. Mở tệp package.json
và thêm cặp khoá-giá trị sau vào đối tượng "scripts"
.
"scripts": {
"build": "rollup -c rollup.config.js"
},
Để chạy tính năng tổng hợp và tạo thư mục bản dựng, hãy chạy lệnh sau.
npm run build
Cuối cùng, hãy kiểm tra thư mục bản dựng dist
. Tệp này phải chứa một tệp có tên bundle.js
chứa ứng dụng và mã phần phụ thuộc được đóng gói.
Để biết thêm thông tin về cách tối ưu hoá bản dựng Rollup cho bản phát hành chính thức, hãy xem tài liệu chính thức của họ về các trình bổ trợ cho bản phát hành chính thức.
Sử dụng Firebase với esbuild
Bạn không cần phải định cấu hình cụ thể cho các ứng dụng Firebase và esbuild. Phần này trình bày cấu hình esbuild chung.
Bước đầu tiên là cài đặt esbuild dưới dạng phần phụ thuộc phát triển.
npm i esbuild -D
Tạo một tệp ở thư mục gốc của dự án cục bộ có tên là esbuild.config.js
rồi thêm mã sau.
require('esbuild').build({
// the entry point file described above
entryPoints: ['src/index.js'],
// the build folder location described above
outfile: 'dist/bundle.js',
bundle: true,
// Replace with the browser versions you need to target
target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
// Optional and for development only. This provides the ability to
// map the built code back to the original source format when debugging.
sourcemap: 'inline',
}).catch(() => process.exit(1))
Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập, đồng thời sử dụng Firestore Lite để tải tài liệu "thành phố".
// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';
const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);
async function loadCity(name) {
const cityDoc = doc(db, `cities/${name}`);
const snapshot = await getDoc(cityDoc);
return {
id: snapshot.id,
...snapshot.data(),
};
}
Bước tiếp theo là thêm tập lệnh npm để chạy esbuild. Mở tệp package.json
và thêm cặp khoá-giá trị sau vào đối tượng "scripts"
.
"scripts": {
"build": "node ./esbuild.config.js"
},
Cuối cùng, hãy kiểm tra thư mục bản dựng dist
. Tệp này phải chứa một tệp có tên bundle.js
chứa ứng dụng và mã phần phụ thuộc được đóng gói.
Để biết thêm thông tin về cách tối ưu hoá esbuild cho bản phát hành chính thức, hãy xem tài liệu chính thức của họ về việc rút gọn và các hoạt động tối ưu hoá khác.