在 Mac M1 上,无法运行 package.json 中的脚本: - sh: <dependency>: command not found

问题描述

我刚买了一台 Mac Mini M1 供个人使用,我正在尝试运行一个预先存在的 React 应用程序。我成功安装了 nodejs 和 npm,据我所知,运行 npm install 确实正确添加node_modules 文件夹;但是每当我运行 npm startnpm run <script> 时,我都会收到错误消息。似乎 npm 无法访问项目的任何依赖项。我也使用 rosetta 终端尝试过,结果相同。

举个例子,我用 npx create-react-app test_app 初始化了一个新的 React 项目,然后 cd 进入它并运行 npm start。我得到:

test_repo@0.1.0 start
> react-scripts start

sh: react-scripts: command not found

如何让这些命令正常运行并启动应用程序?

这是我用于 node 和 npm 的:

➜  test_repo npm -v
7.6.0
➜  test_repo node -v
v15.11.0

解决方法

我现在找到了一个(非常)hacky 的解决方案。我不是 npm 专家,但我发现 npm 脚本间接引用依赖项 - 例如,有一个命令说

 import { AnimationController } from '@ionic/angular';
export const SwipeToCloseDefaults = {
    MIN_PRESENTING_SCALE: 0.93,};
export const enterFromRightAnimation = (baseEl,presentingEl) => {
    const backdropAnimation = new AnimationController().create()
      .addElement(baseEl.querySelector('ion-backdrop'))
      .fromTo('opacity',0.01,'var(--backdrop-opacity)')
      .beforeStyles({
      'pointer-events': 'none'
    })
      .afterClearStyles(['pointer-events']);
    const wrapperAnimation = new AnimationController().create()
      .addElement(baseEl.querySelectorAll('.modal-wrapper,.modal-shadow'))
      .beforeStyles({ 'opacity': 1 })
      .fromTo('transform','translateX(100vh)','translateX(0vh)');
    const baseAnimation = new AnimationController().create()
      .addElement(baseEl)
      .easing('cubic-bezier(0.32,0.72,1)')
      .duration(500)
      .addAnimation(wrapperAnimation);
    if (presentingEl) {
      const isMobile = window.innerWidth < 768;
      const hasCardModal = (presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined);
      const presentingAnimation = new AnimationController().create()
        .beforeStyles({
        'transform': 'translateX(0)','transform-origin': 'top center','overflow': 'hidden'
      });
      const bodyEl = document.body;
      if (isMobile) {
        /**
         * Fallback for browsers that does not support `max()` (ex: Firefox)
         * No need to worry about statusbar padding since engines like Gecko
         * are not used as the engine for standlone Cordova/Capacitor apps
         */
        const transformOffset = (!CSS.supports('width','max(0px,1px)')) ? '30px' : 'max(30px,var(--ion-safe-area-top))';
        const modalTransform = hasCardModal ? '-10px' : transformOffset;
        const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
        const finalTransform = `translateX(${modalTransform}) scale(${toPresentingScale})`;
        presentingAnimation
          .afterStyles({
          'transform': finalTransform
        })
          .beforeAddWrite(() => bodyEl.style.setProperty('background-color','black'))
          .addElement(presentingEl)
          .keyframes([
          { offset: 0,filter: 'contrast(1)',transform: 'translateX(0px) scale(1)',borderRadius: '0px' },{ offset: 1,filter: 'contrast(0.85)',transform: finalTransform,borderRadius: '10px 10px 0 0' }
        ]);
        baseAnimation.addAnimation(presentingAnimation);
      }
      else {
        baseAnimation.addAnimation(backdropAnimation);
        if (!hasCardModal) {
          wrapperAnimation.fromTo('opacity','0','1');
        }
        else {
          const toPresentingScale = (hasCardModal) ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
          const finalTransform = `translateX(-10px) scale(${toPresentingScale})`;
          presentingAnimation
            .afterStyles({
            'transform': finalTransform
          })
            .addElement(presentingEl.querySelector('.modal-wrapper'))
            .keyframes([
            { offset: 0,transform: 'translateX(0) scale(1)' },transform: finalTransform }
          ]);
          const shadowAnimation =new AnimationController().create()
            .afterStyles({
            'transform': finalTransform
          })
            .addElement(presentingEl.querySelector('.modal-shadow'))
            .keyframes([
            { offset: 0,opacity: '1',opacity: '0',transform: finalTransform }
          ]);
          baseAnimation.addAnimation([presentingAnimation,shadowAnimation]);
        }
      }
    }
    else {
      baseAnimation.addAnimation(backdropAnimation);
    }
    return baseAnimation;
  };
  

