Add asset path replacement in JavaScript and TypeScript code
This commit is contained in:
parent
b9208c920c
commit
5031904964
4 changed files with 90 additions and 32 deletions
|
|
@ -3,6 +3,7 @@ package core
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -43,11 +44,17 @@ func (page *Page) Build(option *BuildOption) (*goquery.Document, []string, error
|
||||||
doc.Selection.Find("head").AppendHtml(style)
|
doc.Selection.Find("head").AppendHtml(style)
|
||||||
|
|
||||||
// Add Script
|
// Add Script
|
||||||
script, err := page.BuildScript(option)
|
code, scripts, err := page.BuildScript(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
doc.Selection.Find("body").AppendHtml(script)
|
if scripts != nil {
|
||||||
|
for _, script := range scripts {
|
||||||
|
doc.Selection.Find("body").AppendHtml("\n" + `<script src="` + script + `"></script>` + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doc.Selection.Find("body").AppendHtml(code)
|
||||||
|
|
||||||
return doc, warnings, nil
|
return doc, warnings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +96,7 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
script, err := page.BuildScript(option)
|
code, _, err := page.BuildScript(option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +115,7 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
|
||||||
|
|
||||||
// Replace the slots
|
// Replace the slots
|
||||||
html, _ = Data(data).ReplaceUse(slotRe, html)
|
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 {
|
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
|
code := page.Codes.CSS.Code
|
||||||
|
|
||||||
|
// Replace the assets
|
||||||
if !option.IgnoreAssetRoot {
|
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 != "" {
|
if option.Namespace != "" {
|
||||||
|
|
@ -282,43 +293,65 @@ func (page *Page) BuildStyle(option *BuildOption) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("<style>\n%s\n</style>\n", res), nil
|
return fmt.Sprintf("<style type=\"text/css\">\n%s\n</style>\n", res), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildScript build the script
|
// 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 == "" {
|
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
||||||
return "", nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if page.Codes.TS.Code != "" {
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if option.Namespace == "" {
|
// Replace the assets
|
||||||
return fmt.Sprintf("<script>\n%s\n</script>\n", res), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("<script>\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(res))), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
code := page.Codes.JS.Code
|
|
||||||
if !option.IgnoreAssetRoot {
|
if !option.IgnoreAssetRoot {
|
||||||
code = strings.ReplaceAll(page.Codes.JS.Code, "@assets", option.AssetRoot)
|
code = AssetsRe.ReplaceAllFunc(code, func(match []byte) []byte {
|
||||||
}
|
return []byte(strings.ReplaceAll(string(match), "@assets", option.AssetRoot))
|
||||||
|
})
|
||||||
|
|
||||||
res, err := page.CompileJS([]byte(code), false)
|
if scripts != nil {
|
||||||
if err != nil {
|
for i, script := range scripts {
|
||||||
return "", err
|
scripts[i] = filepath.Join(option.AssetRoot, script)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if option.Namespace == "" {
|
if option.Namespace == "" {
|
||||||
return fmt.Sprintf("<script>\n%s\n</script>\n", res), nil
|
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("<script>\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(res))), nil
|
|
||||||
|
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
code, scripts, err := page.CompileJS([]byte(page.Codes.JS.Code), false)
|
||||||
|
if err != nil {
|
||||||
|
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("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTabToEachLine(input string, prefix ...string) string {
|
func addTabToEachLine(input string, prefix ...string) string {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@ import (
|
||||||
"github.com/yaoapp/kun/log"
|
"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
|
// Compile the page
|
||||||
func (page *Page) Compile(option *BuildOption) (string, error) {
|
func (page *Page) Compile(option *BuildOption) (string, error) {
|
||||||
|
|
||||||
|
|
@ -52,18 +59,36 @@ func (page *Page) Compile(option *BuildOption) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompileJS compile the javascript
|
// CompileJS compile the javascript
|
||||||
func (page *Page) CompileJS(source []byte, minify bool) ([]byte, error) {
|
func (page *Page) CompileJS(source []byte, minify bool) ([]byte, []string, error) {
|
||||||
jsCode := regexp.MustCompile(`import\s+.*;`).ReplaceAllString(string(source), "")
|
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 {
|
if minify {
|
||||||
minified, err := transform.MinifyJS(jsCode)
|
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
|
// CompileTS compile the typescript
|
||||||
func (page *Page) CompileTS(source []byte, minify bool) ([]byte, error) {
|
func (page *Page) CompileTS(source []byte, minify bool) ([]byte, []string, error) {
|
||||||
tsCode := regexp.MustCompile(`import\s+.*;`).ReplaceAllString(string(source), "")
|
|
||||||
|
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 {
|
if minify {
|
||||||
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{
|
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{
|
||||||
Target: api.ESNext,
|
Target: api.ESNext,
|
||||||
|
|
@ -71,12 +96,11 @@ func (page *Page) CompileTS(source []byte, minify bool) ([]byte, error) {
|
||||||
MinifyIdentifiers: true,
|
MinifyIdentifiers: true,
|
||||||
MinifySyntax: true,
|
MinifySyntax: true,
|
||||||
})
|
})
|
||||||
|
return []byte(jsCode), scripts, err
|
||||||
return []byte(jsCode), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{Target: api.ESNext})
|
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{Target: api.ESNext})
|
||||||
return []byte(jsCode), err
|
return []byte(jsCode), scripts, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompileCSS compile the css
|
// CompileCSS compile the css
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ type PageConfig struct {
|
||||||
// PageSetting is the struct for the page setting
|
// PageSetting is the struct for the page setting
|
||||||
type PageSetting struct {
|
type PageSetting struct {
|
||||||
Title string `json:"title,omitempty"`
|
Title string `json:"title,omitempty"`
|
||||||
|
Guard string `json:"guard,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
SEO *PageSEO `json:"seo,omitempty"`
|
SEO *PageSEO `json:"seo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -629,7 +629,7 @@ func (page *Page) AssetScript() (*core.Asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
jsCode, err := page.CompileTS(tsCode, false)
|
jsCode, _, err := page.CompileTS(tsCode, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -647,7 +647,7 @@ func (page *Page) AssetScript() (*core.Asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
jsCode, err = page.CompileJS(jsCode, false)
|
jsCode, _, err = page.CompileJS(jsCode, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue