I want to run a couple different scripts during preinstall, and a few postinstall, but the examples on npm where they split the calls using semi-colons doesn't work, and ends up throwing an error. Was hoping to be able to do something like:
"scripts": {
"preinstall": "composer install; php artisan key:generate; grunt build:app",
"install": "bower install",
"postinstall": "bin\\post_install.sh git#bitbucket.project/project.git"
},
I wanted to have "bower install" in postinstall, but didn't work so since install is essentially the same I put it there, now that I want a couple preinstall calls invoked I don't have the same solution available since only one option. I didn't want to split them all out in bash scripts for each if possible.
Separate commands using '&&' like this:
"preinstall": "composer install && php artisan key:generate && grunt build:app"
Related
When I try deploying my Firebase cloud functions I get the following error.
Desired behavior: Deploy functions successfully.
Error:
Error: There was an error reading functions/package.json:
functions/lib/index.js does not exist, can't deploy
Cloud Functions
Full log:
name#name-MacBook-Pro functions % firebase deploy
=== Deploying to 'newtiktok-21570'...
i deploying functions Running command: npm --prefix "$RESOURCE_DIR"
run lint
functions# lint /Users/name/Desktop/Yoveo/functions
eslint "src/**/*"
/Users/name/Desktop/Yoveo/functions/src/index.ts
186:67 warning 'timestamp' is defined but never used
#typescript-eslint/no-unused-vars 377:86 warning 'mediaNum' is
defined but never used #typescript-eslint/no-unused-vars 377:104
warning 'commentText' is defined but never used
#typescript-eslint/no-unused-vars 377:125 warning 'commentID' is
defined but never used #typescript-eslint/no-unused-vars 419:119
warning 'commentID' is defined but never used
#typescript-eslint/no-unused-vars 463:121 warning 'commentID' is
defined but never used #typescript-eslint/no-unused-vars 520:75
warning 'mediaNum' is defined but never used
#typescript-eslint/no-unused-vars 732:25 warning 'slap' is
defined but never used #typescript-eslint/no-unused-vars
✖ 8 problems (0 errors, 8 warnings)
Running command: npm --prefix "$RESOURCE_DIR" run build ✔ functions:
Finished running predeploy script.
Error: There was an error reading functions/package.json:
My p.json:
{
"name": "functions",
"scripts": {
"lint": "eslint \"src/**/*\"",
"build": "",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "12"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^9.2.0",
"firebase-functions": "^3.11.0"
},
"devDependencies": {
"#typescript-eslint/eslint-plugin": "^4.8.1",
"#typescript-eslint/parser": "^4.8.1",
"eslint": "^7.14.0",
"eslint-plugin-import": "^2.22.0",
"firebase-functions-test": "^0.2.0",
"typescript": "^3.8.0"
},
"private": true
}
cd into your functions folder and run this command
npm run-script build
This will create the lib/index.js file that is missing
firebase uses main field in package.json as program entry point,
set it properly, probably like this.
"main": "lib/src/index.js",
For some reason recently the build flow of firebase functions changed.
It used to be:
npm --prefix ./functions install ./functions
firebase deploy --only functions
now it is:
npm --prefix ./functions install ./functions
npm --prefix ./functions run build
firebase deploy --only functions
I have not researched what caused this change, but adding this as build step fixed the problem for me.
functions/lib/index.js does not exist
In case you are working in firebase project that contains a frontend or is structured as a monorepo, this error may also stem from having accidentally imported a frontend file in the functions backend part of the project. For all files that are not within your functions project scope, the typescript compiler will refuse to compile ts files referencing them. So in this case, the solution is to search for any imports containing /src/ (or any other paths pointing outside) and remove (or correct) them within your functions project.
you just have to change the main inside package.json file from lib/index.js to your index file which is usually under the src folder
Solved:
I was able to solve the problem by removing everything associated with Firebase functions. And running: firebase init again. After I cd functions run npm install. Then I was able to deploy successfully after fixing an error with:
3:26 error 'express' should be listed in the project's dependencies. Run 'npm i -S express' to add it import/no-extraneous-dependencies
Changing the firebase.json file to the following fixed my issue:
{
"functions": {
"predeploy": ["npm --prefix ./functions run build"],
"source": "functions"
}
}
I was able to fix this same issue by following Felix K indications, answered on Apr 28, 2021.
In case you are working in firebase project that contains a frontend or is structured as a monorepo, this error may also stem from having accidentally imported a frontend file in the functions backend part of the project. For all files that are not within your functions project scope, the typescript compiler will refuse to compile ts files referencing them. So in this case, the solution is to search for any imports containing /src/ (or any other paths pointing outside) and remove (or correct) them within your functions project.
In my case, I've accidently imported an interface from the frontend. When updating this import I was able to successfully deploy my function.
Solution from Edward Amoah Idun:
cd into your functions folder and run this command
npm run-script build
This will create the lib/index.js file that is missing
Yes, but it will create the index.js file that is missing in the wrong folder. Still necessary to check that you don't have imports from another projects.
The lib folder is for your built functions code, so you haven't built it. This can be done automatically by adding redeploy code to your firebase.json config file:
{
"functions": [
{
"predeploy": ["npm --prefix \"$RESOURCE_DIR\" run build"],
// rest of config...
}
]
}
I've seen a lot of package.json files where there are scripts that doesn't do anything but call a dependency with the same name. For example :
{
"scripts": {
"lint": "npm run tslint \"src/**/*.ts\"",
"tslint": "tslint"
},
"devDependencies": {
"tslint": "~4.4.2",
"tslint-loader": "^3.3.0"
}
}
Here we have the script tslint that just calls the dependency tslint. I guess that is some kind of a way to make the lint script shorter but how would it look like if there was no script called tslint.
I don't believe NPM has this kind of functionality built in. Yarn (the third-party NPM client built by Facebook, Google, Exponent and Tilde) on the other hand, does - you can just use yarn run and it will pick up the executable from your dependencies, even if you don't have a script for it defined in your package.json:
yarn run tslint
yarn run tslint "src/**/*.ts"
I am on freeCodeCamp, have reached this challenge. I have completed installing NPM, started a project and installed a module too, but I am stuck at NPM TEST which says:
Now you've installed something, and used npm ls to show what's going on. If you look at the package.json file, it has this rather odd bit in it:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
npm can be used as a task runner, and almost every module and project
will have a test script that runs to make sure everything is good. In
order to help remind you to do this, npm puts a "always failing" test
in there by default.
First, create a file called test.js. It doesn't have to do anything,
really. (This is npm class, not testing class.) But it has to exit
without throwing an error, or else the test fails.
Then, edit your package.json file to make your scripts section look like
this instead:
"scripts": {
"test": "node test.js"
},
Once that's done, run how-to-nom verify to check your work.
I tried couple of things I got online to create test.js, but I am not sure how to proceed further.
All you have to do is create an empty test.js file and edit your package.json file. Chances are you missed this step.
In order to pass the test, you need to update the echo \"Error: no test specified\" && exit 1 line with node test.js. As it is an empty file, it won't throw any error and once you run the how-to-npm verify command it will pass.
I've gotten some NPM package from a third party who is developing under Mac OSX. Their build can split into either development or production using "scripts" object in package.json. For example:
"scripts": {
"build": "NODE_ENV=dev node make.js --build",
"build-prod": "NODE_ENV=prod node make.js --build",
}
Under Unix, one can run either "npm run build" or "npm run build-prod" to build either directory (naturally, there are some conditional statements in make.js).
Of course, it does not work under Windows - I had to change the commands similar to this:
"scripts": {
"build": "set NODE_ENV=dev&& node make.js --build",
"build-prod": "set NODE_ENV=prod&& node make.js --build",
}
(Please note that it was important not to put a space before the '&&' - otherwise the environment variable was created with an extra white space in it which ruined all those comparisons in make.js).
However, I would like to have some universal source tree which would work under either Unix or Windows without editing. Could you please give some ideas on how to conditionally split the build depending on the OS?
The question is pretty old, but for these who faces the problem nowadays, npm starting from version >=5.1.0 supports setting shell for processing scripts. By default on Windows, npm internally uses cmd.exe for running scripts, even if npm command itself is typed in git-bash. After setting git-bash as shell, scripts that use bash syntax work normally on Windows:
npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"
Here one needs to substitute his correct path to git-bash executable.
I have been thinking for a while, but I doubt there is any aesthetic solution using these tools, to get the desired effect.
If you are able to influence the change in make.js, I would rather change this file to accept prod or dev as argument, example: node make.js --build=dev. With default value, to ensure backwards compatibility.
Using only npm and not modifying make.js, I could think of only running another JavaScript code, which would change environment variable, and then call make.js.
That will look something like:
"build": "node middleman.js"
Middleman.js file could then use child_process or another module to set variable and execute node make.js file.
If you do not want to create an extra file, you can then embed all the JavaScript inside the package.json using:
"build": "node -e 'my code'"
Be warned, that running "node -e 'process.env[\'NODE_ENV\']=\'dev\' && node make.js" will not work, as process.env sets variable in local process, not global (i.e. does not export to the system).
Not the direct solution, but for sake of best practices, make it work different.
I'v made a static single page site using grunt. I'm now trying to deploy it to heroku using the heroku-buildpack-nodejs-grunt for node grunt.
Below is a pic of my root directory:
Here's my Gruntfile package.json:
Procfile:
web: node index.html
When I run $ git push heroku master it gets to the Gruntfile and fails:
-----> Found Gruntfile, running grunt heroku:production task
>> Local Npm module "grunt-contrib-uglify" not found. Is it installed?
The above errors proceed to list all local NPM modules as not found. If I list all loadNpmTasks instead of using "load-grunt-tasks", I get the exact same error.
When I $ heroku logs I get:
Starting process with command `node web.js`
Error: Cannot find module '/app/web.js'
Can anyone see where I've gone wrong?
For anyone passing by here, I wasn't able to solve the problem. This is where I got to:
In my Gruntfile, I moved npm modules from devDependencies to dependencies. Heroku was then able to install these dependencies.
However, when Heroku ran the tasks, it stops at the haml task w/ error "You need to have Ruby and Haml installed and in your PATH for this task to work". Adding ruby & haml to the Gruntfile as engines did not work.
The only thing I can think of is that maybe Heroku installs your devDependencies first, tries to run Grunt, but since it didn't install load-grunt-tasks yet, you don't get the grunt.loadNpmTasks( 'grunt-contrib-uglify' ); line (which load-grunt-tasks does for you), and thus Grunt can't find the package.
Can you try changing your Gruntfile to explicitly list out all npm modules using the grunt.loadNpmTasks() method?
EDIT:
Just remembered another thing I had to do:
heroku labs:enable user-env-compile -a myapp
heroku config:set NODE_ENV=production
(Obviously replacing myapp with your Heroku app name.)
This makes Heroku allow user set environment variables and then sets your server to production. Try that, and set your dependencies and devDependencies as you had them originally (just to see if it works).
I am coming pretty late to the game here but I have used a couple methods and thought I would share.
Option 1: Get Heroku to Build
This is not my favorite method because it can take a long time but here it is anyway.
Heroku runs npm install --production when it receives your pushed changes. This only installs the production dependencies.
You don't have to change your environment variables to install your dev dependencies. npm install has a --dev switch to allow you to do that.
npm install --dev
Heroku provides an article on how you can customize your build. Essentially, you can run the above command as a postinstall script in your package.json.
"scripts": {
"start": "node index.js",
"postinstall": "npm install --dev && grunt build"
}
I think this is cleaner than putting dev dependencies in my production section or changing the environment variables back and forth to get my dependencies to build.
Also, I don't use a Procfile. Heroku can run your application by calling npm start (at least it can now almost two years after the OP). So as long as you provide that script (as seen above) Heroku should be able to start your app.
As far as your ruby dependency, I haven't attempted to install a ruby gem in my node apps on Heroku but this SO answer suggests that you use multi buildpack.
Option 2: Deploy Your Dependencies
Some argue that having Heroku build your application is bad form. They suggest that you should push up all of your dependencies. If you are like me and hate the idea of checking in your node_modules directory then you could create a new branch where you force add the node_modules directory and then deploy that branch. In git this looks like:
git checkout -b deploy
git add -f node_modules/
git commit -m "heroku deploy"
git push heroku --force deploy:master
git checkout master
git branch -D deploy
You could obviously make this into a script so that you don't have to type that every time.
Option 3: Do It All Yourself
This is my new favorite way to deploy. Heroku has added support for slug deploys. The previous link is a good read and I highly recommend it. I do this in my automated build from Travis-CI. I have some custom scripts to tar my app and push the slug to Heroku and its fast.
I faced a similar problem with Heroku not installing all of my dependencies, while I had no issue locally. I fixed it by running
heroku config:set USE_NPM_INSTALL=true
into the path, where I deployed my project from. This instructs Heroku to install your dependencies using npm install instead of npm ci, which is the default! From Heroku dev center:
"Heroku uses the lockfiles, either the package-lock.json or yarn.lock, to install the expected dependency tree, so be sure to check those files into git to ensure the same dependency versions across environments. If you are using npm, Heroku will use npm ci to set up the build environment."