export const leaveToRightAnimation =  (baseEl,presentingEl,duration = 500) => {
    const backdropAnimation = new AnimationController().create()
      .addElement(baseEl.querySelector('ion-backdrop'))
      .fromTo('opacity','var(--backdrop-opacity)',0.0);
    const wrapperAnimation = new AnimationController().create()
      .addElement(baseEl.querySelectorAll('.modal-wrapper,'translateX(0vh)','translateX(100vh)');
    const baseAnimation = new AnimationController().create()
      .addElement(baseEl)
      .easing('cubic-bezier(0.32,1)')
      .duration(duration)
      .addAnimation(wrapperAnimation);
    if (presentingEl) {
      const isMobile = window.innerWidth < 768;
      const hasCardModal = (presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined);
      const presentingAnimation = new AnimationController().create()
        .beforeClearStyles(['transform'])
        .afterClearStyles(['transform'])
        .onFinish(currentStep => {
        // only reset background color if this is the last card-style modal
        if (currentStep !== 1) {
          return;
        }
        presentingEl.style.setProperty('overflow','');
        const numModals = Array.from(bodyEl.querySelectorAll('ion-modal')).filter(m => m.presentingElement !== undefined).length;
        if (numModals <= 1) {
          bodyEl.style.setProperty('background-color','');
        }
      });
      const bodyEl = document.body;
      if (isMobile) {
        const transformOffset = (!CSS.supports('width',var(--ion-safe-area-top))';
        const modalTransform = hasCardModal ? '-10px' : transformOffset;
        const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
        const finalTransform = `translateX(${modalTransform}) scale(${toPresentingScale})`;
        presentingAnimation
          .addElement(presentingEl)
          .keyframes([
          { offset: 0,borderRadius: '10px 10px 0 0' },borderRadius: '0px' }
        ]);
        baseAnimation.addAnimation(presentingAnimation);
      }
      else {
        baseAnimation.addAnimation(backdropAnimation);
        if (!hasCardModal) {
          wrapperAnimation.fromTo('opacity','1','0');
        }
        else {
          const toPresentingScale = (hasCardModal) ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
          const finalTransform = `translateX(-10px) scale(${toPresentingScale})`;
          presentingAnimation
            .addElement(presentingEl.querySelector('.modal-wrapper'))
            .afterStyles({
            'transform': 'translate3d(0,0)'
          })
            .keyframes([
            { offset: 0,transform: finalTransform },transform: 'translateX(0) scale(1)' }
          ]);
          const shadowAnimation = new AnimationController().create()
            .addElement(presentingEl.querySelector('.modal-shadow'))
            .afterStyles({
            'transform': 'translateX(0) scale(1)'
          })
            .keyframes([
            { offset: 0,transform: 'translateX(0) scale(1)' }
          ]);
          baseAnimation.addAnimation([presentingAnimation,shadowAnimation]);
        }
      }
    }
    else {
      baseAnimation.addAnimation(backdropAnimation);
    }
    return baseAnimation;
  };
    

告诉 npm 在 "test": "jest" 中查找名为 node_modules/.bin 的文件并运行它。 这个问题与 npm 理解这一点有关。但是可以通过将每个依赖项的地址放在脚本中来解决这个问题,例如:

jest

我能够以这种方式构建事物。如果有人提出更好的答案,请告诉我:P

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...