After successfully testing my React app locally via vite
and vite preview
, I have deployed my app to an AWS Amplify environment via git integration. However, in that environment the app cannot find the service worker script at /service-worker.js
and I am totally stumped as to why. I am using Vite with vite-plugin-pwa and Workbox.
The service-worker script is located in the root of my build output directory and other files next to it can be found. All the other files the app tries to load for the first time, including the minified script file for the project is located at /assets/index-randomgibberish.js
, correctly load.
I know that vite preview
runs a dev server using the final build outputs and when I delete build files while previewing, it begins giving 404s as expected, so the same build command being run in the cloud should be generating identical outputs.
During builds, I can see src/service-worker.js being built and public/service-worker.mjs
is printed into the console
PWA v0.21.1
Building src/service-worker.js service worker ("es" format)...
[...]
public/service-worker.mjs
However, I never see any file with the .mjs extension.
Trying to GET mywebsite.com/service-worker.js
, mywebsite.com/service-worker.mjs
, mywebsite.com/assets/service-worker.js
and mywebsite.com/assets/service-worker.mjs
via both the browser and cURL all fail. Trying to configure redirects/rewrites in Amplify between all of these urls does nothing. Turning off all redirects/rewrites doesn't do anything useful.
As far as I can tell, all of the CloudFront and S3 infrastructure (I see headers that mention both S3 and CloudFront with the requests) and any build infrastructure used is managed by AWS and not accessible to me to examine any build artifacts or lower-level configurations.
I am using a custom domain and both it and the generated Amplify url have identical behavior.
This is my amplify.yaml
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci --cache .npm --prefer-offline
build:
commands:
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
- npm run build
artifacts:
baseDirectory: dist
files:
- '**/*'
- 'service-worker.js'
The issue was an inexplicable difference with how the build was being done locally vs in the ci environment.
In my local environment, the service-worker.js script was being placed in the /public directory and copied (somehow) into the /dist production built output. I assumed since vite copies the /public contents into the build output as-is, this was an expected result.
When the same build was being done in the ci pipeline, the script was going into the /public directory as before yet NOT being copied into /dist, so the build artifacts given to Amplify didn't have it.
I have updated my vite.config.ts
to move it directly into dist when building for prod.
export default defineConfig(({mode}) => {
return ({
base: '/',
plugins: [
react(),
VitePWA({
injectManifest: {
injectionPoint: undefined,
globDirectory: './dist',
globPatterns: ['**/*.{js,css,html,png,svg}'],
},
srcDir: "src",
outDir: mode === "production" ? "dist" : "public",
strategies: "injectManifest",
filename: "service-worker.js",
registerType: "autoUpdate"
})
],
build: {
sourcemap: true
}
})
});
I have no idea why these same commands work one way in one place and another way in the other.