Repository: wailsapp/wails (Go)

Issue:
[MacOS] `.mjs` files are served as `text/plain`, throwing errors
### Description

Hi ! 
I'm using SvelteKit's static adapter which outputs `.mjs` files and imports them dynamically via `import`, but the asset server doesn't seem to set the proper `Content-Type` for `.mjs` files which is expected by WebKit to be `text/javascript`, instead we get `text/plain` which causes the following thrown error : 

> `TypeError: 'text/plain' is not a valid JavaScript MIME type.`

### To Reproduce

1. Clone https://github.com/aymeric-giraudet/wails-mjs
2. `wails build -debug`
3. Run built MacOS application
4. Inspect element to open DevTools
5. See the error

### Expected behaviour

`Content-Type` for `.mjs` files should be `text/javascript`

### Screenshots

_No response_

### Attempted Fixes

I'm using a middleware to handle serving `.mjs` files myself because of that but it's a lot of work, I've seen a [PR being merged](https://github.com/wailsapp/wails/pull/2286) which makes it so that `Content-Type` is no longer overridden, but there hasn't been a new build yet.

### System Details

```shell
# System

OS           | MacOS
Version      | 13.2
ID           | 22D49
Go Version   | go1.19.1
Platform     | darwin
Architecture | arm64

# Wails

Version | v2.3.1

# Dependencies

Dependency                | Package Name | Status    | Version
Xcode command line tools  | N/A          | Installed | 2396
npm                       | N/A          | Installed | 8.19.3
*Xcode                    | N/A          | Installed | 14.2 (14C18)
*upx                      | N/A          | Available |
*nsis                     | N/A          | Available |
* - Optional Dependency

# Diagnosis

Your system is ready for Wails development!
Optional package(s) installation details:
  - upx : Available at https://upx.github.io/
  - nsis : More info at https://wails.io/docs/guides/windows-installer/
```


### Additional context

_No response_


Discussion:
Thanks for using Wails and bringing up this issue.

I've published PR #2391 which fixes this issue.



Patch:
diff --git a/v2/pkg/assetserver/mimecache.go b/v2/pkg/assetserver/mimecache.go
index dc2dd5c751d..9d97e8f5afc 100644
--- a/v2/pkg/assetserver/mimecache.go
+++ b/v2/pkg/assetserver/mimecache.go
@@ -9,24 +9,44 @@ import (
 )
 
 var (
-	cache = map[string]string{}
-	mutex sync.Mutex
+	mimeCache = map[string]string{}
+	mimeMutex sync.Mutex
+
+	// The list of builtin mime-types by extension as defined by
+	// the golang standard lib package "mime"
+	// The standard lib also takes into account mime type definitions from
+	// etc files like '/etc/apache2/mime.types' but we want to have the
+	// same behavivour on all platforms and not depend on some external file.
+	mimeTypesByExt = map[string]string{
+		".avif": "image/avif",
+		".css":  "text/css; charset=utf-8",
+		".gif":  "image/gif",
+		".htm":  "text/html; charset=utf-8",
+		".html": "text/html; charset=utf-8",
+		".jpeg": "image/jpeg",
+		".jpg":  "image/jpeg",
+		".js":   "text/javascript; charset=utf-8",
+		".json": "application/json",
+		".mjs":  "text/javascript; charset=utf-8",
+		".pdf":  "application/pdf",
+		".png":  "image/png",
+		".svg":  "image/svg+xml",
+		".wasm": "application/wasm",
+		".webp": "image/webp",
+		".xml":  "text/xml; charset=utf-8",
+	}
 )
 
 func GetMimetype(filename string, data []byte) string {
-	mutex.Lock()
-	defer mutex.Unlock()
-
-	// short-circuit .js, .css to ensure the
-	// browser evaluates them in the right context
-	switch filepath.Ext(filename) {
-	case ".js":
-		return "application/javascript"
-	case ".css":
-		return "text/css; charset=utf-8"
+	mimeMutex.Lock()
+	defer mimeMutex.Unlock()
+
+	result := mimeTypesByExt[filepath.Ext(filename)]
+	if result != "" {
+		return result
 	}
 
-	result := cache[filename]
+	result = mimeCache[filename]
 	if result != "" {
 		return result
 	}
@@ -42,6 +62,6 @@ func GetMimetype(filename string, data []byte) string {
 		result = "application/octet-stream"
 	}
 
-	cache[filename] = result
+	mimeCache[filename] = result
 	return result
 }
diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx
index fdb64b48bdd..0c625ce8822 100644
--- a/website/src/pages/changelog.mdx
+++ b/website/src/pages/changelog.mdx
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Added Webview GPU acceleration options for [Windows](/docs/reference/options#webviewgpuisdisabled) and [Linux](/docs/reference/options#webviewgpupolicy). Added by @Lyimmi in [PR](https://github.com/wailsapp/wails/pull/2266)
 - Added `EnableFraudulentWebsiteDetection` option to opt-in to scan services for fraudulent content, such as malware or phishing attempts. Older releases had the scan services per default activated. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2269)
 - Allow an [AssetServer Middleware](/docs/reference/options#middleware) to specify the `Content-Type` of a file served by the [Assets](/docs/reference/options#assets-1) `fs.FS`. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2286)
+- The AssetServer now detects more mimetypes by extension, e.g. `.mjs`. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2391)
 
 ### Changed
 - Improved fullscreen mode for frameless window on Windows. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279), [PR](https://github.com/wailsapp/wails/pull/2288) and [PR](https://github.com/wailsapp/wails/pull/2299)


Test patch:
diff --git a/v2/pkg/assetserver/mimecache_test.go b/v2/pkg/assetserver/mimecache_test.go
index 6b338b7e411..1496dbf52b6 100644
--- a/v2/pkg/assetserver/mimecache_test.go
+++ b/v2/pkg/assetserver/mimecache_test.go
@@ -25,10 +25,11 @@ func TestGetMimetype(t *testing.T) {
 		want string
 	}{
 		// TODO: Add test cases.
-		{"nil data", args{"nil.svg", nil}, "text/plain"},
-		{"empty data", args{"empty.html", emptyMsg}, "text/plain"},
+		{"nil data", args{"nil.svg", nil}, "image/svg+xml"},
+		{"empty data", args{"empty.html", emptyMsg}, "text/html; charset=utf-8"},
 		{"css", args{"test.css", css}, "text/css; charset=utf-8"},
-		{"js", args{"test.js", []byte("let foo = 'bar'; console.log(foo);")}, "application/javascript"},
+		{"js", args{"test.js", []byte("let foo = 'bar'; console.log(foo);")}, "text/javascript; charset=utf-8"},
+		{"mjs", args{"test.mjs", []byte("let foo = 'bar'; console.log(foo);")}, "text/javascript; charset=utf-8"},
 		{"html-utf8", args{"test_utf8.html", html}, "text/html; charset=utf-8"},
 		{"html-bom-utf8", args{"test_bom_utf8.html", bomHtml}, "text/html; charset=utf-8"},
 		{"svg", args{"test.svg", svg}, "image/svg+xml"},