Capacitor+Vite: when including Filesystem plugin, get warning “Unable to read file at path public/plugins”, then fails on import
I'm brand new to Capacitor and Vite. I’m trying to run a trivial Capacitor app that includes the Filesystem plugin, and it seems to build OK but when I run it in Android Studio I see this warning in AS’s logcat:
D Registering plugin instance: Filesystem
W Unable to read file at path public/plugins
… and then, the index.html loads correctly but the JavaScript fails on:
import { Filesystem, Directory, Encoding } from "@capacitor/filesystem"
… generating the logcat message:
File: - Line 827 - Msg: TypeError: Failed to resolve module specifier "@capacitor/filesystem".
So it looks like public/plugins is never created, leading to the failure. I have installed @cordova/filesystem multiple times, and it appears in my package.json (see below). There is indeed no public/plugins anywhere under my app’s root directory, from a find . -name public. If public/plugins is supposed to be created, what normally creates it?
I’m using the latest Vite for bundling. This app was “converted” from the demo Cordova app (since creating a new Capacitor app with npm init @capacitor/app@latestfails as reported here).
My webDir is set to "www" in capacitor.config.json. When I build and run from the command line with npx cap run android, the same thing happens-- index.html loads but the JS doesn’t run.
Before I build and run in Android Studio, I run npx vite build www && npx cap sync. Is this right?
I've found I can use Capacitor.Plugins to access parts of a plugin but not all. For example, Capacitor.Plugins.Filesystem contains all the methods of Filesystem but not any constants that would be in Directory or Encoding. I could hardcode the constants in my code, but that would be brittle.
This is all using the latest versions of almost everything:
Relevant files are shown below. Note that some still include artifacts from Cordova.
Thank you for any help!
www/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="css/index.css">
<title>Capacitor + Vite test</title>
<script type="module" src="js/index.js"></script>
</head>
<body>
Capacitor + Vite test
</body>
</html>
www/js/index.js:
import { Filesystem, Directory, Encoding } from "@capacitor/filesystem";
alert('starting Capacitor app') ;
let lib= await Filesystem.stat({
directory: Directory.Library,
path: '.',
}) ;
alert(lib) ;
capacitor.config.json:
{
"appId": "com.jmarshall.testcapvite",
"appName": "TestCapacitorVite",
"webDir": "www"
}
package.json:
"name": "com.jmarshall.testcapvite",
"displayName": "TestCapacitorVite",
"version": "1.0.0",
"description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"ecosystem:cordova"
],
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"devDependencies": {
"@capacitor/cli": "^8.5.0",
"cordova-android": "^15.1.0",
"vite": "^8.1.5"
},
"cordova": {
"platforms": [
"android"
]
},
"dependencies": {
"@capacitor/android": "^8.5.0",
"@capacitor/core": "^8.5.0",
"@capacitor/filesystem": "^8.1.2"
}
}