js: Let ESBuild handle all imports from node_modules
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 13 Nov 2020 07:54:29 +0000 (08:54 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Nov 2020 07:54:29 +0000 (08:54 +0100)
This commit fixes some issues where modules in /assets share the same name as in node_modules.

This was not intended, and with this commit the node_modules-components should be isolated. If you want to redefine something inside node_modules, use the `defines` option.

Fixes #7948

commands/static_syncer.go
hugolib/filesystems/basefs.go
hugolib/filesystems/basefs_test.go
hugolib/site.go
resources/resource_transformers/js/options.go
resources/resource_transformers/tocss/scss/tocss.go

index 17fae7d13f827fd3d77f1da911dfdea523cc47c4..bd696520a1f37a598d804693eff749e217da57f3 100644 (file)
@@ -79,9 +79,9 @@ func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
 
                        fromPath := ev.Name
 
-                       relPath := sourceFs.MakePathRelative(fromPath)
+                       relPath, found := sourceFs.MakePathRelative(fromPath)
 
-                       if relPath == "" {
+                       if !found {
                                // Not member of this virtual host.
                                continue
                        }
index 189aa19c6cc700b4eda2c2ca27e1fe268e0ca134..ae3807360acd12daa29a7375753073ccd564baa1 100644 (file)
@@ -267,7 +267,7 @@ func (s SourceFilesystems) IsI18n(filename string) bool {
 // It will return an empty string if the filename is not a member of a static filesystem.
 func (s SourceFilesystems) MakeStaticPathRelative(filename string) string {
        for _, staticFs := range s.Static {
-               rel := staticFs.MakePathRelative(filename)
+               rel, _ := staticFs.MakePathRelative(filename)
                if rel != "" {
                        return rel
                }
@@ -276,8 +276,7 @@ func (s SourceFilesystems) MakeStaticPathRelative(filename string) string {
 }
 
 // MakePathRelative creates a relative path from the given filename.
-// It will return an empty string if the filename is not a member of this filesystem.
-func (d *SourceFilesystem) MakePathRelative(filename string) string {
+func (d *SourceFilesystem) MakePathRelative(filename string) (string, bool) {
 
        for _, dir := range d.Dirs {
                meta := dir.(hugofs.FileMetaInfo).Meta()
@@ -288,10 +287,10 @@ func (d *SourceFilesystem) MakePathRelative(filename string) string {
                        if mp := meta.Path(); mp != "" {
                                rel = filepath.Join(mp, rel)
                        }
-                       return strings.TrimPrefix(rel, filePathSeparator)
+                       return strings.TrimPrefix(rel, filePathSeparator), true
                }
        }
-       return ""
+       return "", false
 }
 
 func (d *SourceFilesystem) RealFilename(rel string) string {
index 633c8fe08cfd454ea2c0bc7b22ff8b2e9cba1873..2d273ae88ee37ac2217ec8f77dd0272c70ac76ca 100644 (file)
@@ -394,9 +394,14 @@ func TestMakePathRelative(t *testing.T) {
        sfs := bfs.Static[""]
        c.Assert(sfs, qt.Not(qt.IsNil))
 
-       c.Assert(sfs.MakePathRelative(filepath.Join(workDir, "dist", "d1", "foo.txt")), qt.Equals, filepath.FromSlash("mydist/d1/foo.txt"))
-       c.Assert(sfs.MakePathRelative(filepath.Join(workDir, "static", "d2", "foo.txt")), qt.Equals, filepath.FromSlash("d2/foo.txt"))
-       c.Assert(sfs.MakePathRelative(filepath.Join(workDir, "dust", "d3", "foo.txt")), qt.Equals, filepath.FromSlash("foo/bar/d3/foo.txt"))
+       makeRel := func(s string) string {
+               r, _ := sfs.MakePathRelative(s)
+               return r
+       }
+
+       c.Assert(makeRel(filepath.Join(workDir, "dist", "d1", "foo.txt")), qt.Equals, filepath.FromSlash("mydist/d1/foo.txt"))
+       c.Assert(makeRel(filepath.Join(workDir, "static", "d2", "foo.txt")), qt.Equals, filepath.FromSlash("d2/foo.txt"))
+       c.Assert(makeRel(filepath.Join(workDir, "dust", "d3", "foo.txt")), qt.Equals, filepath.FromSlash("foo/bar/d3/foo.txt"))
 
 }
 
index 3679e354cca2410befeb1e1ffb77d333dc9702c6..3d77b014af3fca16b0b5a4e0086fe4762f2d5cc4 100644 (file)
@@ -1047,7 +1047,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
        )
 
        for _, ev := range events {
-               if assetsFilename := s.BaseFs.Assets.MakePathRelative(ev.Name); assetsFilename != "" {
+               if assetsFilename, _ := s.BaseFs.Assets.MakePathRelative(ev.Name); assetsFilename != "" {
                        cachePartitions = append(cachePartitions, resources.ResourceKeyPartitions(assetsFilename)...)
                        if evictCSSRe == nil {
                                if cssFileRe.MatchString(assetsFilename) || cssConfigRe.MatchString(assetsFilename) {
index 689efe0b4b74ae2fa1a3cc5db295063fd4b93c17..fde6f58886beba593b3be2f5b2af3f21f785e187 100644 (file)
@@ -19,7 +19,6 @@ import (
        "io/ioutil"
        "path/filepath"
        "strings"
-       "sync"
 
        "github.com/pkg/errors"
 
@@ -113,11 +112,6 @@ func decodeOptions(m map[string]interface{}) (Options, error) {
        return opts, nil
 }
 
-type importCache struct {
-       sync.RWMutex
-       m map[string]api.OnResolveResult
-}
-
 var extensionToLoaderMap = map[string]api.Loader{
        ".js":   api.LoaderJS,
        ".mjs":  api.LoaderJS,
@@ -141,16 +135,18 @@ func loaderFromFilename(filename string) api.Loader {
 func createBuildPlugins(c *Client, opts Options) ([]api.Plugin, error) {
        fs := c.rs.Assets
 
-       cache := importCache{
-               m: make(map[string]api.OnResolveResult),
-       }
-
        resolveImport := func(args api.OnResolveArgs) (api.OnResolveResult, error) {
-
                isStdin := args.Importer == stdinImporter
                var relDir string
                if !isStdin {
-                       relDir = filepath.Dir(fs.MakePathRelative(args.Importer))
+                       rel, found := fs.MakePathRelative(args.Importer)
+                       if !found {
+                               // Not in any of the /assets folders.
+                               // This is an import from a node_modules, let
+                               // ESBuild resolve this.
+                               return api.OnResolveResult{}, nil
+                       }
+                       relDir = filepath.Dir(rel)
                } else {
                        relDir = filepath.Dir(opts.sourcefile)
                }
@@ -204,8 +200,7 @@ func createBuildPlugins(c *Client, opts Options) ([]api.Plugin, error) {
                        return api.OnResolveResult{Path: m.Filename(), Namespace: nsImportHugo}, nil
                }
 
-               // Not found in /assets. Probably in node_modules. ESBuild will handle that
-               // rather complex logic.
+               // Fall back to ESBuild's resolve.
                return api.OnResolveResult{}, nil
        }
 
@@ -214,26 +209,7 @@ func createBuildPlugins(c *Client, opts Options) ([]api.Plugin, error) {
                Setup: func(build api.PluginBuild) {
                        build.OnResolve(api.OnResolveOptions{Filter: `.*`},
                                func(args api.OnResolveArgs) (api.OnResolveResult, error) {
-                                       // Try cache first.
-                                       cache.RLock()
-                                       v, found := cache.m[args.Path]
-                                       cache.RUnlock()
-
-                                       if found {
-                                               return v, nil
-                                       }
-
-                                       imp, err := resolveImport(args)
-                                       if err != nil {
-                                               return imp, err
-                                       }
-
-                                       cache.Lock()
-                                       defer cache.Unlock()
-
-                                       cache.m[args.Path] = imp
-
-                                       return imp, nil
+                                       return resolveImport(args)
 
                                })
                        build.OnLoad(api.OnLoadOptions{Filter: `.*`, Namespace: nsImportHugo},
index 20f0efbb9505412a80208316a554ba8c59649524..fc7a19f33254e7954b27aa7d3548ec0ee76e75d9 100644 (file)
@@ -76,7 +76,7 @@ func (t *toCSSTransformation) Transform(ctx *resources.ResourceTransformationCtx
                if prev == "stdin" {
                        prevDir = baseDir
                } else {
-                       prevDir = t.c.sfs.MakePathRelative(filepath.Dir(prev))
+                       prevDir, _ = t.c.sfs.MakePathRelative(filepath.Dir(prev))
 
                        if prevDir == "" {
                                // Not a member of this filesystem. Let LibSASS handle it.