Loading...

Làm thế nào để tải trước một file json trước khi page được kết xuất?

1.Vấn đề

Thông thường khi làm việc trong 1 dự án, các biến về config thường sẽ được khởi tạo trong file .env và sau đó sẽ được đem ra sử dụng như dưới đây

DB_HOST=https://services.sandbox.icondo.asia/

và sau đó sẽ gọi ra và sử dụng

console.log(proccess.env.DB_HOST)

Mọi chuyện vẫn đúng và chức năng vẫn hoạt động bình thường, nhưng sẽ có những bất cập dưới đây:

  • Khi nhu cầu config thay đổi bạn phải chỉnh sửa lại file .env và build lại dự án của mình. Vì căn bản file .env này sẽ chạy và lưu giá trị trong quá trình compile time

Vì những bất cập đó, thì phải có 1 nơi sẽ chỉnh sửa file config cho từng dự án, và nhiệm vụ của phía client là load file config đó lên và sử dụng giá trị đó thay cho file env. Dưới đây là những cách tiếp cận mà mình sẽ hướng dẫn cho bạn

2. Áp dụng

Chúng ta sẽ tạo 1 function để fetch data từ api

export const fetcherJSON = (url: string, config?: RequestInit) => fetch(url, config).then((res) => res.json());
Với Angular ở file main.ts
(async () => {
  const data = await fetcherJSON('link json here...')
// todo with json config data
  function bootstrap() {
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
  };
  if (document.readyState === 'complete') {
    bootstrap();
  } else {
    document.addEventListener('DOMContentLoaded', bootstrap);
  }
})();
Với React ở file index.tsx
(async () => {
    try {

        const container = document.getElementById('main-condo');
        const root = createRoot(container);
        const config = await fetcherJSON('/assets/config.json');
        root.render(<Provider>
                <App config={data}/>
        </Provider>);
    } catch (e) {
        // todo error
    }
})();
Ở file App.tsx
function App(props) {
    useEffect(() => {
        console.log(props.config)
        // todo with props.config
    }, []);
    return (<>...</>)
}
Với Remix ở file root.tsx
import {useLoaderData} from "@remix-run/react";
export const loader = async ({request}) => {
    const location = new URL(request.url)
    const config = await fetcherJSON(location.origin + `/config.json`);
    return json(config);
}

export default function App() {
    const config= useLoaderData();
    // todo config
    return (
       <><Outlet/></>
    )
}

3. Lời kết

Với những gì mình giới thiệu ở trên thì sẽ giúp được các bạn trong vấn đề dynamic config với từng môi trường dev của mình. Nhưng bên cạnh đó việc sử dụng cách này sẽ dẫn đến việc các data config sẽ dễ bị lộ hơn so với dùng env file

© 2024 Nguyen Ba Tran Van. All Rights Reserved.