首頁  >  文章  >  web前端  >  使用 Oats~i 建立 Web 應用程式 – 設定

使用 Oats~i 建立 Web 應用程式 – 設定

PHPz
PHPz原創
2024-08-19 17:08:07976瀏覽

在上一篇文章中,我寫了一篇關於開放網路框架 Oats~i 的介紹文章。我討論了它的核心功能、它的工作原理以及預期內容。如果您還沒有讀過那篇文章,請快速瀏覽一下。

在過去的幾天裡,我圍繞 Oats~i 創建了一些工具,以確保我們能夠快速啟動並運行安裝框架、運行入門專案以及無縫地進行教程和學習。

本文是「使用 Oats~i 建立 Web 應用程式」系列的第一篇。我們將首先使用兩種方法設定 Oats~i 項目 – 使用 cli 或手動。

使用 Oats~i CLI(建議)

這是建立 Oats~i 專案最推薦的方法。它可以節省您編寫樣板程式碼和安裝 Oats~i 專案啟動和運行所需的依賴項的時間。

但是,您應該僅在建立全新專案時使用此方法,以避免 Oats~i 和目前專案結構之間潛在的檔案衝突。

cli 附帶了一個帶有主頁和關於頁面的入門項目。您可以在這兩個頁面之間導航,查看 Oats~i 已經在運行,處理路由和片段。

如何使用 Oats~i CLI

  • 導航到您要建立 Oats~i 專案的資料夾
  • 開啟終端機並運行
npx oats-i-cli

  • 依照提示操作,等待設定完成
  • 奔跑吧
npm run dev

  • 導覽至建置開始時終端中顯示的位址(通常是 localhost:8080)。這將在您的瀏覽器上開啟啟動項目。 (您可以使用本地網路位址在連接到相同網路的其他裝置上查看)

手動安裝

如果您有一個現有項目想要安裝 Oats~i,或者喜歡硬核,您可以手動設定 Oats~i。這個過程要長得多,並且需要更多的關注以確保一切順利。

安裝依賴項

現在,首先導航到專案的目錄並開啟終端。

首先,我們安裝建置和執行 Oats~i 所需的依賴項。如果您開始一個新專案,請從運行開始。

npm init -y

然後,請按照下面列出的步驟操作。

注意:除了安裝 Oats~i 之外,如果您已經在當前專案中安裝了庫/依賴項,您可以跳過後面的任何步驟。

安裝 Oats~i(核心)

安裝核心 Oats~i 庫。

奔跑

npm install oats-i

安裝Webpack

安裝 Webpack 作為開發相依性。 Webpack 將使我們能夠擁有更好的專案結構以及其他功能,包括庫處理模組捆綁和資產管理。

奔跑

npm install --save-dev webpack webpack-cli

安裝 Webpack 開發伺服器

安裝 webpack 開發伺服器作為開發相依性。這將使我們能夠運行一個開發伺服器,該伺服器將在我們建置和測試 Oats~i Web 應用程式時自動更新新的變更。

奔跑

npm install --save-dev webpack-dev-server

安裝車把-裝載機

強烈建議您使用模板引擎在 Oats~i 中渲染視圖。我的首選是車把。 (了解更多關於車把的資訊)

要使用 webpack,我們需要安裝 handbars-loader 作為開發依賴項。這將允許我們使用車把模板在應用程式內生成和渲染我們的視圖。

奔跑

npm install --save-dev handlebars-loader

安裝 HTML 載入器

為了建立伺服器端視圖,基本 Oats~i 設定使用 html-loader 和 html-webpack-plugin 的組合。讓我們先安裝 html-loader 函式庫作為開發依賴項。

奔跑

npm install --save-dev html-loader

安裝 HTML-Webpack-Plugin

html-webpack-plugin 函式庫允許我們使用 webpack 為我們的應用程式輸出伺服器端視圖。它與 html-loader 結合使用。將其安裝為開發依賴項。

奔跑

npm install --save-dev html-webpack-plugin

安裝 Babel-Loader

