summaryrefslogtreecommitdiffstats
path: root/resources/resource_transformers
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2021-09-01 09:07:29 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2021-09-01 10:47:41 +0200
commitcf73cc2ececd4e794df09ea382a38ab18960d84e (patch)
tree2e457c014924feff4f5d8104fbcc78c856dbe20f /resources/resource_transformers
parent7d1f806ecb3621ae7b545a686d04de4568814055 (diff)
js: Fix import order for ./foo when both ./foo.js and ./foo/index.js exists
This is in line with how both Node and ESBuild's native import resolver does it. The ambiguous situations above were discovered trying to build AlpineJS v3. Note that the above was never an issue if you used `./foo.js` and similar to import the component. Fixes #8945
Diffstat (limited to 'resources/resource_transformers')
-rw-r--r--resources/resource_transformers/js/options.go23
-rw-r--r--resources/resource_transformers/js/options_test.go50
2 files changed, 69 insertions, 4 deletions
diff --git a/resources/resource_transformers/js/options.go b/resources/resource_transformers/js/options.go
index d1359ebda..9d2bb2e70 100644
--- a/resources/resource_transformers/js/options.go
+++ b/resources/resource_transformers/js/options.go
@@ -149,6 +149,10 @@ func resolveComponentInAssets(fs afero.Fs, impPath string) *hugofs.FileMeta {
// We assume that imports of JSON, CSS etc. will be using their full
// name with extension.
for _, ext := range []string{".js", ".ts", ".tsx", ".jsx"} {
+ if strings.HasSuffix(impPath, ext) {
+ // Import of foo.js.js need the full name.
+ return nil
+ }
if fi, err := fs.Stat(base + ext); err == nil {
return fi.(hugofs.FileMetaInfo).Meta()
}
@@ -160,7 +164,21 @@ func resolveComponentInAssets(fs afero.Fs, impPath string) *hugofs.FileMeta {
var m *hugofs.FileMeta
- // First the path as is.
+ // See issue #8949.
+ // We need to check if this is a regular file imported without an extension.
+ // There may be ambigous situations where both foo.js and foo/index.js exists.
+ // This import order is in line with both how Node and ESBuild's native
+ // import resolver works.
+ // This was fixed in Hugo 0.88.
+
+ // It may be a regular file imported without an extension, e.g.
+ // foo or foo/index.
+ m = findFirst(impPath)
+ if m != nil {
+ return m
+ }
+
+ // Finally check the path as is.
fi, err := fs.Stat(impPath)
if err == nil {
@@ -169,9 +187,6 @@ func resolveComponentInAssets(fs afero.Fs, impPath string) *hugofs.FileMeta {
} else {
m = fi.(hugofs.FileMetaInfo).Meta()
}
- } else {
- // It may be a regular file imported without an extension.
- m = findFirst(impPath)
}
return m
diff --git a/resources/resource_transformers/js/options_test.go b/resources/resource_transformers/js/options_test.go
index c178ee8c9..e5b04e355 100644
--- a/resources/resource_transformers/js/options_test.go
+++ b/resources/resource_transformers/js/options_test.go
@@ -14,8 +14,13 @@
package js
import (
+ "path/filepath"
"testing"
+ "github.com/gohugoio/hugo/hugofs"
+
+ "github.com/spf13/afero"
+
"github.com/gohugoio/hugo/media"
"github.com/evanw/esbuild/pkg/api"
@@ -127,3 +132,48 @@ func TestToBuildOptions(t *testing.T) {
},
})
}
+
+func TestResolveComponentInAssets(t *testing.T) {
+ c := qt.New(t)
+
+ for _, test := range []struct {
+ name string
+ files []string
+ impPath string
+ expect string
+ }{
+ {"Basic, extension", []string{"foo.js", "bar.js"}, "foo.js", "foo.js"},
+ {"Basic, no extension", []string{"foo.js", "bar.js"}, "foo", "foo.js"},
+ {"Basic, no extension, typescript", []string{"foo.ts", "bar.js"}, "foo", "foo.ts"},
+ {"Not found", []string{"foo.js", "bar.js"}, "moo.js", ""},
+ {"Not found, double js extension", []string{"foo.js.js", "bar.js"}, "foo.js", ""},
+ {"Index file, folder only", []string{"foo/index.js", "bar.js"}, "foo", "foo/index.js"},
+ {"Index file, folder and index", []string{"foo/index.js", "bar.js"}, "foo/index", "foo/index.js"},
+ {"Index file, folder and index and suffix", []string{"foo/index.js", "bar.js"}, "foo/index.js", "foo/index.js"},
+
+ // Issue #8949
+ {"Check file before directory", []string{"foo.js", "foo/index.js"}, "foo", "foo.js"},
+ } {
+
+ c.Run(test.name, func(c *qt.C) {
+ baseDir := "assets"
+ mfs := afero.NewMemMapFs()
+
+ for _, filename := range test.files {
+ c.Assert(afero.WriteFile(mfs, filepath.Join(baseDir, filename), []byte("let foo='bar';"), 0777), qt.IsNil)
+ }
+
+ bfs := hugofs.DecorateBasePathFs(afero.NewBasePathFs(mfs, baseDir).(*afero.BasePathFs))
+
+ got := resolveComponentInAssets(bfs, test.impPath)
+
+ gotPath := ""
+ if got != nil {
+ gotPath = filepath.ToSlash(got.Path)
+ }
+
+ c.Assert(gotPath, qt.Equals, test.expect)
+ })
+
+ }
+}