From 7afd9db233374644ac388d5d51cbb8882ae6ac3f Mon Sep 17 00:00:00 2001 From: Alien ZHOU Date: Wed, 29 Jun 2022 21:15:45 +0800 Subject: [PATCH] feat(build): prevent submodules bundling their local dependencies (#354) Co-authored-by: zhouhongxuan --- .gitignore | 1 + server/build.go | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a28c4dfc1..c1fb638f4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ esmd node_modules/ target/ pkg/ +.vscode/launch.json diff --git a/server/build.go b/server/build.go index d1f444daf..767b5deb5 100644 --- a/server/build.go +++ b/server/build.go @@ -8,6 +8,8 @@ import ( "fmt" "os" "path" + "path/filepath" + "reflect" "strings" "time" @@ -308,11 +310,35 @@ func (task *BuildTask) build(tracing *stringSet) (esm *ModuleMeta, err error) { } } - // bundles undefined relative imports or the package/module it self - if isLocalImport(specifier) || specifier == task.Pkg.ImportPath() { + // bundle the package/module it self and the entrypoint + if specifier == task.Pkg.ImportPath() || specifier == entryPoint { return api.OnResolveResult{}, nil } + // for local modules + if isLocalImport(specifier) { + // bundle if the entry pkg is not a submodule + if task.Pkg.Submodule == "" { + return api.OnResolveResult{}, nil + } + + // bundle if this pkg has 'exports' definitions but the local module is not in 'exports' + if npm.DefinedExports != nil && !reflect.ValueOf(npm.DefinedExports).IsNil() { + return api.OnResolveResult{}, nil + } + + // otherwise do not bundle its local dependencies + var dirpath = args.ResolveDir + if strings.HasPrefix(dirpath, "/private/var/") { + dirpath = strings.TrimPrefix(dirpath, "/private") + } + fullFilepath := filepath.Join(dirpath, specifier) + // convert: full filepath --> package name + submodule path + specifier = strings.TrimPrefix(fullFilepath, filepath.Join(task.wd, "node_modules")+"/") + external.Add(specifier) + return api.OnResolveResult{Path: "__ESM_SH_EXTERNAL:" + specifier, External: true}, nil + } + // ignore `require()` of esm package if task.NoRequire && (args.Kind == api.ResolveJSRequireCall || args.Kind == api.ResolveJSRequireResolve) { return api.OnResolveResult{Path: specifier, External: true}, nil