第一次批处理文件尝试 - 异步命令有问题

1st Batch File attempt - trouble with asynchronous commands

我正在尝试编写我的第一个批处理文件来构建嵌套在 SilverStripe 项目中的 React 应用程序(使用节点包管理器),并重命名 js 和 css 构建文件,并移动媒体构建文件到 SilverStripe 项目中的新目录(这样它们就可以被配置为指向 SilverStripe 项目的虚拟主机获取)。

为了在 cmd 中启动脚本,我使用了以下带有两个参数的脚本名称:

updateReactInSS "C:\wamp64\www\example5" "C:\wamp64\www\example5\app\moe-card-app"

脚本确实成功执行了 npm 运行 构建,但之后没有继续。我的预感是:

下面是完整的脚本:

Rem ============================================================================================
Rem This batch script builds a React Application inside SilverStripe and
Rem moves media files if they exist to the public directory of the SilverStripe project.
Rem command line argument 1 = full path to the nested SilverStripe project folder
Rem command line argument 2 = full path to the nested React application
Rem It relies on node package manager and composer being installed.
Rem The result works with a virtual host configured to point at the SilverStripe project folder.
Rem =============================================================================================
@echo off
Rem Checking argument 1 entered correctly.
if "%~1"=="" (
echo You forgot to specify the full path to the SilverStripe project folder:
echo argument 1 = ?
goto finished
) else (
echo argument 1 = The path to the SilverStripe project folder is:
echo %1
)
Rem Checking argument 2 entered correctly.
if "%~2"=="" (
echo You forgot to specify the full path to the nested React application:
echo argument 2 = ?
goto finished
) else (
echo argument 2 = The path to the nested React application is:
echo %2
)
Rem Going to React application path. NOTE: could also add condition to check npm install if 1st time run
cd %2
cd
Rem Delete build directory if it exists. Using node package manager to build the React application.
if exist build\ del build /s /e
npm run build
Rem Adding time for npm run build to finish before continuing
TIMEOUT /T 20
echo TIMEOUT finished. Script continuing...
Rem Rename main.hashcode.js to main.bundle.js so consistent with requirements in related SS page controller.
cd %2\build\static\js
cd
rename main.*.js "main.bundle.js"
Rem Rename main.hashcode.css to main.bundle.css so consistent with requirements in related SS page controller.
cd %2\build\static\css
cd
rename main.*.css "main.bundle.css"
Rem Going to to SilverStripe project root to run composer vendor-expose command creating sym-links if not there.
cd %1
composer vendor-expose
Rem Copying media build files if media directory exists in React build files to the public folder in SilverStripe. project.
if exist %2\build\static\media (
MD \public\static\media
xcopy %2\build\static\media %1\public\static\media /s /e
) else (
goto finished
)
if errorlevel 4 goto lowmemory
if errorlevel 2 goto abort
if errorlevel 0 goto exit
:lowmemory
echo Insufficient memory to copy files or
echo invalid drive or command-line syntax.
goto exit
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
:finished
echo The programme updateReactInSS has completed.
:exit

这是我在 Whosebug 上提出的一个相关问题,其中包含有关我要实现的目标的更多详细信息。如果你回答了这个问题,你也回答了 one = 2 birds with one stone!!!

这个问题的解决方法是将原来的单个脚本分成 2 个脚本,可以在命令行中 运行。此拆分必须在 npm run build 完成后继续,如果 composer vendor-expose 需要 运行 并完成。这是因为我的脚本在完成时会自动退出。下面是两个带参数的脚本:

updateReactInSS_1 "C:\wamp64\www\silverstripeProject" "C:\wamp64\www\silverstripeProject\app\ReactApp"

