VueJS: Cấu trúc mã nguồn

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Tránh những singleton đơn độc

Khi viết mã chỉ dành cho client, chúng ta được sử dụng một thực tế là mã của chúng ta sẽ được đánh giá trong một ngữ cảnh mới mẻ mỗi lần. Tuy nhiên, một máy chủ Node.js là một quá trình chạy dài. Khi mã của chúng tôi được yêu cầu trong quá trình, nó sẽ được đánh giá một lần và nằm trong bộ nhớ. Điều này có nghĩa là nếu bạn tạo một đối tượng đơn lẻ, nó sẽ được chia sẻ giữa mọi yêu cầu gửi đến.

Như đã thấy trong ví dụ cơ bản, chúng ta đang tạo một cá thể Vue gốc mới cho mỗi yêu cầu. Điều này tương tự như cách mỗi người dùng sẽ sử dụng phiên bản ứng dụng mới trong trình duyệt của riêng họ. Nếu chúng ta sử dụng một cá thể được chia sẻ trên nhiều yêu cầu, nó sẽ dễ dàng dẫn đến tình trạng nhiễu các yêu cầu state chéo nhau.

Vì vậy, thay vì trực tiếp tạo một cá thể ứng dụng, chúng ta nên trưng ra một hàm state có thể được thực thi nhiều lần để tạo ra các đối tượng ứng dụng mới cho mỗi yêu cầu:

// app.js
const Vue = require('vue')

module.exports = function createApp (context) {
  return new Vue({
    data: {
      url: context.url
    },
    template: `<div>URL đã visit là: {{ url }}</div>`
  })
}

Và mã server của chúng ta bây giờ sẽ trở thành:

// server.js
const createApp = require('./app')

server.get('*', (req, res) => {
  const context = { url: req.url }
  const app = createApp(context)

  renderer.renderToString(app, (err, html) => {
    // lỗi xử lý...
    res.end(html)
  })
})

Quy tắc tương tự cũng áp dụng cho các router, lưu trữ và sự kiện bus. Thay vì xuất trực tiếp từ một mô-đun và nhập nó vào ứng dụng của bạn, bạn cần phải tạo một cá thể mới createApp và chèn nó từ đối tượng Vue gốc.

Ràng buộc này có thể được loại bỏ khi sử dụng trình kết xuất gói với { runInNewContext: true }, tuy nhiên nó đi kèm với một số chi phí hiệu năng đáng kể vì bối cảnh vm mới cần được tạo cho mỗi yêu cầu.

Giới thiệu Bước Xây dựng

Chúng ta vẫn chưa thảo luận cách phân phối cùng một ứng dụng Vue cho ứng dụng client. Để làm điều đó, chúng ta cần sử dụng webpack để gói ứng dụng Vue của chúng ta. Trong thực tế, chúng ta có thể muốn sử dụng webpack để gói ứng dụng Vue trên máy chủ, lý do là bởi vì:

  • Các ứng dụng Vue điển hình được xây dựng với webpack và vue-loader, và nhiều tính năng cụ thể của webpack như nhập tệp qua file-loader, nhập CSS qua css-loader sẽ không hoạt động trực tiếp trong Node.js.

  • Mặc dù phiên bản mới nhất của Node.js hỗ trợ đầy đủ các tính năng ES2015, chúng ta vẫn cần phải chuyển mã phía máy khách để phục vụ cho các trình duyệt cũ hơn. Điều này một lần nữa liên quan đến một bước xây dựng.

Ý tưởng cơ bản là chúng ta sẽ sử dụng webpack để gói ứng dụng của chúng ta cho cả máy khách và máy chủ - server bundle sẽ được yêu cầu bởi máy chủ và được sử dụng cho SSR, trong khi gói ứng dụng khách được gửi tới trình duyệt để hydrate các đánh dấu tĩnh.

kiến trúc

Chúng ta sẽ thảo luận chi tiết về thiết lập trong các phần sau - cho đến lúc này thì chúng ta hãy giả sử rằng chúng ta đã có thiết lập xây dựng và chúng ta có thể viết mã ứng dụng Vue với việc kích hoạt webpack.

Cấu trúc mã với gói webpack

Bây giờ chúng ta đang sử dụng webpack để xử lý ứng dụng cho cả máy chủ và máy khách, phần lớn mã nguồn của chúng ta có thể được viết theo kiểu trình diễn universal, với quyền truy cập vào tất cả các tính năng hỗ trợ webpack. Đồng thời, có một số điều bạn nên ghi nhớ khi viết mã phổ quát.

Một dự án đơn giản sẽ trông như thế này:

src
├── components
│   ├── Foo.vue
│   ├── Bar.vue
│   └── Baz.vue
├── App.vue
├── app.js # đầu vào universal
├── entry-client.js # chỉ chạy trong trình duyệt
└── entry-server.js # chỉ chạy trên server

#app.js

app.js là đầu vào universal cho ứng dụng của chúng ta. Trong một ứng dụng chỉ dành cho client thì chúng ta sẽ tạo ra cá thể Vue gốc ngay trong tệp này và gắn trực tiếp vào DOM. Tuy nhiên, đối với SSR, trách nhiệm đó được chuyển vào tệp mục nhập chỉ dành cho máy khách. app.js chỉ cần xuất một hàm createAp:

import Vue from 'vue'
import App from './App.vue'

// export a factory function for creating fresh app, router and store
// instances
export function createApp () {
  const app = new Vue({
    // the root instance simply renders the App component.
    render: h => h(App)
  })
  return { app }
}

entry-client.js :

Entry cho client chỉ cần tạo ứng dụng và gắn nó vào DOM:

import { createApp } from './app'

// client-specific bootstrapping logic...

const { app } = createApp()

// giả xử rằng template App.vue gốc có `id="app"`
app.$mount('#app')

entry-server.js:

Entry cho server sử dụng export mặc định là một hàm có thể được gọi nhiều lần cho mỗi kết xuất. Tại thời điểm này, nó không làm được gì khác ngoài việc tạo và trả về đối tượng app - nhưng sau đó chúng ta sẽ thực hiện khớp route phía máy chủ và logic tìm nạp dữ liệu tại đây.

import { createApp } from './app'

export default context => {
  const { app } = createApp()
  return app
}
» Tiếp: Định tuyến và tách mã
« Trước: Viết mã phổ dụng (Universal)
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!