如何在 angular.json 的脚本部分使用 glob 模式?
Posted
技术标签:
【中文标题】如何在 angular.json 的脚本部分使用 glob 模式?【英文标题】:How to use a glob pattern in the scripts section of angular.json? 【发布时间】:2020-02-27 20:26:42 【问题描述】:我有一个 AngularJS/Angular 混合应用程序,它需要一些时间才能完成迁移以完全成为一个 Angular 应用程序。当这个过程发生时,我想从以前的构建系统转移到使用 CLI 和 webpack 来管理所有旧的 AngularJS 脚本。这是可能的,因为我之前通过将我的所有脚本添加到 angular.json
中的 scripts
部分,如下所示:
"scripts": [
"src/app/angularjs/app.js",
"src/app/angularjs/controllers/main.js",
"src/app/angularjs/services/someService.js",
"src/app/angularjs/controllers/someController.js"
],
这运行良好,通过 ng serve
和 ng build
构建的 CLI 继续根据需要为混合引导应用程序工作。我现在遇到的问题是手动列出我正在迁移的当前应用程序的每个文件并不理想。我有数百个脚本需要添加,我需要的是能够使用如下通配模式:
"scripts": [
"src/app/angularjs/**/*.js"
],
问题是我所知道的这种语法不受支持。在angular.json
的assets
部分中支持全局模式 如此处所述,但在scripts
部分中不支持:https://angular.io/guide/workspace-config#assets-configuration
在scripts
部分我找不到类似的解决方案。它确实有一个扩展的对象 API,但没有什么能解决我可以告诉从此处列出的特定目录中选择 all .js
文件的问题:https://angular.io/guide/workspace-config#styles-and-scripts-configuration
是否可以通过某种方式使用 glob 模式或类似方法为angular.json
中的scripts
部分选择目录的所有文件,这样我就不必手动列出数百个单独的.js
文件?
【问题讨论】:
【参考方案1】:坏消息
scripts
部分不支持与 assets
部分相同的 glob 模式。
好消息(?)
由于您正在从 AngularJS 过渡,因此您希望将来不会有任何新文件要导入,因此您可以生成需要导入的所有文件的列表。
前往src/app/angular
目录并运行以下命令:
find . -iregex '.*\.\(js\)' -printf '"%p",\n'
这将为您提供您的清单,为方便起见已引用。您可能需要进行快速搜索/替换(将“.”更改为“src/app/angularjs”),并且不要忘记删除最后一个逗号,但是一旦您完成了该操作,您就应该准备就绪。
额外新闻
您可以使用-not
进一步过滤掉不需要的文件,因此(根据您的评论)您可以这样做:
find . -iregex '^.*\.js$' -not -iregex '^.*_test\.js$' -printf '"%p",\n'
这应该会给你所有的 .js 文件,而不需要你的 _test.js 文件。
亲吻
当然,这不是一个复杂的模式,所以正如@atconway 在下面指出的那样,这同样适用:
find . -iname "*.js" -not -iname "*_test.js" -printf '"%p",\n'
不过,我将保留上述内容,以便在正则表达式的全部功能可能派上用场的情况下使用。
【讨论】:
可靠的答案,从技术上讲,您甚至不必删除最后一个逗号。 @Woohoojin 实际上是你做的,因为它是一个 JSON。看看吧 这是我的下一个想法,即创建一个 Powershell 脚本或类似的东西来列出所有文件。对于阅读本文的不太懂命令行的人来说,请注意,上面的命令是Bash
shell 命令,必须照此运行。现在我只需要弄清楚如何修改 RegEx
以排除 _test.js
文件,我应该设置。
@atconway 因为不支持环视,最简单的做法可能是保持正则表达式不变,只需添加 -not
和要排除的正则表达式。就性能而言,也许不是最好的解决方案,但我不认为你需要经常这样做。我希望这会有所帮助!
是的,我能够将RegEx
全部删除,只需使用-iname
和-not -iname
,如本文所示:unix.stackexchange.com/questions/550721/… 即可完全按照我的需要获取列表。这是最终结果:find . -iname "*.js" -not -iname "*_test.js" -printf '"%p",\n'
【参考方案2】:
我想扩展 @JasonVerber 的分析器,这里是 Node.JS 代码,因此(我相信)是跨平台的。
首先安装find
包,然后将sn-p中的内容保存在一些file.js
中。
然后,指定路径,以便它们解析到您不想从哪里获取文件以及将生成的文件放到哪里。
在node file-name.js
之后,这会将所有找到的文件路径保存到result.txt
中的resultPath
,准备好Ctrl+A
、Ctrl+C
、Ctrl+V
。
const find = require('find');
const path = require('path');
const fs = require('fs');
// BEFORE USAGE INSTALL `find` package
// Path to the folder where to look for files
const sourcePath = path.resolve(path.join(__dirname, 'cordova-app', 'src'));
// Path that will be removed from absolute path to files
const pathToRemove = path.resolve(path.join(__dirname, 'cordova-app'));
// Path where to put result.txt
const resultPath = path.resolve(path.join(__dirname, './result.txt'));
// Collects the file paths
const res = [];
// Path with replaced \ onto /
const pathToRemovehReplaced = pathToRemove.replace(/\\/g, '/');
// Get all fils that match a regex
find.eachfile(/\.js$/, sourcePath, file =>
// First remove all \ with / and then remove the path from root to source so that only relative path is left
const fileReplaced = file.replace(/\\/g, '/').replace(`$pathToRemovehReplaced/`, '');
// Surround with quoutes
res.push(`"$fileReplaced"`);
).end(() =>
// Write file and concatenate results with newline and commas
fs.writeFileSync(resultPath, res.join(',\r\n'), 'utf8');
console.log('DONE!');
);
我在测试时得到的结果(/\.ts$/
for regex)
"src/app/app.component.spec.ts",
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/environments/environment.prod.ts",
"src/environments/environment.ts",
"src/main.ts",
"src/polyfills.ts",
"src/test.ts"
【讨论】:
以上是关于如何在 angular.json 的脚本部分使用 glob 模式?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular CLI 6: angular.json 中添加 Sass 编译?