frontend

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2022 License: Apache-2.0 Imports: 21 Imported by: 0

README

frontend-go

Go Reference

SPA (Single Page Application) style web application frontend helper for go server. This package works with Next.js, Vue.js, SvelteKit, Solid.js.

Development Mode

It runs dev server behind go server. It works as reverse proxy. You can get all features that the web framework dev server provides (hot module replacement and so on).

Development Mode

Production Mode

It gets prebuilt assets (HTML, JS, CSS) from go's embed. Basically, all SPA needs to fallback to index.html when there is not have assets.

Release Mode

Integration

frontend-go assumes the following structure. Important points are the following:

  • There is frontend project folder named frontend.
  • There is release.go at the parent folder of frontend folder.
  • Add frontend-go's handler to your web server.
awesome-your-web-app
├── LICENSE
├── README.md
├── cmd
│   └── server
│      └── main.go    # Add frontend-go's handler
├── go.mod
├── go.sum
├── api.go
├── release.go        # You should add this
└── frontend          # frontend project (Next.js, Vue.js, SvelteKit, Solid.js)
    └── package.json

release.go has the following code.

//go:build release

package webapp

// ↓this folder is decided by your frontend framework

//go:embed frontend/build/*
var asset embed.FS

init() {
    frontend.SetFrontAsset(asset, frontend.Opt{
        FrameworkType: frontend.NextJS, // select: NextJS, VueJS, SvelteKit, SolidJS
    })
}

Use with net/http:

package main

func handler() http.Handler {
    mux := http.NewServeMux()
    mux.Handle("/api", YourAPIHandler)
    mux.Handle("/", frontend.MustNewSPAHandler())
    return mux
}

Use with chi:


import (
    "github.com/go-chi/chi/v5"
)

func handler() http.Handler  {
    r := chi.NewRouter()
    r.Post("/api", YourAPIHandler)
    r.NotFound(frontend.MustNewHandlerFunc())
    return r
}
# Development mode
$ go run main.go

# Production build
$ go build -tags release

Web Frameworks Specific Instructions

Next.js 12

frontend-go assumes Next.js's static generation result (that does'n need Node.js/bun to run).

To start project with Next.js, init project like this:

$ go mod init yourapp
$ mkdir -p cmd/yourapp
$ npx create-next-app@latest --ts frontend

To enable static generation, add unoptimized flag to next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  experimental: { // Add here
    images: {
      unoptimized: true,
    }
  }
}

You should build frontend project by using the following commands.

$ npm run build
$ npm exec next export

The go:embed directive comment should be the following by default:

//go:embed frontend/out/*
//go:embed frontend/out/_next/static/*/*
//go:embed frontend/out/_next/static/chunks/pages/*.js
var asset embed.FS

init() {
    frontend.SetFrontAsset(asset, frontend.Opt{
        FrameworkType: frontend.NextJS,
    })
}
Vue.js

To start project with Vue.js, init project like this:

$ go mod init yourapp
$ mkdir -p cmd/yourapp
$ vue create frontend

You should build frontend project by using the following commands.

$ npm run build

The go:embed directive comment should be the following by default:

//go:embed frontend/dist/*
var asset embed.FS

init() {
    frontend.SetFrontAsset(asset, frontend.Opt{
        FrameworkType: frontend.VueJS,
    })
}
SvelteKit

Default SvelteKit provides frontend program that requires Node.js to run. To work with this module, you should configure the front end project with static site mode.

$ go mod init yourapp
$ mkdir -p cmd/server
$ npm create yourapp@latest frontend

To modify front end site, add static-adaptor.

$ npm install @sveltejs/adapter-static
import adapter from '@sveltejs/adapter-static'; // Modify here

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: preprocess(),

  kit: {
    adapter: adapter({       // Modify here for static HTML/JS generation
      fallback: 'index.html'
    }),
    prerender: {             // Modify here for SPA mode
      default: false
    },
    trailingSlash: 'always'  // Modify here
  }
};

export default config;

You should build frontend project by using the following commands.

$ npm run build

The go:embed directive comment should be the following by default:

//go:embed frontend/build/*
var asset embed.FS

init() {
    frontend.SetFrontAsset(asset, frontend.Opt{
        FrameworkType: frontend.SvelteKit,
    })
}
Solid.js
$ go mod init yourapp
$ mkdir -p cmd/server
$ npx degit solidjs/templates/ts frontend

You should build frontend project by using the following commands.

$ npm run build

The go:embed directive comment should be the following by default:

//go:embed frontend/dist/*
var asset embed.FS

init() {
    frontend.SetFrontAsset(asset, frontend.Opt{
        FrameworkType: frontend.SolidJS,
    })
}

Configuration

frontend.SetFrontAsset() (for production), frontend.SetOption() (other usage) accept option that modifies package's behavior.

