AWS Elastic Beanstalk run Grunt task - node.js

I want to run a node.js application on elastic beanstalk. I have a client which gets build by a grunt job (jade, less, concat, etc.) I excluded this folder from git
I can localy run this by grunt buildClient which is executed by grunt-cli
I added grunt and grunt-cli in my packages dev-dependencies
I want to run the grunt build before the application is launched, i already setup a configuration in .ebextensions/app.config
container_commands:
01_build_client:
command: grunt buildClient
I guess my cwd is /tmp/deployment/application/
but there is says Fatal error: Unable to find local grunt. I guess grunt-cli is installed, but why is this error?
i also tried putting the grunt job in the postinstall section of package.json, but this doesnt work as well.
How do i build my grunt job on a EBS instance?

When running Grunt on a paas, it's best to install a local copy of grunt-cli and grunt locally in the project. That way it's always available and is the exact version you'll need. Then you run npm install instead of grunt so your postinstall works properly.
For example, your package.json might look like this:
"grunt": "0.4.5",
"grunt-cli": "0.1.13",

You can first specify the path to your gruntfile using the --gruntfile <pathToGruntfile> option on the grunt command. However, you'll also need to npm install grunt before running this, or you'll receive the same error.

I've just run into a similar problem whilst trying to get webpack bundilng on elastic beanstalk. I found that when elastic beanstalk runs an npm install it includes the --production flag. This means that you'll need to move your dev dependencies into the dependencies block.
Something else that caught me out is that eb doesn't seem to run the postinstall script which is really annoying! I did find that it runs the prestart script though.
My package.json file ended up looking something like this:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"prestart": "node node_modules/webpack/bin/webpack.js"
},
"dependencies": {
"backbone": "^1.2.1",
"backbone.marionette": "^2.4.1",
"webpack": "^1.9.10",
...
}
}

Related

Cannot install vue

