Resposta de uma perspectiva de front-end:
Não ouça todo mundo dizendo que isso não pode ser feito, porque um serviço da Web experimental da Universidade do Estado de São Francisco que eu co-escrevi em 1996 finalmente foi para o paraíso na Internet há alguns anos e nunca precisou de uma única correção de compatibilidade de navegador naquele tempo ; isso é quase metade da sua meta de 40 anos. E esse front-end baseado em JavaScript que eu fiz em 1998 para um projeto do Stanford Research Institute foi substituído por algo mais chamativo alguns anos depois, mas não há razão para que a interface do usuário original ainda não estivesse funcionando hoje com pequenas correções de compatibilidade.
O truque é garantir que seu aplicativo use apenas os padrões W3C / ECMA amplamente suportados e tenha um design limpo sob seu controle. Embora muitos aplicativos da Web gravados na moderna tecnologia da era dos anos 90 não funcionem bem ou hoje, os aplicativos da era dos anos 90 gravados nos principais padrões ainda funcionam. Eles podem parecer ultrapassados, mas eles funcionam.
O objetivo aqui não é escrever um aplicativo Web que suba no servidor e permaneça lá por 40 anos sem que ninguém o toque novamente. É construir uma base que ainda possa ser usada décadas depois, que pode crescer para suportar novos recursos sem precisar ser reconstruída do zero.
Primeiro de tudo, você precisa codificar para padrões oficiais e somente para padrões oficiais. Nenhum recurso JavaScript que não faça parte de um padrão ECMAScript ratificado; ES5.1 é a versão atual e geralmente é suportada, de modo que é seguro segmentar. Da mesma forma, as versões atuais de HTML5, CSS e Unicode são boas. Não há recursos experimentais de JavaScript, CSS3 ou HTML (aqueles com prefixos de fornecedores ou sem acordo de 100% entre os navegadores). E não há hacks de compatibilidade específicos do navegador. Você pode começar a usar um novo recurso quando ele estiver no padrão e todos o suportarem sem prefixos.
O suporte ao ES5 significaria abandonar o IE8 ou anterior, o que eu sugiro de qualquer maneira, pois requer hacks específicos do navegador que serão inúteis em alguns anos. Eu sugiro o Modo Estrito do ES5 para a melhor chance de longevidade, o que realmente define a compatibilidade do navegador de linha de base no IE10 e nas versões recentes de todos os outros . Esses navegadores também têm suporte nativo para muitos dos recursos de validação de formulário e espaço reservado do HTML5, que serão úteis por muito tempo.
Novas edições do ECMAScript mantêm a compatibilidade com versões mais antigas, por isso será muito mais fácil adotar os próximos recursos se o seu código for escrito de acordo com os padrões atuais. Por exemplo, as classes definidas usando a class
sintaxe futura serão totalmente intercambiáveis com as classes definidas com a constructor.prototype
sintaxe atual . Assim, em cinco anos, um desenvolvedor pode reescrever classes no formato ES6, arquivo por arquivo, sem quebrar nada - supondo, é claro, que você também tenha bons testes de unidade.
Segundo, evite estruturas modernas de aplicativos JavaScript, especialmente se elas mudarem a maneira como você codifica seu aplicativo. A espinha dorsal era toda a raiva, então SproutCore e Ember, e agora o Angular é a estrutura que todo mundo gosta de promover. Eles podem ser úteis, mas também têm algo em comum: geralmente quebram aplicativos e exigem alterações de código quando novas versões são lançadas e sua longevidade é questionável. Atualizei recentemente um aplicativo Angular 1.1 para 1.2 e um pouco teve que ser reescrito. Da mesma forma, passar do Backbone 2 para 3 requer muitas alterações de HTML. Os padrões são lentos por um motivo, mas essas estruturas se movem rapidamente e as coisas quebram periodicamente são o custo.
Além disso, novos padrões oficiais geralmente deixam obsoletas estruturas antigas e, quando isso acontece, essas estruturas sofrem mutações (com alterações recentes) ou são deixadas para trás. Você sabe o que vai acontecer com todas as bibliotecas de promessas concorrentes do mundo depois que o ECMAScript 6 for ratificado e todos os navegadores suportarem sua classe Promise padronizada? Eles ficarão obsoletos e seus desenvolvedores deixarão de atualizá-los. Se você escolheu a estrutura correta, seu código pode se adaptar bem o suficiente e, se você adivinhou mal, verá uma grande refatoração.
Portanto, se você está pensando em adotar uma biblioteca ou estrutura de terceiros, pergunte-se o quão difícil será remover no futuro. Se é uma estrutura como Angular que nunca pode ser removida sem reconstruir seu aplicativo do zero, é um bom sinal de que não pode ser usado em uma arquitetura de 40 anos. Se for um widget de calendário de terceiros que você abstraiu com um middleware personalizado, a substituição levaria algumas horas.
Terceiro, ofereça uma estrutura de aplicativo boa e limpa. Mesmo se você não estiver usando uma estrutura de aplicativo, ainda poderá aproveitar as ferramentas do desenvolvedor, criar scripts e um bom design limpo. Pessoalmente, sou fã do gerenciamento de dependências do Closure Toolkit porque é leve e sua sobrecarga é completamente removida na criação do aplicativo. LessCSS e SCSS também são ótimas ferramentas para organizar suas folhas de estilo e criar folhas de estilo CSS baseadas em padrões para lançamento.
Você também pode organizar seu próprio código em classes de uso único com uma estrutura MVC. Isso tornará muito mais fácil voltar vários anos no futuro e saber o que você estava pensando quando escreveu algo, e substituir apenas as partes que precisam.
Você também deve seguir os conselhos do W3C e manter as informações de apresentação completamente fora do seu HTML. (Isso inclui truques, como fornecer aos elementos nomes de classe de apresentação, como "texto verde grande" e "largura de duas colunas".) Se o seu HTML for semântico e o CSS for de apresentação, será muito mais fácil mantê-lo e adaptá-lo para novas plataformas no futuro. Também será mais fácil adicionar suporte a navegadores especializados para pessoas cegas ou deficientes.
Quarto, automatize seus testes e verifique se você tem uma cobertura quase total. Escreva testes de unidade para todas as classes, seja do lado do servidor ou em JavaScript. No front-end, verifique se cada classe tem desempenho de acordo com suas especificações em todos os navegadores suportados. Automatize esses testes do seu bot de compilação para cada confirmação. Isso é importante tanto para a longevidade quanto para a confiabilidade, pois é possível detectar erros mais cedo, mesmo quando os navegadores atuais os ocultam. As estruturas de teste baseadas em JSUnit do Jasmine e do JS Closit do Google são boas.
Você também deseja executar testes funcionais completos da interface do usuário, nos quais o Selenium / WebDriver é bom. Basicamente, você escreve um programa que percorre sua interface do usuário e o usa como se uma pessoa estivesse testando. Conecte-os também ao bot de compilação.
Por fim, como outros já mencionaram, seus dados são importantes. Pense em seu modelo de armazenamento de dados e verifique se ele foi desenvolvido para durar. Certifique-se de que seu esquema de dados seja sólido e que também seja testado completamente em todas as confirmações. E verifique se a arquitetura do servidor é escalável. Isso é ainda mais importante do que qualquer coisa que você faça no front end.