If you put frontend project at frontend folder and doesn't change npm scripts, you don't have to modify configuration.

//go:build release

:

//go:embed frontend/build/*
var asset embed.FS

handler := frontend.SetFrontAsset(assets, frontend.Opt{
    FrontEndFolder: "frontend",              // Frontend application folder that contains package.json. default value is "frontend"
    ProjectType:    frontend.AutoDetect,     // NextJS, SvelteKit, VueJS, SolidJS is available
    SkipRunningDevServer:     false,         // Skip running dev server even if development mode
    DistFolder:     "",                      // Specify dist folder instead of auto detect
    Port:           0,                       // Specify port instead of auto detect
    DevelopmentCommand: "npm run dev",       // Specify dev server command instead of auto detect
    FallbackPath:       string               // Specify fallback file path. Default is "index.html"
})

For development mode, this package tries to configure package as much as possible, including framework type.

If you want to set option for development mode, add the following file and set option:

//go:build !release

package webapp

init() {
    frontend.SetOption(frontend.Opt{
        SkipRunningDevServer: true,
    })
}

Credits

Yoshiki Shibukawa

License

Apache 2

Documentation

Overview

Package frontend helps development Go web server that uses SPA (Single Page Application) style web frontend.

In development mode, it runs frontend's dev server automatically.

In production mode, it returns prebuilt assets from go:embed

This package works with Next.js, Vue.js, SvelteKit, Solid.js.

Index

Constants

This section is empty.

Variables

View Source
var ErrDir = errors.New("path is dir")
View Source
var ErrPackageJsonNotFound = errors.New("package.json not found")

Functions

func MustNewSPAHandler

func MustNewSPAHandler(ctx context.Context) http.Handler

MustNewSPAHandler is similar to NewSPAHandler but this calls panic when error.

func MustNewSPAHandlerFunc

func MustNewSPAHandlerFunc(ctx context.Context) http.HandlerFunc

MustNewSPAHandlerFunc is similar to NewSPAHandlerFunc but this calls panic when error.

func NewSPAHandler

func NewSPAHandler(ctx context.Context) (http.Handler, error)

NewSPAHandler is handler that handles SPA contents.

Use with net/http:

h, err := NewSPAHandler(ctx)
http.Handle("/", h)

func NewSPAHandlerFunc

func NewSPAHandlerFunc(ctx context.Context) (http.HandlerFunc, error)

NewSPAHandlerFunc is handler function that handles SPA contents.

Use with chi:

r := chi.NewRouter()
c, err := NewSPAHandlerFunc(ctx)
http.NotFound(h)

func SetFrontAsset

func SetFrontAsset(assets embed.FS, o Opt)

func SetOption

func SetOption(o Opt)

Types

type FrameworkType

type FrameworkType int
const (
	AutoDetect FrameworkType = iota
	NextJS
	VueJS
	SvelteKit
	SolidJS

	NotFound
)

func FrameworkTypeString

func FrameworkTypeString(s string) (FrameworkType, error)

FrameworkTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func FrameworkTypeValues

func FrameworkTypeValues() []FrameworkType

FrameworkTypeValues returns all values of the enum

func (FrameworkType) IsAFrameworkType

func (i FrameworkType) IsAFrameworkType() bool

IsAFrameworkType returns "true" if the value is listed in the enum definition. "false" otherwise

func (FrameworkType) String

func (i FrameworkType) String() string

type Mode

type Mode int
const (
	Development Mode = iota
	Release
)

func ModeString

func ModeString(s string) (Mode, error)

ModeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ModeValues

func ModeValues() []Mode

ModeValues returns all values of the enum

func (Mode) IsAMode

func (i Mode) IsAMode() bool

IsAMode returns "true" if the value is listed in the enum definition. "false" otherwise

func (Mode) String

func (i Mode) String() string

type Opt

type Opt struct {
	FrontEndFolderName   string        // Frontend application folder name that contains package.json. Default value is "frontend"
	FrontEndFolderPath   string        // Absolute frontend application folder that contains package.json.
	SkipRunningDevServer bool          // Even if development mode, frontend-go doesn't run dev server
	FrameworkType        FrameworkType // NextJS, VueJS, SvelteKit, SolidJS is available instead of auto detect
	DistFolder           string        // Specify dist folder instead of auto detect
	Port                 uint16        // Specify port instead of auto detect
	DevServerCommand     string        // Specify dev server command instead of auto detect
	FallbackPath         string        // Specify fallback file path. Default is "index.html"
}

Opt specifies frontend configuration.

frontend-go assumes frontend project is in "frontend" folder. And it tries to get other config as soon as possible. If you changed dist folder or build scripts and so on, use Opt and pass to NewSPAHandler, NewSPAHandlerFunc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL