Saturday, 17 June 2023

Adonis web using Inertia

- Install Adonisjs Web

yarn create adonis-ts-app hello-world
 
❯ Select the project structure · web
❯ Enter the project name · hello-world
❯ Setup eslint? (y/N) · false
❯ Configure webpack encore for compiling frontend assets? (y/N) · true

- Install inertia 

yarn add  @eidellev/inertia-adonisjs
node ace configure @eidellev/inertia-adonisjs
❯ Enter the `.edge` view file you would like to use as your root template · app
❯ Would you like to use SSR? (y/N) · false
❯ Which client-side adapter would you like to set up? · @inertiajs/react
[ wait ]  Installing dependencies: @inertiajs/react, react, react-dom, @types/react, @types/react-dom ..

-  Register Inertia middleware

// start/kernel.ts
Server.middleware.register([
() => import('@ioc:Adonis/Core/BodyParser'),
() => import('@ioc:EidelLev/Inertia/Middleware'),
]); 

- Configure Webpack-Encore for React in Typescript: By default Webpack Encore (AdonisJS asset bundler) is configured for JS, we want to use TS in our app, let's configure support for TS.

yarn add ts-loader @babel/preset-react --save-dev 
=> have file  resources\views\app.edge.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="/favicon.ico">
@entryPointStyles('app')
@entryPointScripts('app')
<title>csr-adonis-inertia-react</title>
</head>
<body>
@inertia
</body>
</html>

- Modify the entrypoint, edit webpack.config.js changing the following:

// webpack.config.js
Encore.addEntry('app', './resources/js/app.js')
into:
Encore.addEntry('app', './resources/js/app.tsx')
Encore.enableTypeScriptLoader()
Encore.enableReactPreset()

// Rename ./resources/js/app.js to ./resources/js/app.tsx.
resources/js/app.tsx.

// Create a file ./resources/js/tsconfig.json, with contents:
{
"include": ["**/*"],
"compilerOptions": {
"lib": ["DOM"],
"jsx": "react",
"esModuleInterop": true
}
}

// tsconfig.json at the root of your project add the following to the "compilerOptions" section
"lib": ["DOM"],
"jsx": "react",

- Configure the app entrypoint file resources/js/app.tsx to contain

import { InertiaApp } from '@inertiajs/inertia-react'
import React from 'react'
import ReactDOM from 'react-dom'
import '../css/app.css'

// initial page object with props from server
const root = document.getElementById('app')
const page = JSON.parse(root?.dataset.page as string)

// dynamically load specified page component from "resources/js/Pages/." dir
async function resolver(pageName) {
const module = await import(`./Pages/${pageName}`)
return module.default
}

function App() {
return <InertiaApp initialPage={page} resolveComponent={resolver} initialComponent={''} />
}

ReactDOM.render(<App />, root)

- Create a test component

import React from 'react'

const Test = ({exampleProp}) => <div>Hello world, from {exampleProp}!)</div>

export default Test

- Create a test route

// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'

Route.get('/test', async ({ inertia }) => {
return inertia.render('Test', { exampleProp: 'inertia' })
})

* show result

node ace serve --watch

* Errors

- TS2688: Cannot find type definition file for 'pino-std-serializers'.

yarn add @types/pino-std-serializers

- TS2307: Cannot find module '@inertiajs/inertia-react'

yarn add @inertiajs/inertia-react

-  Error: Can't resolve '@inertiajs/inertia'

yarn add @inertiajs/inertia

- Warning: React-dom.development.js:86: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17

// update resources/js/app.tsx
import { InertiaApp } from '@inertiajs/inertia-react';
import React from 'react';
import { createRoot } from 'react-dom/client';
import '../css/app.css';

// initial page object with props from server
const root = document.getElementById('app');
const page = JSON.parse(root?.dataset.page as string);

// dynamically load specified page component from "resources/js/Pages/." dir
async function resolver(pageName) {
const module = await import(`./Pages/${pageName}`);
return module.default;
}

function App() {
return <InertiaApp initialPage={page} resolveComponent={resolver} initialComponent={''} />;
}

createRoot(root).render(<App />);

Source git: https://github.com/phong2018/learning-adonisjs-web-inertia

Reference: guide

Thank you.  

No comments:

Post a Comment

Golang Advanced Interview Q&A