I usually perform fresh re-installs of packages after a period of non-use, but when I came to perform a fresh install of Vue.js and vue-cli I tried to perform a vue init on a new project but was told that vue was not recognised as an operable or batch file etc.
It is possible that I created a problem when I uninstalled vue-cli, which removed something like 250 packages. Subsequent reinstall only installed 1 package, but I was then unable to get any response from the vue init command other than the above.
I have tried every workaround I could find on SO and elsewhere which boils down to the following: -
Upgrading node and npm
Upgrading git
Cleaning the npm cache
One consistent error message in my attempts to perform npm install vue was that I lacked a package.json file in my C:/Users/user folder (I am said user and I have administrator privileges). I ran npm init to create a blank package.json file in that folder but that didn't work either.
The root problem seems to be that nothing I do re-installs a vue.cmd file in my AppData/Roaming/npm folder, even though this path is properly installed in my environment variables. I have looked if this file has been installed elsewhere on my machine, but it hasn't.
Is it possible to manually download a vue.cmd file and put it exactly where it needs to sit, i.e. in my AppData/Roaming/npm folder? I googled this to no avail. All this is while running Command Prompt as an administrator.
Is anyone else having this problem? Is there something with another JS framework which is currently blocking Vue from being properly installed? (I have also developed projects in React and Angular5.)
Just as an update, this is the package.json file I currently have in my C:/Users/user folder after running npm init from that folder: -
{
"name": "user",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"npm": "^5.8.0",
"vue": "^2.5.16"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
It sounds like you don't have vue-cli installed on your machine
But without any error messages it's impossible to tell.
try npm install -g vue-cli#2.9.3
then run which vue-cli to check the location

How do I deploy my Typescript Node.js app to Heroku?

When testing locally I was previously running:
"build-live": "nodemon --exec ./node_modules/.bin/ts-node -r dotenv/config -- ./index.ts"
I then figured my Procfile should be something like:
web: ./node_modules/.bin/ts-node -- ./index.ts
But it says module 'typescript' not found, even when it is in package.json. I read in a few places that ts-node is not the way to go to deploy to Heroku, so I am not sure what to do.
UPDATE: I think I am supposed to compile it, so I tried:
web: ./node_modules/.bin/tsc --module commonjs --allowJs --outDir build/ --sourceMap --target es6 index.ts && node build/index.js
This succeeds, however when actually running it, a bunch of the libs I'm using get "Cannot find module '...'".
Alternatively you can have the TypeScript compile as a postinstall hook and run node build/index.js as the only Procfile command:
Your package.json should contain a postinstall hint that gets executed after npm install and before the node process launches:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
You can then leave your Procfile as is:
web: npm start
This 'build on deploy' approach is documented by Heroku here.
The command you've given Heroku is to launch the web "process" by compiling index.ts and dependencies and starting node at index.js. Depending on how things are timed, index.js might or might not exist at the time node starts.
You need to already have your sources compiled by the time you want to start your app. For example, web should just be web: node index.js or similar.
Each build process is different, so you need to figure that out for your own setup. But, suppose you have a classical setup where you push to git and then Heroku picks up that change and updates the app with the new slug. You could just compile things locally and include index.js and any other build output in the repository, for it to be available in the slug for Heroku to use.
A better approach is to use a build server which has an integration with Heroku. After you do the build there, configure it to send the build results to Heroku. Travis has a straighforward setup like this. This way you don't need to include build outputs in your repository, which is considered an anti-pattern.
On a sidenode, try using a tsconfig.json to keep the tsc configuration. It will save you from having to write such long command lines all over the place.
Fabian said that we could do something like:
"scripts": {
"start": "node build/index.js",
"build": "tsc",
"postinstall": "npm run build"
}
As of me writing this, I tested this and can state: postinstall is not required since build script is ran by Heroku. If you want to do it without build script, then you can use heroku-postbuild which will run after dependencies are installed there you run tsc to compile.
My problem was about missing Typescript npm modules. The Typescript compiler tsc was not found when deployed the app to Heroku.
The Heroku deploy process (rightly) does not install development dependencies, in my case the Typescript module was part of devDependencies and thus the tsc command was not running on the Heroku platform.
Solution 1
Add typescript to dependencies: npm i typescript -s
Solution 2
Open Heroku console:
Select console type:
Run the command npm i typescript && npm run tsc
Install typescript as a dev dependency (cf. https://www.typescriptlang.org/download). Once built, your app does not need typescript anymore!
npm install -D typescript
Then in your package.json:
{
"main": "index.js", // <- file will be generated at build time with `tsc`
"scripts": {
"build": "tsc",
"start": "node ."
"start:dev": "ts-node index.ts" // idem, install ts-node as a dev dependency
}
}
The key point here is "build": "tsc".
Why?
Heroku does install all dependencies during build and remove the dev dependencies before the app is deployed (source here).
Node.js deployments will automatically execute an app’s build script during build (since March 11. 2019 source here)
In package.json
"scripts": {
"tsc": "./node_modules/typescript/bin/tsc",
"postinstall": "npm run tsc"
},
Works for me for Heroku deployment.
Installing typescript npm install -D typescript and writing tsc in the build script "build": "tsc", does not work for me. Also, try to run npm i typescript && npm run tsc in the Heroku console which also does not work.
In my case, I remove some dependencies from "devDependencies" to "dependencies", so it goes like this:
"dependencies": {
// The other dependencies goes here, I don't touch them.
// But all TS dependencies I remove to here.
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3",
"ts-loader": "^8.0.18"
},

Prepublish not working as expected

I am testing on npm scripts to build my project dependency.
My idea comes from https://github.com/ParsePlatform/parse-server which impressed me by code in repository doesn't mean code in node_modules after npm install.
Below is my testmodule structure
src/index.js
package.json
and this is my package.json content
{
"name": "testmodule",
"version": "1.0.0",
"description": "",
"main": "lib/index.js",
"scripts": {
"build": "babel src/ -d lib/",
"prepublish": "npm run build"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.18.2"
}
}
and this is structure I expect after run npm install testmodule
node_modules/testmodule/lib/index.js
node_modules/testmodule/package.json
which is src folder should not be here.
But after I run npm install, it is exactly the same as when I push to my git repository.
Please take note that I am using GitLab in my own server.
So my questions are:
Is there anything that i'm missing to make prepublish run?
Which part of parse-server code makes the src folder and other files not there after install?
How are you running npm install?
According to the documentation on npm scripts, the prepublish script is run "BEFORE the package is published. (Also run on local npm install without any arguments.)". It seems clear that the prepublish script is only run on npm publish or npm install <local directory>.
If you are trying to install directly from your local gitlab server via a URL, this will not work - the script will not be run. The solution would be to install locally unless you're willing to open source your package & push it to the npm repository or pay for a private npm repository. This is what I have done during development of packages before they're ready to be made public.

How to run `npm install && bower install` before `sbt compile` for Heroku Deployment?

I am working on a Playframework project which has front-end codes in sub-directory ./ui and managed by Grunt using https://github.com/tuplejump/play-yeoman
Currently I used https://github.com/heroku/heroku-buildpack-multi and set
https://github.com/heroku/heroku-buildpack-nodejs.git
https://github.com/heroku/heroku-buildpack-scala.git
in the .buildpacks file.
And set
{
"name": "scala-grunt",
"dependencies": {
"grunt-cli": "0.1.13"
},
"devDependencies": {
"grunt": "~0.4.5"
},
"version": "0.1.0",
"engines": {
"node": "~0.10.21"
}
}
in the package.json file of root directory.
However, when I pushed the code base to heroku it will throw an exception Fatal error: Unable to find local grunt. I think that is because sbt doesn't to run npm install && bower install in the ./ui directory.
Does anyone have ideas about how to run a command npm install && bower install before sbt compile in heroku?
Check out https://docs.npmjs.com/misc/scripts. There are a couple keywords you can use to run bower and grunt at different times. Check out the preinstall and postinstall keyword.
For an example, here is my script section from my package.json file that I use a lot.
"scripts": {
"start": "node lib/app.js",
"postinstall": "bower install --allow-root",
"test": "grunt"
}
This command solved for me:
heroku buildpacks:set https://github.com/heroku/heroku-buildpack-multi.git

How can I invoke npm on heroku command line (to install bower components)?

Bower is for client side Javascript what npm is for the server side and reads a component.json file to recognize dependencies that should be fetched at deploy time so I'd be happy it heroku would run it at slug compilation time.
Unfortunately I can not invoke npm or bower from a heroku console or one-off command (heroku run "npm help") (heroku run bash -> npm help) as it's possible with ruby's rake. I've put npm and node (latest/x versions) in my package.json but in the engines section, not the dependencies.
I think this could be solved by customizing the node buildpack but I consider this a little too heavy task just for activating something so obvious.
You can also setup a postintall command, something like this in your package.json
"dependencies": {
"bower": "0.6.x"
},
"scripts": {
"postinstall": "./node_modules/bower/bin/bower install"
}
Then npm install will also install bower dependencies.
Pros : one command to rule them all.
Cons : you unnecessarily embed bower as a dependency.
You can use run like this:
heroku run npm install git://github.com/webjay/kaiseki
You should declare NPM dependencies in the package.json file
All you install from shell will be deleted on exit shell. You are in a cloned instance.
You can use bower directly like this
"dependencies": {
"bower": "^1.7.9"
},
"scripts": {
"postinstall": "sudo bower install --allow-root "
}

Resources