Babel-loader 將使用 webpack 載入和轉換我們的 JavaScript 檔案。將其安裝為開發依賴項。

奔跑

npm install --save-dev babel-loader

安裝樣式載入器和 CSS 載入器

Style-loader 和 css-loader 會將我們的 css 匯入作為樣式表注入到由 html-loader 和 html-webpack-plugin 產生的 html 檔案中。安裝這些載入器作為開發依賴項。

奔跑

npm install --save-dev style-loader

npm install --save-dev css-loader

安裝 Webpack-Merge

Webpack-merge 將允許我們合併多個 webpack 配置文件,從而使我們能夠以最佳方式建立我們的設定檔以適合我們的專案設定。安裝此程式庫作為開發依賴項。

奔跑

npm install --save-dev webpack-merge

Install Express-Handlebars

Express-handlebars will allow us to emulate server-side rendering in development using handlebars view files outputted by our webpack configuration, using html-loader and html-webpack-plugin. Install this library as a development dependency.

Run

npm install --save-dev express-handlebars

Create Webpack Configuration Files

At the root of your project’s directory, create a new folder and call it “webpack-configs”.

Build a Web App with Oats~i – Setting Up

Navigate into this folder and create two new folders inside it named “main” and “oats~i”.

Your folder structure should now look like this:

Build a Web App with Oats~i – Setting Up

Now, navigate into “oats~i” and create two more folders named “default” and “main”.

Your folder structure should now look like this:

Build a Web App with Oats~i – Setting Up

------

The “default” folder will hold the default webpack configuration needed by Oats~i to have it’s webpack-dependent functions work. Currently, that is code splitting and lazy loading for fragments.

The “main” folder will hold the webpack configuration for loaders used and recommended by Oats~i. These are the loaders we installed in the “install dependencies” stage. Feel free to edit this configuration later if you want to change loaders.

------

Navigate to the “default” folder and create a new file called “webpack.config.js”

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code inside it.

//@ts-check
const DefaultOats_iConfig = {

    optimization: {

        splitChunks: {

            minSize: 0, //Minimum size, in bytes, for a chunk to be generated.
            minSizeReduction: 1, //Minimum size reduction to the main chunk (bundle), in bytes, needed for a chunk to be generated.
            minChunks: 2,
            cacheGroups: {

                commons: {

                    chunks: "async", //Allow chunks to be shared between sync and async
                }
            }
        }
    }
}

module.exports = DefaultOats_iConfig;

Now, navigate back to the “oats~i” folder and navigate into “main”.

Create a new file and name it “webpack.config.js”.

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code inside.

//@ts-check
/**
 * Contains loaders
 */
const DefaultOats_iLoadersConfig = {

    module: {

        rules: [

            {
                test: /\.(html|sv.hbs|p.hbs)$/,
                use: [
                        {
                            loader: "html-loader",
                            options: {
                                minimize: false
                            }
                        }
                ]
            },
            {
                test: /\.(hbs)$/,
                exclude: /\.(sv.hbs|p.hbs)/,
                use: [
                    {
                        loader: "handlebars-loader",
                        options: {
                            inlineRequires: "./assets"
                        }
                    }
                ]
            },
            {
                test: /\.(js)$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "babel-loader"
                    }
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                type: 'asset/resource',
            },
            {
                test: /\.css$/,
                use: [

                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
}

module.exports = DefaultOats_iLoadersConfig;

We’re done setting up the core webpack configuration for Oats~i. Now, we need to merge them in a common configuration file that we’ll use project-wide.

Now, navigate back to the “oats~i” folder then back to the “webpack-configurations” folder. Now navigate into “main”.

Create a new file and name it “webpack.config.js”.

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code inside.

//@ts-check
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const DevServerMiddlewareConfig = require("../../proxy-server/proxy_server");
//The folder we'll have our assets emitted after build
const DIST_PATH_PUBLIC_ASSETS = "../../dist/public";
const { merge } = require("webpack-merge");
const DefaultOats_iConfig = require("../oats~i/default/webpack.config");
const DefaultOats_iLoadersConfig = require("../oats~i/main/webpack.config");

//@ts-expect-error
module.exports = merge(DefaultOats_iConfig, DefaultOats_iLoadersConfig, {

    mode: "development",
    devtool: "eval-source-map",
    output: {

        //Where we'll output public assets
        path: path.resolve(__dirname, `${DIST_PATH_PUBLIC_ASSETS}`),
        publicPath: "/",
        assetModuleFilename: 'assets/[name][ext]',
        filename: "js/[name].dev_bundle.js",
        clean: true
    },
    entry: {

        //The main entry (app)
        index: "./src/app/index/scripts/index.js",
    },
    plugins: [
        new HtmlWebpackPlugin({

            template: "./src/server/home/home.sv.hbs",
            filename: "../views/home.hbs",
            chunks: ["index"],
            minify: false
        })
    ],
    devServer: {

        devMiddleware: {

            writeToDisk: true, //Because of our configured server
        },
        setupMiddlewares: DevServerMiddlewareConfig,
    }
});

Now, we should be done setting up our webpack configurations that’s just fine to run an Oats~i project.

Update package.json

Navigate back to your project’s root folder. Open package.json, look for the “scripts” line, and add the following line after “test” (remember to separate with a comma).

"dev": "webpack-dev-server --config ./webpack-configs/main/webpack.config.js"

Build a Web App with Oats~i – Setting Up

Set Up Dev Server Middlewares

In our final webpack configuration file, we specified a middlewares file for the webpack dev server under

setupMiddlewares: DevServerMiddlewareConfig

Under normal circumstances, you don’t need this setup. You can simply write your server view files in html format, use html-loader and html-webpack-plugin to produce them, and have them directly served by webpack-dev-server during development.

However, as you’ll come to learn later, this is not the best setup for building an Oats~i project that’s already primed for server-side rendering. The server-side files are already in html format, meaning they can’t be easily templated with data before being rendered to the client on the initial request.

To accommodate that, the default Oats~i setup ensures you’re creating template files for your server views that will be easy to render with data from your server every time a client requests for a fresh page.

Our dev server middlewares setup will allow us to mimic such as setup on the actual server, for our development environment.

With its default setup, you don’t need to update it for new fragments that you add to the project, as long as you’re not interested in having them server-side rendered. However, once you get to the point where you want to have server-side rendering and test it in development, setting things up will be much easier and faster, without a change in file formats you’ve already used across the project.

Let’s Set Up this Config

At your project’s root directory, create a new folder and name it “proxy-server”. Inside this new folder, create a file and name it “proxy_server.js”

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code:

//@ts-check
const express = require("express");
const path = require("path");
const hbs = require("express-handlebars");

const DevServerMiddlewareConfig = (middlewares, devServer) => {

    /**
     * @type {import("express").Application}
     */
    const app = devServer.app;

    //Configure the view engine
    app.set("views", path.resolve(__dirname, "../dist/views"));
    app.set("view engine", "hbs");
    app.engine("hbs", hbs.engine({

        extname: "hbs",
        layoutsDir: path.resolve(__dirname, "../dist/views"),
        partialsDir: path.resolve(__dirname, "../dist/views/partials")
    }));

    //for json
    app.use(express.json());
    //I think params and queries
    app.use(express.urlencoded({ extended: false }));
    //static
    app.use(express.static(path.resolve(__dirname, "../dist/public")));

    //My middlewares
    //Capture all
    app.get("/*", (req, res, next) => {

        res.render("home", {
            layout: "home"
        });
    });

    return middlewares;
}

module.exports = DevServerMiddlewareConfig;

This configuration will capture all requests to the dev server and return the home.hbs layout file. You can rename this later to your file’s actual name once you start creating your own Oats~i project and leave it as is as long as you’ll not require server-side rendering for any of your fragments.

Create jsconfig.json

Oats~i is typed using a combination of typescript declaration files and JSDoc. There’s a slight issue where types may not always reflect correctly when using the framework, slightly hurting the developer experience.

Instead of refactoring over 100 files and thousands of lines of code, I’ve found a way to make typescript and intellisense (at least in VSCode) to understand the JSDoc types used in Oats~i.

To do this, navigate to your project’s root folder. Create a file named “jsconfig.json”.

Build a Web App with Oats~i – Setting Up

Open it and paste the code below:

{
    "include": [
        "*/**/*.js",
        "**/*",
        "/**/*",
        "node_modules/oats-i" //to get type definitions for oats-i in your project
    ],
}

NOTE: This bit comes automatically with the cli, so don’t do this for an Oats~i project you’ve set up using the cli.

Create Starter Project Files

Let’s now put everything together and create our starter project files to run an Oats~i app for the first time.

Server-side Base Layout

Navigate to your project’s root folder and create a new folder named “src”. This folder will contain all of our project’s source files.

Inside the “src” folder, create two folders named “app” and “server”.

Build a Web App with Oats~i – Setting Up

Navigate to the “server” folder and create a new folder named “home”. Inside the “home” folder, create a new file and name it “home.sv.hbs”

Build a Web App with Oats~i – Setting Up

Open the file and paste the code below:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home - My Oats~i App</title>
</head>
<body>
    <app-root id="my-app">
       <div id="nav">
            <a href="/" class="home-link">Home</a>
        </div>
        <main-fragment>
        </main-fragment>
    </app-root>
</body>
</html>

App Files

Now navigate back to “src”. Get into the “app” folder and create two folders name “fragments” and “index”.

Build a Web App with Oats~i – Setting Up

Navigate into the “index” folder and create two folders named “scripts” and “styles”.

Build a Web App with Oats~i – Setting Up

Inside the “scripts” folder, create a new folder called “routing-info”. Inside “routing-info” create two files named “app_main_nav_info.js” and “app_routing_info.js”

Build a Web App with Oats~i – Setting Up

Main Navigation info

Open “app_main_nav_info.js” and paste the following code:

//@ts-check
import MainNavigationInfoBuilder from "oats-i/router/utils/nav-info/main_nav_info_builder";

const AppMainNavInfo = MainNavigationInfoBuilder.buildMainNavigationInfo([
    {
        selector: "home-link",
        defaultRoute: "/",
        baseActiveRoute: "/",
    }
]);

export default AppMainNavInfo;

Main Routing Info

Now open “app_routing_info.js” and paste the following code:

//@ts-check
import RoutingInfoUtils from "oats-i/router/utils/routing-info/routing_info_utils";
import AppMainNavInfo from "./app_main_nav_info";
import homeMainFragmentBuilder from "../../../fragments/home/scripts/home_main_fragment";

const AppRoutingInfo = RoutingInfoUtils.buildMainRoutingInfo([

    {
        route: "/",
        target: homeMainFragmentBuilder,
        nestedChildFragments: null
    }
], AppMainNavInfo);

export default AppRoutingInfo;

Index.css

We’ll create an index.css file for a special reason, which MUST be replicated across all your Oats~i projects if you want consistent behavior.

Navigate back to the “index” folder, and create a new folder named “styles”. Inside the folder, create a new file called “index.css”

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code:

/* Crucial styling to allow specially structured A links to still have clicks intercepted by router. */
/* Carry over to your project */
a *:not([click-override=true]){ 

    pointer-events: none 
}

What this css code does is remove pointer events from elements nested inside an A tag, to ensure the browser doesn’t intercept it before Oats~i does. It also gives you, the developer, the freedom to override this behavior using the attribute click-override=true on any element nested within an A tag.

However, expect Oats~i, at its current state, not to intercept links from an A tag with a child element having that attribute.

This means that you can safely write A tags without any modification or special attributes for Oats~i to automatically intercept them and navigate your app locally. You only add special attributes when you want to stop this behavior and have the browser manually route the website.

Carry over this css directive in all Oats~i projects you create. If you use the cli, you’ll find it already in index.css.

Index.js

Navigate back to “scripts” (inside index) and create a new file named “index.js”.

Build a Web App with Oats~i – Setting Up

Open the file and paste the following code.

//@ts-check
//import styles
import "../styles/index.css";
import AppStateManager from "oats-i/base-history/app_state_manager";
import appRoot from "oats-i/bin/app_root"
import AppRoutingInfo from "./routing-info/app_routing_info";
import MainRouter from "oats-i/router/main_router";
import AppMainNavInfo from "./routing-info/app_main_nav_info";

function initApp(){

    const appStateManager = new AppStateManager(AppRoutingInfo);
    appRoot.initApp(appStateManager, new MainRouter(AppRoutingInfo, appStateManager, (args) => {}, "", async (url) => {

        return {

            canAccess: true,
            fallbackRoute: "/"
        }
    }), { template: null, mainNavInfos: AppMainNavInfo }, "");
}

initApp();

Fragments

Navigate back to the “app” folder. Navigate into “fragments” and create a new folder named “home”.

Inside “home”, create a new folder named “scripts”. Inside “scripts”, create a new file named “home_main_fragment.js”.

Build a Web App with Oats~i – Setting Up

Open the file and paste the code below.

//@ts-check
import AppFragmentBuilder from "oats-i/fragments/builder/AppFragmentBuilder";
import AppMainFragment from "oats-i/fragments/AppMainFragment"

class HomeMainFragment extends AppMainFragment{

    async initializeView(cb){

        //@ts-expect-error cannot find module (for view)
        const uiTemplate = require("../views/home_fragment.hbs")();
        this.onViewInitSuccess(uiTemplate, cb);
    }
}

const homeMainFragmentBuilder = new AppFragmentBuilder(HomeMainFragment, {

    localRoutingInfos: null,
    viewID: "home-main-fragment",
});
export default homeMainFragmentBuilder;

Now navigate back to “home” and create a new folder called “views”. Inside “views”, create a new file and name it “home_fragment.hbs”

Build a Web App with Oats~i – Setting Up

Open file and paste the following code:

<h1>Home Fragment<h1/>

Test the Configuration

Navigate to your project’s root. Open the terminal and run

npm run dev

This will start the webpack-dev-server which will bundle the files and run Oats~i. If you open the browser at the url shown in the terminal (often is localhost:8080) and see a page with “Home Fragment” showing, your project has been successfully set up and Oats~i is working fine.

Configuration Extensibility

Regardless of whether you’ve manually set up an Oats~i project or used the cli, there are configuration flexibilities you can enjoy thanks to Oats~i running on top of Webpack.

Basically, apart from the default Oats~i webpack configuration, you can change anything else to your liking as long as you understand webpack, plugins, and loaders, and how they’ll affect your project.

For instance, you can have a production configuration that will use MiniCssExtractPlugin to extract your css into files that will be added to the final html-webpack-plugin output. You can use advanced babel configurations and even switch handlebars-loader for a loader that suits your favorite templating engine.

However, the default setup provided by Oats~i is good enough for most projects. Later on in the tutorials, we’ll add a new configuration to create the final production build with key features such as minification.

Further Reading

I encourage you to learn about Webpack, why it’s needed, and how you can configure it, to make the most out of Oats~i and other projects you may have using Webpack as a bundler.

Sign Up and Follow for the Next Tutorial

That’s it for setting up Oats~i for your project. If you’re working on a new project, just use the cli. It’s easier, faster, and will directly load you into a beautiful starter project that you can inspect and start getting ideas of how to setup a full project with view, styling, and script files in Oats~I, before we start doing that together.

In the next tutorial, we’ll create our first simple project in Oats~i, where we’ll start learning what routing infos, nav infos, and fragments are in Oats~i.

Leave a like and follow to get notified when the next tutorial drops.

See you then.

Support Oats~i

You can support the development of Oats~i through Patreon or buy me a coffee.

以上是使用 Oats~i 建立 Web 應用程式 – 設定的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn