From bd0dbd4db87b754d885fa4d239ca6a6690712501 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 24 Sep 2023 23:42:16 +0800 Subject: [PATCH] [add] Page Builder typescript support --- script/script.go | 2 +- sui/core/block.go | 40 ++++++++++++++++++++++++++--- sui/storages/local/block.go | 22 ++++++++++++---- sui/storages/local/template.go | 2 ++ sui/storages/local/template_test.go | 28 ++++++++++++++++++-- 5 files changed, 83 insertions(+), 11 deletions(-) diff --git a/script/script.go b/script/script.go index 34c7e739..2c8c08a6 100644 --- a/script/script.go +++ b/script/script.go @@ -11,7 +11,7 @@ import ( // Load 加载共享库 func Load(cfg config.Config) error { - exts := []string{"*.js"} + exts := []string{"*.js", "*.ts"} err := application.App.Walk("scripts", func(root, file string, isdir bool) error { if isdir { return nil diff --git a/sui/core/block.go b/sui/core/block.go index 58d1d039..20876ec1 100644 --- a/sui/core/block.go +++ b/sui/core/block.go @@ -3,21 +3,55 @@ package core import ( "fmt" "strings" + + "github.com/evanw/esbuild/pkg/api" + "github.com/yaoapp/gou/runtime/transform" ) // Compile compile the block func (block *Block) Compile() (string, error) { + // Typescript is the default language + // Typescript + if block.Codes.TS.Code != "" { + varName := strings.Replace(block.ID, "-", "_", -1) + ts := strings.Replace(block.Codes.TS.Code, "export default", fmt.Sprintf("window.block__%s =", varName), 1) + if block.Codes.HTML.Code != "" && !strings.Contains(block.Codes.TS.Code, "content:") { + html := strings.ReplaceAll(block.Codes.HTML.Code, "`", "\\`") + ts = strings.Replace(ts, "{", fmt.Sprintf("{\n content: `%s`,", html), 1) + } + + js, err := transform.TypeScript(ts, api.TransformOptions{ + Target: api.ESNext, + MinifyWhitespace: true, + MinifyIdentifiers: true, + MinifySyntax: true, + }) + + if err != nil { + return "", err + } + block.Compiled = js + return js, nil + } + + // Javascript if block.Codes.JS.Code == "" { return "", fmt.Errorf("Block %s has no JS code", block.ID) } - js := strings.Replace(block.Codes.JS.Code, "export default", fmt.Sprintf("window.block__%s =", block.ID), 1) + varName := strings.Replace(block.ID, "-", "_", -1) + js := strings.Replace(block.Codes.JS.Code, "export default", fmt.Sprintf("window.block__%s =", varName), 1) if block.Codes.HTML.Code != "" && !strings.Contains(block.Codes.JS.Code, "content:") { html := strings.ReplaceAll(block.Codes.HTML.Code, "`", "\\`") js = strings.Replace(js, "{", fmt.Sprintf("{\n content: `%s`,", html), 1) } - block.Compiled = js - return js, nil + minified, err := transform.MinifyJS(js) + if err != nil { + return "", err + } + + block.Compiled = minified + return minified, nil } diff --git a/sui/storages/local/block.go b/sui/storages/local/block.go index 5e287041..635ca9d7 100644 --- a/sui/storages/local/block.go +++ b/sui/storages/local/block.go @@ -8,12 +8,24 @@ import ( func (block *Block) Load() error { root := filepath.Join(block.tmpl.Root, "__blocks") - jsFile := filepath.Join(root, block.Codes.JS.File) - jsCode, err := block.tmpl.local.fs.ReadFile(jsFile) - if err != nil { - return err + + // Type script is the default language + tsFile := filepath.Join(root, block.Codes.TS.File) + if exist, _ := block.tmpl.local.fs.Exists(tsFile); exist { + tsCode, err := block.tmpl.local.fs.ReadFile(tsFile) + if err != nil { + return err + } + block.Codes.TS.Code = string(tsCode) + + } else { + jsFile := filepath.Join(root, block.Codes.JS.File) + jsCode, err := block.tmpl.local.fs.ReadFile(jsFile) + if err != nil { + return err + } + block.Codes.JS.Code = string(jsCode) } - block.Codes.JS.Code = string(jsCode) htmlFile := filepath.Join(root, block.Codes.HTML.File) if exist, _ := block.tmpl.local.fs.Exists(htmlFile); exist { diff --git a/sui/storages/local/template.go b/sui/storages/local/template.go index e8f56b4b..6673c393 100644 --- a/sui/storages/local/template.go +++ b/sui/storages/local/template.go @@ -160,6 +160,7 @@ func (tmpl *Template) getBlock(id string) (core.IBlock, error) { } jsFile := filepath.Join("/", id, "main.js") + tsFile := filepath.Join("/", id, "main.ts") htmlFile := filepath.Join("/", id, "main.html") block := &Block{ tmpl: tmpl, @@ -168,6 +169,7 @@ func (tmpl *Template) getBlock(id string) (core.IBlock, error) { Codes: core.SourceCodes{ HTML: core.Source{File: htmlFile}, JS: core.Source{File: jsFile}, + TS: core.Source{File: tsFile}, }, }, } diff --git a/sui/storages/local/template_test.go b/sui/storages/local/template_test.go index 39fb0429..f82daa45 100644 --- a/sui/storages/local/template_test.go +++ b/sui/storages/local/template_test.go @@ -82,17 +82,20 @@ func TestTemplateBlocks(t *testing.T) { assert.Equal(t, "columns-two", blocks[0].(*Block).ID) assert.Equal(t, "/columns-two/main.html", blocks[0].(*Block).Codes.HTML.File) assert.Equal(t, "/columns-two/main.js", blocks[0].(*Block).Codes.JS.File) + assert.Equal(t, "/columns-two/main.ts", blocks[0].(*Block).Codes.TS.File) assert.Equal(t, "hero", blocks[1].(*Block).ID) assert.Equal(t, "/hero/main.html", blocks[1].(*Block).Codes.HTML.File) assert.Equal(t, "/hero/main.js", blocks[1].(*Block).Codes.JS.File) + assert.Equal(t, "/hero/main.ts", blocks[1].(*Block).Codes.TS.File) assert.Equal(t, "section", blocks[2].(*Block).ID) assert.Equal(t, "/section/main.html", blocks[2].(*Block).Codes.HTML.File) assert.Equal(t, "/section/main.js", blocks[2].(*Block).Codes.JS.File) + assert.Equal(t, "/section/main.ts", blocks[2].(*Block).Codes.TS.File) } -func TestTemplateBlock(t *testing.T) { +func TestTemplateBlockJS(t *testing.T) { tests := prepare(t) defer clean() @@ -109,6 +112,27 @@ func TestTemplateBlock(t *testing.T) { assert.Equal(t, "columns-two", block.(*Block).ID) assert.NotEmpty(t, block.(*Block).Codes.HTML.Code) assert.NotEmpty(t, block.(*Block).Codes.JS.Code) - assert.Contains(t, block.(*Block).Compiled, "window.block__columns-two") + assert.Contains(t, block.(*Block).Compiled, "window.block__columns_two") assert.Contains(t, block.(*Block).Compiled, `
`) +}