在我的凤凰应用程序中,我正在运行一个位于应用程序内assets/
目录中的React前端...它拥有自己的package.json
文件,我想能够从Phoenix应用程序的mix.exs
文件中运行别名的NPM脚本。我一直在尝试使用Elixir System.cmd()
,但它似乎没有做到这一点。
基本上,我为我的前端设置了一个lint命令 - 在assets/package.json
,我已经
"lint": "eslint ./*.js ./js/*.js || exit 0"
并从$ npm run lint
目录运行assets/
按预期工作......但是只能从应用程序的顶级运行命令就可以了。
在我的mix.exs
文件中,我正在尝试像这样的别名:
defp aliases do
[
"lint": [System.cmd("npm", ["run lint"], cd: "assets")
]
end
但是运行mix lint
会产生一个非常冗长的错误:
** (FunctionClauseError) no function clause matching in Mix.Task.run_alias/3
The following arguments were given to Mix.Task.run_alias/3:
# 1
[{"\nUsage: npm <command>\n\nwhere <command> is one of:\n access, adduser, bin, bugs, c, cache, completion, config,\n ddp, dedupe, deprecate, dist-tag, docs, edit, explore, get,\n help, help-search, i, init, install, install-test, it, link,\n list, ln, login, logout, ls, outdated, owner, pack, ping,\n prefix, prune, publish, rb, rebuild, repo, restart, root,\n run, run-script, s, se, search, set, shrinkwrap, star,\n stars, start, stop, t, tag, team, test, tst, un, uninstall,\n unpublish, unstar, up, update, v, version, view, whoami\n\nnpm <cmd> -h quick help on <cmd>\nnpm -l display full usage info\nnpm help <term> search for help on <term>\nnpm help npm involved overview\n\nSpecify configs in the ini-formatted file:\n /Users/user/.npmrc\nor on the command line via: npm <command> --key value\nConfig info can be viewed via: npm help config\n\nnpm@3.10.10 /Users/user/.nvm/versions/node/v6.11.1/lib/node_modules/npm\n", 1}]
# 2
[]
# 3
:ok
Attempted function clauses (showing 3 out of 3):
defp run_alias([h | t], alias_args, _res) when is_binary(h)
defp run_alias([h | t], alias_args, _res) when is_function(h, 1)
defp run_alias([], _alias_task, res)
(mix) lib/mix/task.ex:331: Mix.Task.run_alias/3
(mix) lib/mix/task.ex:266: Mix.Task.run/2
(mix) lib/mix/cli.ex:75: Mix.CLI.run_task/2
(elixir) lib/code.ex:376: Code.require_file/2
好的,显然我做错了什么。是否可以在Phoenix应用程序的子目录上执行NPM命令?
答案 0 :(得分:3)
首先,run
和lint
应该是参数列表中的单独字符串。
其次,您拥有的代码将立即运行命令,而不是在调用别名时。
您可以使用"run -e ..."
别名在别名中执行任意代码,如下所示:
"lint": [~s|run -e 'System.cmd("npm", ["run", "lint"], cd: "assets")'|)
(我使用~s||
语法只是为了更容易输入包含单引号和双引号的字符串。)
答案 1 :(得分:0)
还有一个扩展名可用于执行此操作,但不幸的是它无法遍历路径。但也许会被修补。
答案 2 :(得分:0)
替代~s||带有 cd
的符号,我们也可以在 npm 命令中使用 --prefix
标志。
lintjs: ["cmd npm run format:ci --prefix assets"]
如果使用伞形项目,请在其运行的应用中定义别名,并在项目根目录中添加别名。
<root>/mix.exs
defp aliases do
[
# run `mix setup` in all child apps
setup: ["cmd mix setup"],
# app-specific alias defined in onstage_web/mix.exs
lint: ["cmd --app myapp_name mix lintjs"]
]
end
<root>/apps/myapp_name/mix.exs
defp aliases do
[
# run npm install in child app
setup: ["deps.get", "cmd npm install --prefix assets"],,
# simplified/equivalent of accepted answer
lintjs: ["cmd npm run format:ci --prefix assets"]
]
end
现在,我们可以从项目根目录运行 mix lint
来对子应用中的 JS 进行 lint。
另外,请记住在进行更改后运行 mix compile
。