【问题标题】:1st Batch File attempt - trouble with asynchronous commands第一次批处理文件尝试 - 异步命令问题
【发布时间】:2019-05-27 19:06:49
【问题描述】:

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

要在 cmd 中启动脚本,我使用以下脚本名称和两个参数:

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

脚本确实成功地执行了 npm run build 但之后不再继续。我的预感是:

  • 可能发生了异步事件?我为此添加了超时,但可能语法错误。以下行永远不会运行: echo "超时结束。脚本继续..."
  • 我的语法可能有误,无法访问正确的目录?

以下是完整的脚本:

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

这是我在 StackOverFlow 上提出的一个相关问题,其中详细说明了我想要实现的目标。如果你回答了这个问题,你也回答了 1 = 2 只鸟用一块石头!!!

【问题讨论】:

  • 目前我能提供的最好的方法就是让您了解每个命令的工作原理。为此,您可以通过在命令提示符处输入命令名称和其帮助选项/? 来访问每个命令的帮助信息。此外,您应该使用Rem 进行备注,而不是格式错误的标签::。要检查空参数,您应该使用If "%~1" == "",要检查是否存在目录而不是文件,您应该使用尾部反斜杠if exist build\ 。我还建议您不要用双引号括住任何 echo 字符串,例如If Exist "build\"CD "%~1".
  • 非常感谢!我将对脚本进行这些更改并编辑此问题。

标签: reactjs batch-file silverstripe-4


【解决方案1】:

解决这个问题的方法是将原来的单个脚本分成 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

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

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    相关资源
    最近更新 更多