Acho que a solução para isso é manter os arquivos .js estáticos no S3 e manter as versões anteriores junto com as novas durante a publicação de novos aplicativos.
O CloudFront exibirá o conteúdo estático do S3 e o conteúdo dinâmico do EC2.
Publique o conteúdo estático no S3 primeiro e inicie a transição.
Nesse caso, a página de índice gerada dinamicamente se referiria a um bucket S3 na versão antiga e outro no novo. Como os dois recursos sempre resolvem no S3, não haverá 404.