5

I was wrong

The reason why npm install whatever deletes the node_modules/- folder is different: I thought it runs preinstall but no postinstall and I was wrong.

I runs neither of the two scripts.

The reason seems to be that npm install whatever also removes all packages not mentioned in my package.json. Funnilly, it does not install packages mentioned in my package.json but missing in node_modules. It's exactly like Michael Waddell wrote in a comment. This makes no sense to me, but....


Following this comment, I switched to absolute imports and rely on postinstall (in my own package.json) to create the link

{
  "scripts": {
    "preinstall": "rm node_modules/-",
    "postinstall": "ln -s `pwd`/src node_modules/-",
    ...
  },
}

It works well, unless when I really install something. With

npm install

the link gets deleted and then re-created. However, with

npm install whatever

the link gets deleted, but not re-created. Is this a bug or is this intentional and I should use some other "postinstall"?

Please note that I'm not concerned about losing my src directory. That's a different problem. My problem is the "postinstall" running only sometimes.

Update

People commented that the hooks only get run when running npm install without any arguments. I could live with that, but it's not true:

> ls -l node_modules/-
lrwxrwxrwx 1 maaartinus maaartinus 40 May 29 11:53 node_modules/- -> /home/maaartinus/work/octopus/reocto/src

> npm i whatever
foo bar baz blah

> ls -l node_modules/-
ls: cannot access 'node_modules/-': No such file or directory

This mean that preinstall runs, but postinstall did not. This sounds like a bug...

> node -v
v12.16.3
> npm -v
6.13.4

Update 2

The pre- and postinstall scripts are in my own package.json (which can be understood from the context, but I should have stated clearly).

maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • I think you should check on this link for using absolute paths without getting any files deleted ..." https://github.com/facebook/create-react-app/issues/5118#issuecomment-464025389 " ...The link you mentioned it has some disadvantage as you can see in github. – Pallamolla Sai May 15 '20 at 16:40
  • @PALLAMOLLASAI I'm not afraid about this setting being dangerous - I know about the problem of cleaning the src directory via the symlink (a stupid old bug, hopefully solved in the meantime), but I commit very often, so the possible harm is limited. The problem with all the smart solutions is that none of them is supported by react/CRA. *They may break anytime.* – maaartinus May 16 '20 at 14:37
  • Could it be that postinstall is supposed to run when you install the current package, not when you install other packages? – ray May 25 '20 at 23:41
  • @rayhatfield Maybe... I couldn't find any such info. Anyway, I need something really working... – maaartinus May 26 '20 at 05:03
  • @maaartinus Could you just [alias](https://webpack.js.org/configuration/resolve/#resolvealias) your prefix in your webpack config? e.g. `{ '-': [path.resolve(__dirname, 'src/')}`? – ray May 28 '20 at 17:10
  • Sorry. I now see that that was the original question in the github issue you linked to. I guess you'd have to eject to change the webpack config, or change it locally in `node_modules/react-scripts/config/`, but the latter is a bit of a hack and it's going to reset every time you reinstall. You could have a postinstall script that updates the react-scripts config, but again, feels like a bit of a hack. – ray May 28 '20 at 18:09
  • 1
    preinstall and postinstall scripts only run when you do an "npm install" - there's no way to run them when you install modules (see https://stackoverflow.com/a/46729184/1238190). It's not the case that the "preinstall" script is running but the "postinstall" is not. Installing a module tells npm to "cleanup" the folder. My recommendation would be to create a shell script (e.g. npm_install.sh) that does all 3 steps and use that instead of calling "npm install module" – Michael Waddell May 28 '20 at 20:58
  • As others have said, lifecycle hooks/scripts such as `postinstall` are invoked only when running the generic `npm install` command. However, If you're wanting a `postinstall` script to run whenever you run `npm install whatever` then you'll need to override npm's logic at the shell level. See my answer [here](https://stackoverflow.com/questions/59934610/run-a-script-like-postinstall-after-npm-installing-a-single-package/60096171#60096171) which shows how that can be achieved on _*nix_ when running `npm install whatever` in a specific project directory. – RobC May 29 '20 at 09:32
  • @MichaelWaddell I tried again, and it's not exactly true: See my edit. – maaartinus May 29 '20 at 09:51
  • @RobC Thank you, but what happens is pretty annoying, but doesn't deserve that much code - especially when it can't be placed in the directory itself. :( – maaartinus May 29 '20 at 10:05
  • @maaartinus - The behaviour demonstrated in your first **Update** section is a bug. When running `npm install whatever`, the `pre-` and `postinstall` scripts defined in your own _package.json_ should not be invoked. The expected behaviour is that they _should_ only be invoked when either; **A)** You run `npm install` in your projects directory. Or, **B)** Your resultant project/package is installed as a dependency for some other project. Interestingly, in [issue #481](https://github.com/npm/cli/issues/481) someone is requesting the behaviour that you currently encounter as a new feature. – RobC May 29 '20 at 12:16
  • 1
    @MichaelWaddell You're right (and took me a while to understand it). Feel free to vote for closing as a duplicate. – maaartinus May 30 '20 at 01:02

1 Answers1

-1

sometime node currpted due to some reason therefore its delete node_module folder. you can install whatever by yarn

yarn add whatever

preinstall & postinstall

preinstall: Run BEFORE the package is installed install

postinstall: Run AFTER the package is installed.

Absolute path:

install babel-plugin-module-resolver by

yarn add -D babel-plugin-module-resolver
yarn add -D customize-cra

then add relative path in babel.config.js file like this

const { override, addBabelPlugins } = require('customize-cra');
module.exports = override(

    ...addBabelPlugins([
        'module-resolver',
        {
            alias : {
                '@components'     : './src/components',
            }
        }
    ])
);

then you can use an absolute path like this

import TextLabel from '@components/textLabel/index.js'
Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80