如何解决有没有办法从模板中获取 Angular AST使用 ng-ast?
我想构建一个应用程序,它可以读取 Angular 应用程序的源文件,然后使用模板文件的 AST。
这是一个可以重现问题的独立节点脚本:
const Path = require('path');
const fs = require('fs');
const { WorkspaceSymbols } = require('ngast');
try { fs.mkdirsync("./foo") } catch (e) {};
try { fs.mkdirsync("./foo/src") } catch (e) {};
try { fs.mkdirsync("./foo/src/app") } catch (e) {};
const files = {
"README.md": "# angular-ivy-scfsqv\n\n[Edit on StackBlitz ⚡️](https://stackblitz.com/edit/angular-ivy-scfsqv)","angular.json": "{\n \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n \"version\": 1,\n \"newProjectRoot\": \"projects\",\n \"projects\": {\n \"demo\": {\n \"root\": \"\",\n \"sourceRoot\": \"src\",\n \"projectType\": \"application\",\n \"prefix\": \"app\",\n \"schematics\": {},\n \"architect\": {\n \"build\": {\n \"builder\": \"@angular-devkit/build-angular:browser\",\n \"options\": {\n \"outputPath\": \"dist/demo\",\n \"index\": \"src/index.html\",\n \"main\": \"src/main.ts\",\n \"polyfills\": \"src/polyfills.ts\",\n \"tsConfig\": \"src/tsconfig.app.json\",\n \"assets\": [\n \"src/favicon.ico\",\n \"src/assets\"\n ],\n \"styles\": [\n \"src/styles.css\"\n ],\n \"scripts\": []\n },\n \"configurations\": {\n \"production\": {\n \"fileReplacements\": [\n {\n \"replace\": \"src/environments/environment.ts\",\n \"with\": \"src/environments/environment.prod.ts\"\n }\n ],\n \"optimization\": true,\n \"outputHashing\": \"all\",\n \"sourceMap\": false,\n \"extractCss\": true,\n \"namedChunks\": false,\n \"aot\": true,\n \"extractLicenses\": true,\n \"vendorChunk\": false,\n \"buildOptimizer\": true\n }\n }\n },\n \"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"options\": {\n \"browserTarget\": \"demo:build\"\n },\n \"configurations\": {\n \"production\": {\n \"browserTarget\": \"demo:build:production\"\n }\n }\n },\n \"extract-i18n\": {\n \"builder\": \"@angular-devkit/build-angular:extract-i18n\",\n \"options\": {\n \"browserTarget\": \"demo:build\"\n }\n },\n \"test\": {\n \"builder\": \"@angular-devkit/build-angular:karma\",\n \"options\": {\n \"main\": \"src/test.ts\",\n \"tsConfig\": \"src/tsconfig.spec.json\",\n \"karmaConfig\": \"src/karma.conf.js\",\n \"styles\": [\n \"styles.css\"\n ],\n \"scripts\": [],\n \"src/assets\"\n ]\n }\n },\n \"lint\": {\n \"builder\": \"@angular-devkit/build-angular:tslint\",\n \"options\": {\n \"tsConfig\": [\n \"src/tsconfig.app.json\",\n \"src/tsconfig.spec.json\"\n ],\n \"exclude\": [\n \"**/node_modules/**\"\n ]\n }\n }\n }\n }\n },\n \"defaultProject\": \"demo\"\n}","package.json": "{\n \"name\": \"angular\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"dependencies\": {\n \"@angular/animations\": \"^11.0.8\",\n \"@angular/common\": \"^11.0.8\",\n \"@angular/compiler\": \"^11.0.8\",\n \"@angular/core\": \"^11.0.8\",\n \"@angular/forms\": \"^11.0.8\",\n \"@angular/platform-browser\": \"^11.0.8\",\n \"@angular/platform-browser-dynamic\": \"^11.0.8\",\n \"@angular/router\": \"^11.0.8\",\n \"rxjs\": \"^6.6.3\",\n \"tslib\": \"^2.1.0\",\n \"zone.js\": \"^0.11.3\"\n },\n \"scripts\": {\n \"ng\": \"ng\",\n \"start\": \"ng serve\",\n \"build\": \"ng build\",\n \"test\": \"ng test\",\n \"lint\": \"ng lint\",\n \"e2e\": \"ng e2e\"\n },\n \"devDependencies\": {\n \"@angular-devkit/build-angular\": \"~0.1100.4\",\n \"@angular/cli\": \"~11.0.4\",\n \"@angular/compiler-cli\": \"~11.0.4\",\n \"@types/jasmine\": \"~3.6.0\",\n \"@types/node\": \"^12.11.1\",\n \"codelyzer\": \"^6.0.0\",\n \"jasmine-core\": \"~3.6.0\",\n \"jasmine-spec-reporter\": \"~5.0.0\",\n \"karma\": \"~5.1.0\",\n \"karma-chrome-launcher\": \"~3.1.0\",\n \"karma-coverage\": \"~2.0.3\",\n \"karma-jasmine\": \"~4.0.0\",\n \"karma-jasmine-html-reporter\": \"^1.5.0\",\n \"protractor\": \"~7.0.0\",\n \"ts-node\": \"~8.3.0\",\n \"tslint\": \"~6.1.0\",\n \"typescript\": \"~4.0.2\"\n }\n}","tsconfig.json": "{\n \"compileOnSave\": false,\n \"compilerOptions\": {\n \"baseUrl\": \"./\",\n \"outDir\": \"./dist/out-tsc\",\n \"sourceMap\": true,\n \"declaration\": false,\n \"downlevelIteration\": true,\n \"experimentalDecorators\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"node\",\n \"importHelpers\": true,\n \"target\": \"es2015\",\n \"typeRoots\": [\n \"node_modules/@types\"\n ],\n \"lib\": [\n \"es2018\",\n \"dom\"\n ]\n },\n \"angularCompilerOptions\": {\n \"enableIvy\": true,\n \"fullTemplateTypeCheck\": true,\n \"strictInjectionParameters\": true\n }\n}","src/index.html": "<link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css\">\n<my-app>loading</my-app>","src/main.ts": "import './polyfills';\n\nimport { enableProdMode } from '@angular/core';\nimport { platformbrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\n\nplatformbrowserDynamic().bootstrapModule(AppModule).then(ref => {\n // Ensure Angular destroys itself on hot reloads.\n if (window['ngRef']) {\n window['ngRef'].destroy();\n }\n window['ngRef'] = ref;\n\n // Otherwise,log the boot error\n}).catch(err => console.error(err));","src/polyfills.ts": "/**\n * This file includes polyfills needed by Angular and is loaded before the app.\n * You can add your own extra polyfills to this file.\n *\n * This file is divided into 2 sections:\n * 1. browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.\n * 2. Application imports. Files imported after ZoneJS that should be loaded before your main\n * file.\n *\n * The current setup is for so-called \"evergreen\" browsers; the last versions of browsers that\n * automatically update themselves. This includes Safari >= 10,Chrome >= 55 (including Opera),\n * Edge >= 13 on the desktop,and iOS 10 and Chrome on mobile.\n *\n * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html\n */\n\n/***************************************************************************************************\n * broWSER polyFILLS\n */\n\n/** IE9,IE10 and IE11 requires all of the following polyfills. **/\n// import 'core-js/es6/symbol';\n// import 'core-js/es6/object';\n// import 'core-js/es6/function';\n// import 'core-js/es6/parse-int';\n// import 'core-js/es6/parse-float';\n// import 'core-js/es6/number';\n// import 'core-js/es6/math';\n// import 'core-js/es6/string';\n// import 'core-js/es6/date';\n// import 'core-js/es6/array';\n// import 'core-js/es6/regexp';\n// import 'core-js/es6/map';\n// import 'core-js/es6/set';\n\n/** IE10 and IE11 requires the following for NgClass support on SVG elements */\n// import 'classlist.js'; // Run `npm install --save classlist.js`.\n\n/** IE10 and IE11 requires the following to support `@angular/animation`. */\n// import 'web-animations-js'; // Run `npm install --save web-animations-js`.\n\n\n/** Evergreen browsers require these. **/\n// import 'core-js/es6/reflect';\n// import 'core-js/es7/reflect';\n\n\n/**\n * Web Animations `@angular/platform-browser/animations`\n * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.\n * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).\n */\n// import 'web-animations-js'; // Run `npm install --save web-animations-js`.\n\n\n\n/***************************************************************************************************\n * Zone JS is required by Angular itself.\n */\nimport 'zone.js/dist/zone'; // Included with Angular CLI.\n\n\n/***************************************************************************************************\n * APPLICATION IMPORTS\n */\n\n/**\n * Date,currency,decimal and percent pipes.\n * Needed for: All but Chrome,Firefox,Edge,IE11 and Safari 10\n */\n// import 'intl'; // Run `npm install --save intl`.","src/styles.css": "/* Add application styles & imports to this file! */","src/app/app.component.html": "<div class=\"container\">\n<div class=\"row\">\n\t<div class=\"col-md-6\">\n\t\t<h3 class=\"mb-5\">Invoice</h3>\n\t\t<div>\n\t\t\t<div class=\"row mb-2\">\n\t\t\t\t<label for=\"client\" class=\"col-form-label col-2\">Client</label>\n\t\t\t\t<div class=\"col-6\">\n\t\t\t\t\t<input type=\"text\" id=\"client\" class=\"form-control\">\n </div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"row mb-2\">\n\t\t\t\t\t<label for=\"amount\" class=\"col-form-label col-2\">Amount</label>\n\t\t\t\t\t<div class=\"col-6\">\n\t\t\t\t\t\t<input type=\"number\" id=\"amount\" class=\"form-control\">\n </div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"row mb-2\">\n\t\t\t\t\t\t<label for=\"date\" class=\"col-form-label col-2\">Date</label>\n\t\t\t\t\t\t<div class=\"col-6\">\n\t\t\t\t\t\t\t<input type=\"date\" id=\"date\" class=\"form-control\">\n </div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"col-md-6\">\n\t\t\t\t\t<h3 class=\"mb-5\">Preview</h3>\n\t\t\t\t\t<p>Client: <span class=\"bg-warning rounded p-2\">Todo</span></p>\n\t\t\t\t\t<p>Amount: <span class=\"bg-warning rounded p-2\">Todo</span></p>\n\t\t\t\t\t<p>Date: <span class=\"bg-warning rounded p-2\">Todo</span></p>\n\t\t\t\t</div>\n\t\t\t</div></div>","src/app/app.component.ts": "import { Component,VERSION } from \"@angular/core\";\n\n@Component({\n selector: \"my-app\",\n templateUrl: \"./app.component.html\",\n styleUrls: []\n})\nexport class AppComponent {\n name = \"Angular \" + VERSION.major;\n}\n","src/app/app.module.ts": "import { NgModule } from '@angular/core';\nimport { browserModule } from '@angular/platform-browser';\nimport { FormsModule } from '@angular/forms';\n\nimport { AppComponent } from './app.component';\n\n@NgModule({\n imports: [ browserModule,FormsModule ],\n declarations: [ AppComponent ],\n bootstrap: [ AppComponent ]\n})\nexport class AppModule { }\n"
};
Object.entries(files).forEach(([path,contents]) => {
fs.writeFileSync(Path.join(__dirname,`./foo/${path}`),contents);
});
const config = Path.join(process.cwd(),'./foo/tsconfig.json');
const workspace = new WorkspaceSymbols(config);
console.log(workspace.getAllComponents()[0].getTemplateAst());
最后,即使存在 workspace.getAllComponents()[0].getTemplateAst()
模板,null
也会返回 app.component.html
。
我真的不需要编译整个项目 - 我只需要一种方法来获取单个 Angular HTML 文件并从中获取 AST。这可能吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。