summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-12-15 13:31:07 +0700
committerShulhan <ms@kilabit.info>2024-12-15 13:31:07 +0700
commit2c0c677e558e54854dd4189858895e9eaf063455 (patch)
tree92b3602fb1437faed9eb85ed71e9d529a6454677
parentdb651010fd746282748c9fde610e0f0d9c53380e (diff)
downloadkilabit.info-2c0c677e558e54854dd4189858895e9eaf063455.tar.xz
journal/2024: write down "Memfs vs go:embed"
This article compare the feature of go:embed with the memfs package from my pakakeh.go module.
-rw-r--r--_content/journal/2024/index.adoc4
-rw-r--r--_content/journal/2024/memfs_vs_goembed/index.adoc122
2 files changed, 126 insertions, 0 deletions
diff --git a/_content/journal/2024/index.adoc b/_content/journal/2024/index.adoc
index be0b314..e38dc65 100644
--- a/_content/journal/2024/index.adoc
+++ b/_content/journal/2024/index.adoc
@@ -1,6 +1,10 @@
=== 2024
+link:/journal/2024/memfs_vs_goembed/[Memfs vs go:embed^].
+This article compare the feature of go:embed with the memfs package
+from my pakakeh.go module.
+
link:/journal/2024/two_types_of_leader/[Two types of leader^].
link:/journal/2024/bad_coding_practices/[Bad coding practices^].
diff --git a/_content/journal/2024/memfs_vs_goembed/index.adoc b/_content/journal/2024/memfs_vs_goembed/index.adoc
new file mode 100644
index 0000000..5118da3
--- /dev/null
+++ b/_content/journal/2024/memfs_vs_goembed/index.adoc
@@ -0,0 +1,122 @@
+= Memfs vs go:embed
+:sectanchors:
+:sectlinks:
+:toc:
+
+This article compare the feature of
+https://pkg.go.dev/embed["go:embed"^]
+with the
+https://pkg.go.dev/git.sr.ht/~shulhan/pakakeh.go/lib/memfs[memfs
+package^] from my
+https://pkg.go.dev/git.sr.ht/~shulhan/pakakeh.go[pakakeh.go^]
+module.
+
+The memfs package created on
+https://git.sr.ht/~shulhan/pakakeh.go/commit/05b02c7b[November 2018^],
+based on my experiences maintains the fork of
+https://github.com/shuLhan/go-bindata[go-bindata^]
+project.
+The "go:embed" directive introduced into Go tools since
+https://go.dev/doc/go1.16[Go version 1.16^],
+released February 2021, three years after the first release of memfs
+package.
+
+Given the following directory structure,
+
+----
+module-root/
++-- cmd/prog/main.go
++-- _content/
+ +-- index.adoc
+ +-- index.html
+ +-- static/
+ +-- index.png
+ +-- index.png
+----
+
+We want to embed the directory "_content" but only html files and all
+files inside the "static/" directory.
+
+
+**Cons #1: The "go:embed" only works if files or directory to be
+embedded is in the same parent directory.**
+
+The "go:embed" directive define in "cmd/prog/main.go" will not able to
+embed files in their parent.
+The following code will not compile,
+
+----
+//go:embed ../../_content/*.html
+//go:embed ../../_content/static
+var contentFS embed.FS
+
+// go build output,
+// pattern ../../_content/*.html: invalid pattern syntax
+----
+
+If we remove the ".." and execute "go build" from module-root, it will
+still not compile,
+
+----
+//go:embed _content/*.html
+//go:embed _content/static
+var contentFS embed.FS
+
+// go build or run output,
+// pattern _content/*.html: no matching files found
+----
+
+The only solution is to create and export the variable "ContentFS" in
+the same parent directory as "_content".
+
+The memfs package does not have this limitation.
+As long as the Go commands are executed from the module-root
+directory, you can define the variable in any packages.
+
+
+**Cons #2: Accessing the embedded file require the original path.**
+
+Let say we have embeded the "_content" directory using the following
+syntax,
+
+----
+//go:embed _content/*.html
+//go:embed _content/static
+var ContentFS embed.FS
+----
+
+To access the file "index.html" you need to pass their full path, in
+this case "_content/index.html".
+The path "_content" leaked to the parent FS and not portable.
+
+In the memfs package, the content of [Options.Root] directory can be
+accessed with "/", so it would become "/index.html".
+This design allow flexibility and consistency between modules and
+packages.
+If an external, third-party package accept the MemFS instance and the
+first thing they do is to read all contents of "/" directory, the
+caller can embed any path without have specific prefix or name.
+
+Case example, when we embed SQL files for migration under directory
+"db/migration" using the "go:embed" directive,
+
+----
+//go:embed db/migration/*.sql
+var DBMigrationFS embed.FS
+----
+
+and then call the Migrate function, it cannot found any ".sql" files
+inside the "/" directory because the files is stored under
+"db/migration/" prefix.
+
+
+**Cons #3: No development mode.**
+
+Let say we run our server that served the content from FS instance.
+If we changes the html files, and refresh the browser, the new content
+will not reflected because it serve the content on the first embed.
+
+The memfs package have [Options.TryDirect] that bypass file in memory
+and read directly to the file system.
+This allow quick development when changes only template or non-code
+files.