Rem =======updateReactInSS_1=============
Rem updateReactInSS_1 is part 1 of 2 that updates a React Application nested inside a SilverStripe project.
Rem It deletes an existing React application build directory and rebuilds it with npm.
Rem Dependencies are node package manager (npm) and Composer installed globally by editing the
Rem environment variable path on your machine so they can be run from the command line (cmd).
Rem You also need a virtual host configured to point at your-SilverStripe-project folder.
Rem Argument 1 = full path to the nested SilverStripe project folder
Rem Argument 2 = full path to the nested React application
Rem updateReactInSS_1 file is located at Argument 2.
Rem updateReactInSS_2 file is located at Argument 2. It renames the "hash" js and css build files to "bundle"
Rem then copies and moves existing media build media files to the public directory of the SilverStripe project.
Rem Note: If "composer vendor-expose" runs then updateReactInSS_2 needs to be run again to complete the script.
Rem =======START===========
@echo off
Rem Checking argument 1 entered correctly.
if "%~1"=="" (
echo You forgot to specify the full path to the SilverStripe project folder:
echo argument 1 = ?
goto exit
) else (
echo argument 1 = %1 (path to the SilverStripe project folder)
)
Rem Checking argument 2 entered correctly.
if "%~2"=="" (
echo You forgot to specify the full path to the nested React application:
echo argument 2 = ?
goto exit
) else (
echo argument 2 = %2 (path to the nested React application)
)
Rem Going to React application path (NOTE could also add condition to check npm install if 1st time run)
cd %2
Rem Deletes the React application build directory if it exists and then use node package manager to build the React application.
if exist build\ del build /s /e
npm run build
:exit

updateReactInSS_2 "C:\wamp64\www\silverstripeProject" "C:\wamp64\www\silverstripeProject\app\ReactApp"

Rem updateReactInSS_2 is part 2 of 2.
Rem Argument 1 = full path to the nested SilverStripe project folder
Rem Argument 2 = full path to the nested React application
Rem updateReactInSS_2 file is located at Argument 2 (where updateReactInSS_1 is forced to end by npm run build).
Rem It renames the "hash" js and css build files to "bundle" and copies and moves
Rem existing build media files to the public directory of the SilverStripe project.
Rem Note: If updateReactInSS_2 is forced to end by composer vendor-expose command at Argument 1,
Rem you need to cd to Argument 2 to run updateReactInSS_2 again to complete the script. 
Rem If symlinks have already been created by Composer, the command composer vendor-expose is
Rem skipped so updateReactInSS_2 only needs to be run once from the command line. 
Rem =======START=======
@echo off
Rem Checking argument 1 entered correctly.
if "%~1"=="" (
echo You forgot to specify the full path to the SilverStripe project folder:
echo argument 1 = ?
goto finished
) else (
echo argument 1 = %1 (path to the SilverStripe project folder)
)
Rem Checking argument 2 entered correctly.
if "%~2"=="" (
echo You forgot to specify the full path to the nested React application:
echo argument 2 = ?
goto finished
) else (
echo argument 2 = %2 (path to the nested React application)
)
Rem Rename main.hashcode.js to main.bundle.js so consistent with requirements in related SS page controller.
cd %2\build\static\js
rename main.*.js "main.bundle.js"
Rem Rename main.hashcode.css to main.bundle.css so consistent with requirements in related SS page controller.
cd %2\build\static\css
rename main.*.css "main.bundle.css"
Rem checking if composer vendor-expose needs to run to create symlinking.
cd %1\public\resources
if not exist app\moe-card-app\build\ (
echo Please cd to %2 and run updateReactInSS_2 again to complete script commands.
cd %1
composer vendor-expose
)
Rem Go to public folder of SilverStripe project if no static\media directory exists, make it.
cd %1\public
if not exist static\media\ (
MD 1%\public\static\media
)
Rem Copying media build files if media directory exists in React build files to the public folder in SilverStripe. project.
if exist %2\build\static\media\ (
xcopy %2\build\static\media %1\public\static\media /s /e
) else (
echo No media directory to copy in react build\static\
goto exit
)
if errorlevel 4 goto lowmemory
if errorlevel 2 goto abort
if errorlevel 0 (
cd %2
goto finished
)
:lowmemory
echo Insufficient memory to copy files or
echo invalid drive or command-line syntax.
goto exit
:abort
echo You pressed CTRL+C to end the copy operation.
goto exit
:finished
echo updateReactInSS_2 COMPLETED
:exit

请评论更好的设计方案。是否可以将它们制作成一个脚本或由第三个脚本控制,以便只需要在命令行中输入一个命令?我正在学习并且一定会做一些与这里的最佳实践和惯例相反的事情!!!!!非常感谢您花时间在 Whosebug 上分享您的知识 :-)。