Podczas hackathonu w jakim brałem udział tydzień temu - Node Knockout 2017, budowałem aplikację, którą - zgodnie z regulaminem wydarzenia - musiałem opublikować na Heroku. Przyzwyczaiłem się już do tego, że zawsze tam lądują moje aplikacje podczas wydarzeń takiego typu.
Spotkały mnie pewne problemy, które rozwiązałem i chciałem się podzielić moim rozwiązaniem. Nie uważam je za idealne. Jednak za wystarczające.
Disclaimer Zdaje sobie z tego sprawę, że wrzucanie katalogu
distdo repozytorium jest bez sensowne, ponieważ Git nie powinien wersjonować plików zbundlowanych jednak - jak zawsze - istnieją wyjątki.
Aktualizacja: 2026-09-26
Pakiet vue-cli i polecenie vue init webpack to narzędzia z czasów Vue 2
i są porzucone. Nowy projekt Vue tworzy się dziś poleceniem
npm create vue@latest, które korzysta z Vite. Node.js 8 z pola engines
dawno nie jest wspierany, podaj aktualną wersję LTS.
Etap 0 Heroku: Zakładanie konta
-
Zakładamy konto na: heroku.com
-
Panel użytkownika: dashboard.heroku.com
Heroku udostępnia panel dla użytkownika, gdzie można tworzyć nowe kontenery, gdzie uruchomiony jest system operacyjny Linux. Pojedynczy kontener w żargonie firmy nazywa się
DynoWięcej na ich temat w pomocy.
Etap 1 Heroku: Przygotowanie środowiska
- Tworzymy nową aplikację:
New→Create new app -
Wpisujemy nazwę dla naszej aplikacji w pole
App nameWpisana nazwa jest na sprawdzana “w locie” pod kątem dostępności.
- Opcjonalnie: Wybieramy region:
Choose a region→Europe
•
🎉 Aplikacja stworzona! 🎉
Możemy otworzyć aplikację w przeglądarce klikając w przycisk: Open app
Naszym oczom powinien ukazać się komunikat:
Heroku | Welcome to your new app!
•
Etap 2 Stworzenie projektu za pomocą Vue CLI
1. Instalacja
Copy + paste
npm install -g vue-cli
Po instalacji, w terminalu będzie dostępne polecenie vue.
2. Wygenerowanie projektu za pomocą szablonu
Copy + paste
vue init webpack NAZWA_PROJEKTU
Wykorzystujemy jeden w predefiniowanej struktury aplikacji.
W projekcie vue-templates istnieje 6 różnych szablonów:
- webpack
- webpack-simple
- pwa
- simple
- browserify
- browserify-simple
3. Poprawienie wersji
Uwaga: W package.json należy poprawić wersję, z uwagi na
problem, który wystąpi podczas instalacji zależności na Heroku:
"engines": {
- "node": ">= 4.0.0",
- "npm": ">= 3.0.0"
+ "node": "8.x",
+ "npm": "5.x"
},
4. Instalacja zależności
Copy + paste
npm install
W głównym katalogu projektu stworzy się plik package-lock.json,
w którym zostaną zapisane wszystkie dane na temat zainstalowanych paczek wraz
z ich wersjami.
Stacktrace z błędem
Jeśli nie zaktualizujemy wersji to będziemy świadkami błędu:
remote: -----> Building dependencies
remote: Installing node modules (package.json + package-lock)
remote: WARNING: You are likely using a version of node-tar or npm that is incompatible with this version of Node.js.
remote: Please use either the version of npm that is bundled with Node.js, or a version of npm (> 5.5.1 or < 5.4.0) or node-tar (> 4.0.1) that is compatible with Node.js 9 and above.
remote: /tmp/build_ab1c9272aa348395c069d548da02c8c4/.heroku/node/bin/node[273]: ../src/node_zlib.cc:437:static void node::{anonymous}::ZCtx::Init(const v8::FunctionCallbackInfo<v8::Value>&): Assertion `args.Length() == 7 && "init(windowBits, level, memLevel, strategy, writeResult, writeCallback," " dictionary)"' failed.
remote: 1: node::Abort() [npm]
remote: 2: node::Assert(char const* const (*) [4]) [npm]
remote: 3: 0x1255aff [npm]
remote: 4: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [npm]
remote: 5: 0xb77f9c [npm]
remote: 6: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [npm]
remote: 7: 0x253e476842fd
remote: /app/tmp/buildpacks/19862b8792e84bd8421ded4660b92dfd1c41d92e19ac0b38c90301adc8ae3e0bd512fa01998af18fc2f0d31a157e9c82e8fdceba1a05e5d29adb8dc2bfaf08e1/lib/dependencies.sh: line 111: 273 Aborted npm install --unsafe-perm --userconfig $build_dir/.npmrc 2>&1
remote:
remote: -----> Build failed
remote:
remote: We're sorry this build is failing! You can troubleshoot common issues here:
remote: https://devcenter.heroku.com/articles/troubleshooting-node-deploys
remote:
remote: Some possible problems:
remote:
remote: - Dangerous semver range (>) in engines.node
remote: https://devcenter.heroku.com/articles/nodejs-support#specifying-a-node-js-version
remote:
remote: Love,
remote: Heroku
5. Zamieniamy projekt w repozytorium
Copy + paste
git init
git add .
git commit -am "Initial import"
•
Teraz mamy dwie opcje:
- Dodajemy katalog
dist/do repozytorium - Nie dodajemy katalogu
dist/(rekomendowana)
Zobaczmy jak wyglądają obie opcje w realu!
•
Etap 2 → Opcja 1 Dodajemy katalog dist/ do repozytorium
1. Budujemy produkcyjną wersję aplikacji w katalogu dist/
Copy + paste
npm run build
2. Wyłączamy ignorowania przez Git-a katalog dist/
Usuwamy linijkę w pliku .gitignore:
node_modules/
- /dist/
npm-debug.log*
3. Dodajemy katalog dist/ do repozytorium
Copy + paste
git add .
git commit -am "Add distributed version"
4. Instalacja narzędzia, które będzie serwować katalog dist/
Copy + paste
npm install serve --save
5. Tworzymy zadanie run-script, które uruchomi aplikację
"scripts": {
- "start": "npm run dev",
+ "start": "serve dist/",
+ "deploy": "npm run build && git add dist/ && git commit -am 'Deploy' && git push heroku master"
},
Opiszę co robią dodane zadania:
start- uruchomi paczkęserve, która będzie serwować katalogdist/, jako główny katalog aplikacjideploy- aby przyspieszyć proces deploymentu warto zrobić takie zadanie, które wykona za nas wszelkie prace związanie ze zbudowaniem wersji produkcyjnej
6. Zapisujemy stan projektu
Copy + paste
git add .
git commit -am "Serve static files"
Aplikacja jest gotowa do pierwszego release-u! 🏆
•
Etap 2 → Opcja 2 Nie dodajemy katalogu dist/ do repozytorium (rekomendowana)
1. Instalujemy paczkę, która będzie serwowała katalog dist/
Dla odmiany wykorzystajmy inną paczkę.
Tym razem niech to będzie http-server.
Copy + paste
npm install http-server --save
2. Dodajemy nowe zadania
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"build": "node build/build.js",
+ "deploy": "git push heroku master",
+ "heroku-postbuild": "npm run build",
+ "start": "http-server dist/ -d false -g"
},
Opiszę nowo dodane polecenia:
deploy- zadanie dzięki, któremu zaktualizujemy branchmasterw Heroku, przez co zostanie zaktualizowany projekt w serwerowni.-
heroku-postbuild- jest to hook (event handler), który zostanie uruchomiony przez Heroku w celu zbudowania aplikacji.Zadanie zostanie uruchomione po instalacji wszystkich zależności.
start- uruchamia serwer HTTP, który będzie serwował katalogdist/jakodirectoryRoot, czy główny katalog aplikacji
3. Ustawmy zmienną środowiskową na Heroku
W panelu Heroku, w zakładce Settings → Config Variables.
Należy w niej ustawić zmienną:
NPM_CONFIG_PRODUCTION = false
(Aktualizacja 2026: od 2018 roku buildpack Node.js na Heroku sam instaluje zależności developerskie na czas budowania i usuwa je po nim, więc ta zmienna nie jest już potrzebna.)
Zmienna jest ustawiona po to, aby podczas procesu budowania projektu Heroku
pobrało również zależności developerskie, które są potrzebne do zbudowania
aplikacji do katalogu dist/.
Aplikacja jest gotowa do pierwszego release-u! 🏆
•
Etap 3 Deployment
Czas najwyższy, aby opublikować aplikację. Mamy kilka możliwości na deployment aplikacji. Dla mnie interesujące są 2 pierwsze:
- Automatyczny deployment z brancha na GitHubie
- Manualny deployment po wrzuceniu projektu do zdalnego repozytorium Git, trzymanego na Heroku.
Wybieram opcję numer 2 ponieważ pierwsza jest mniej elastyczna. Chciałbym coś wrzucić na Heroku, ale nie chciałbym publikować tych zmian na GitHuba.
1. Logujemy się do Heroku CLI
Copy + paste
heroku login
2. Łączymy repozytorium lokalne ze zdalnym na Heroku
Copy + paste
heroku git:remote -a NAZWA_PROJEKTU
3. Wypychamy zmiany na serwer 🚀
Wyślijmy nasze repozytorium na Heroku, aby zainicjować proces deploymentu:
Copy + paste
git push heroku master
Odśwież w przeglądarce wcześniej otworzoną stronę, aby zobaczyć:
•
🎊 Aplikacja opublikowana! 🎊
Więcej na temat deploymentu przeczytasz w pomocy.
Aby później deployować aplikację za pomocą jednego polecenia:
Copy + paste
npm run deploy
•
Jeśli znasz lepszy sposób na deployment napisz komentarz!
Cya! 👋