diff --git a/sui/core/build.go b/sui/core/build.go
index e92bade0..340cae3f 100644
--- a/sui/core/build.go
+++ b/sui/core/build.go
@@ -3,6 +3,7 @@ package core
import (
"bufio"
"fmt"
+ "path/filepath"
"regexp"
"strings"
@@ -43,11 +44,17 @@ func (page *Page) Build(option *BuildOption) (*goquery.Document, []string, error
doc.Selection.Find("head").AppendHtml(style)
// Add Script
- script, err := page.BuildScript(option)
+ code, scripts, err := page.BuildScript(option)
if err != nil {
warnings = append(warnings, err.Error())
}
- doc.Selection.Find("body").AppendHtml(script)
+ if scripts != nil {
+ for _, script := range scripts {
+ doc.Selection.Find("body").AppendHtml("\n" + `` + "\n")
+ }
+ }
+ doc.Selection.Find("body").AppendHtml(code)
+
return doc, warnings, nil
}
@@ -89,7 +96,7 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
warnings = append(warnings, err.Error())
}
- script, err := page.BuildScript(option)
+ code, _, err := page.BuildScript(option)
if err != nil {
warnings = append(warnings, err.Error())
}
@@ -108,7 +115,7 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
// Replace the slots
html, _ = Data(data).ReplaceUse(slotRe, html)
- return html, style, script, warnings, nil
+ return html, style, code, warnings, nil
}
func (page *Page) parse(doc *goquery.Document, option *BuildOption, warnings []string) error {
@@ -267,8 +274,12 @@ func (page *Page) BuildStyle(option *BuildOption) (string, error) {
}
code := page.Codes.CSS.Code
+
+ // Replace the assets
if !option.IgnoreAssetRoot {
- code = strings.ReplaceAll(page.Codes.CSS.Code, "@assets", option.AssetRoot)
+ code = AssetsRe.ReplaceAllStringFunc(code, func(match string) string {
+ return strings.ReplaceAll(match, "@assets", option.AssetRoot)
+ })
}
if option.Namespace != "" {
@@ -282,43 +293,65 @@ func (page *Page) BuildStyle(option *BuildOption) (string, error) {
return "", err
}
- return fmt.Sprintf("\n", res), nil
+ return fmt.Sprintf("\n", res), nil
}
// BuildScript build the script
-func (page *Page) BuildScript(option *BuildOption) (string, error) {
+func (page *Page) BuildScript(option *BuildOption) (string, []string, error) {
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
- return "", nil
+ return "", nil, nil
}
if page.Codes.TS.Code != "" {
- res, err := page.CompileTS([]byte(page.Codes.TS.Code), false)
+ code, scripts, err := page.CompileTS([]byte(page.Codes.TS.Code), false)
if err != nil {
- return "", err
+ return "", nil, err
+ }
+
+ // Replace the assets
+ if !option.IgnoreAssetRoot {
+ code = AssetsRe.ReplaceAllFunc(code, func(match []byte) []byte {
+ return []byte(strings.ReplaceAll(string(match), "@assets", option.AssetRoot))
+ })
+
+ if scripts != nil {
+ for i, script := range scripts {
+ scripts[i] = filepath.Join(option.AssetRoot, script)
+ }
+ }
}
if option.Namespace == "" {
- return fmt.Sprintf("\n", res), nil
+ return fmt.Sprintf("\n", code), scripts, nil
}
- return fmt.Sprintf("\n", option.Namespace, addTabToEachLine(string(res))), nil
+ return fmt.Sprintf("\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
}
- code := page.Codes.JS.Code
- if !option.IgnoreAssetRoot {
- code = strings.ReplaceAll(page.Codes.JS.Code, "@assets", option.AssetRoot)
- }
-
- res, err := page.CompileJS([]byte(code), false)
+ code, scripts, err := page.CompileJS([]byte(page.Codes.JS.Code), false)
if err != nil {
- return "", err
+ return "", nil, err
+ }
+
+ // Replace the assets
+ if !option.IgnoreAssetRoot {
+ code = AssetsRe.ReplaceAllFunc(code, func(match []byte) []byte {
+ return []byte(strings.ReplaceAll(string(match), "@assets", option.AssetRoot))
+ })
+
+ if scripts != nil {
+ for i, script := range scripts {
+ scripts[i] = filepath.Join(option.AssetRoot, script)
+ }
+ }
}
if option.Namespace == "" {
- return fmt.Sprintf("\n", res), nil
+ return fmt.Sprintf("\n", code), scripts, nil
}
- return fmt.Sprintf("\n", option.Namespace, addTabToEachLine(string(res))), nil
+
+ return fmt.Sprintf("\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
}
func addTabToEachLine(input string, prefix ...string) string {
diff --git a/sui/core/compile.go b/sui/core/compile.go
index d5dd7718..0c2cc37f 100644
--- a/sui/core/compile.go
+++ b/sui/core/compile.go
@@ -8,6 +8,13 @@ import (
"github.com/yaoapp/kun/log"
)
+var quoteRe = "'\"`"
+var importRe = regexp.MustCompile(`import\s*\t*\n*[^;]*;`) // import { foo, bar } from 'hello'; ...
+var importAssetsRe = regexp.MustCompile(`import\s*\t*\n*\s*['"]@assets\/([^'"]+)['"];`) // import '@assets/foo.js'; or import "@assets/foo.js";
+
+// AssetsRe is the regexp for assets
+var AssetsRe = regexp.MustCompile(`[` + quoteRe + `]@assets\/([^` + quoteRe + `]+)[` + quoteRe + `]`) // '@assets/foo.js' or "@assets/foo.js" or `@assets/foo`
+
// Compile the page
func (page *Page) Compile(option *BuildOption) (string, error) {
@@ -52,18 +59,36 @@ func (page *Page) Compile(option *BuildOption) (string, error) {
}
// CompileJS compile the javascript
-func (page *Page) CompileJS(source []byte, minify bool) ([]byte, error) {
- jsCode := regexp.MustCompile(`import\s+.*;`).ReplaceAllString(string(source), "")
+func (page *Page) CompileJS(source []byte, minify bool) ([]byte, []string, error) {
+ scripts := []string{}
+ matches := importAssetsRe.FindAll(source, -1)
+ for _, match := range matches {
+ assets := AssetsRe.FindStringSubmatch(string(match))
+ if len(assets) > 1 {
+ scripts = append(scripts, assets[1])
+ }
+ }
+ jsCode := importRe.ReplaceAllString(string(source), "")
if minify {
minified, err := transform.MinifyJS(jsCode)
- return []byte(minified), err
+ return []byte(minified), scripts, err
}
- return []byte(jsCode), nil
+ return []byte(jsCode), scripts, nil
}
// CompileTS compile the typescript
-func (page *Page) CompileTS(source []byte, minify bool) ([]byte, error) {
- tsCode := regexp.MustCompile(`import\s+.*;`).ReplaceAllString(string(source), "")
+func (page *Page) CompileTS(source []byte, minify bool) ([]byte, []string, error) {
+
+ scripts := []string{}
+ matches := importAssetsRe.FindAll(source, -1)
+ for _, match := range matches {
+ assets := AssetsRe.FindStringSubmatch(string(match))
+ if len(assets) > 1 {
+ scripts = append(scripts, assets[1])
+ }
+ }
+
+ tsCode := importRe.ReplaceAllString(string(source), "")
if minify {
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{
Target: api.ESNext,
@@ -71,12 +96,11 @@ func (page *Page) CompileTS(source []byte, minify bool) ([]byte, error) {
MinifyIdentifiers: true,
MinifySyntax: true,
})
-
- return []byte(jsCode), err
+ return []byte(jsCode), scripts, err
}
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{Target: api.ESNext})
- return []byte(jsCode), err
+ return []byte(jsCode), scripts, err
}
// CompileCSS compile the css
diff --git a/sui/core/types.go b/sui/core/types.go
index 3f0ecd34..390e7e6a 100644
--- a/sui/core/types.go
+++ b/sui/core/types.go
@@ -244,6 +244,7 @@ type PageConfig struct {
// PageSetting is the struct for the page setting
type PageSetting struct {
Title string `json:"title,omitempty"`
+ Guard string `json:"guard,omitempty"`
Description string `json:"description,omitempty"`
SEO *PageSEO `json:"seo,omitempty"`
}
diff --git a/sui/storages/local/page.go b/sui/storages/local/page.go
index 21cbafc1..f16a423f 100644
--- a/sui/storages/local/page.go
+++ b/sui/storages/local/page.go
@@ -629,7 +629,7 @@ func (page *Page) AssetScript() (*core.Asset, error) {
return nil, err
}
- jsCode, err := page.CompileTS(tsCode, false)
+ jsCode, _, err := page.CompileTS(tsCode, false)
if err != nil {
return nil, err
}
@@ -647,7 +647,7 @@ func (page *Page) AssetScript() (*core.Asset, error) {
return nil, err
}
- jsCode, err = page.CompileJS(jsCode, false)
+ jsCode, _, err = page.CompileJS(jsCode, false)
if err != nil {
return nil, err
}