├── .prettierignore ├── test ├── hello-world-app │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── __pages │ │ │ ├── root │ │ │ │ ├── root.component.css │ │ │ │ ├── root.entry.ts │ │ │ │ ├── root.module.ts │ │ │ │ └── root.component.html │ │ │ ├── base-forms │ │ │ │ ├── base-forms.component.css │ │ │ │ ├── base-forms.component.html │ │ │ │ ├── base-forms.entry.ts │ │ │ │ ├── base-forms.module.ts │ │ │ │ └── base-forms.component.ts │ │ │ ├── base-http │ │ │ │ ├── base-http.component.css │ │ │ │ ├── base-http.component.html │ │ │ │ ├── base-http.entry.ts │ │ │ │ ├── base-http.module.ts │ │ │ │ └── base-http.component.ts │ │ │ ├── base-tap │ │ │ │ ├── base-tap.component.css │ │ │ │ ├── base-tap.entry.ts │ │ │ │ ├── base-tap.module.ts │ │ │ │ ├── base-tap.component.html │ │ │ │ └── base-tap.component.ts │ │ │ ├── ng-content │ │ │ │ ├── ng-content.component.css │ │ │ │ ├── ng-content.component.html │ │ │ │ ├── ng-content.entry.ts │ │ │ │ ├── ng-content.component.ts │ │ │ │ └── ng-content.module.ts │ │ │ ├── base-component │ │ │ │ ├── base-component.component.css │ │ │ │ ├── base-component.component.html │ │ │ │ ├── base-component.entry.ts │ │ │ │ ├── base-component.component.ts │ │ │ │ └── base-component.module.ts │ │ │ ├── base-directive │ │ │ │ ├── base-directive.component.css │ │ │ │ ├── base-directive.component.html │ │ │ │ ├── base-directive.entry.ts │ │ │ │ ├── base-directive.component.ts │ │ │ │ ├── directive1.directive.ts │ │ │ │ └── base-directive.module.ts │ │ │ ├── self-component │ │ │ │ ├── self-component.component.css │ │ │ │ ├── self-component.component.html │ │ │ │ ├── self-component.entry.ts │ │ │ │ ├── self-component.component.ts │ │ │ │ └── self-component.module.ts │ │ │ ├── complex-structure │ │ │ │ ├── complex-structure.component.css │ │ │ │ ├── complex-structure.entry.ts │ │ │ │ ├── complex-structure.component.ts │ │ │ │ ├── complex-structure.module.ts │ │ │ │ └── complex-structure.component.html │ │ │ ├── complex-property-event │ │ │ │ ├── complex-property-event.component.css │ │ │ │ ├── complex-property-event.component.html │ │ │ │ ├── complex-property-event.entry.ts │ │ │ │ ├── complex-property-event.component.ts │ │ │ │ ├── app-dir1.directive.ts │ │ │ │ └── complex-property-event.module.ts │ │ │ ├── component-use-template │ │ │ │ ├── component-use-template.component.css │ │ │ │ ├── component-use-template.entry.ts │ │ │ │ ├── component-use-template.component.html │ │ │ │ ├── component-use-template.component.ts │ │ │ │ └── component-use-template.module.ts │ │ │ ├── custom-structural-directive │ │ │ │ ├── custom-structural-directive.component.css │ │ │ │ ├── custom-structural-directive.component.html │ │ │ │ ├── custom-structural-directive.entry.ts │ │ │ │ ├── custom-structural-directive.component.ts │ │ │ │ ├── custom-structural-directive.module.ts │ │ │ │ └── structural1.directive.ts │ │ │ ├── default-structural-directive │ │ │ │ ├── default-structural-directive.component.css │ │ │ │ ├── default-structural-directive.entry.ts │ │ │ │ ├── default-structural-directive.module.ts │ │ │ │ └── default-structural-directive.component.ts │ │ │ ├── life-time-page │ │ │ │ ├── life-time.component.html │ │ │ │ ├── life-time-page.entry.ts │ │ │ │ ├── life-time.module.ts │ │ │ │ └── life-time.component.ts │ │ │ └── life-time-page-use-component │ │ │ │ ├── life-time.component.html │ │ │ │ ├── life-time-page-use-component.entry.ts │ │ │ │ └── life-time.module.ts │ │ ├── __components │ │ │ ├── content │ │ │ │ ├── content.component.css │ │ │ │ ├── content.component.html │ │ │ │ ├── content.entry.ts │ │ │ │ ├── content.component.ts │ │ │ │ └── content.module.ts │ │ │ ├── component1 │ │ │ │ ├── component1.component.css │ │ │ │ ├── component1.component.html │ │ │ │ ├── component1.entry.ts │ │ │ │ ├── component1.module.ts │ │ │ │ └── component1.component.ts │ │ │ ├── component2 │ │ │ │ ├── component2.component.css │ │ │ │ ├── component2.component.html │ │ │ │ ├── component2.entry.ts │ │ │ │ ├── component2.component.ts │ │ │ │ └── component2.module.ts │ │ │ ├── component3 │ │ │ │ ├── component3.component.css │ │ │ │ ├── component3.component.html │ │ │ │ ├── component3.entry.ts │ │ │ │ └── component3.component.ts │ │ │ ├── content-multi │ │ │ │ ├── content-multi.component.css │ │ │ │ ├── content-multi.entry.ts │ │ │ │ ├── content-multi.component.html │ │ │ │ ├── content-multi.component.ts │ │ │ │ └── content-multi.module.ts │ │ │ ├── life-time │ │ │ │ ├── life-time.component.html │ │ │ │ └── life-time.entry.ts │ │ │ └── component-need-template │ │ │ │ ├── component-need-template.component.css │ │ │ │ ├── component-need-template.component.html │ │ │ │ ├── component-need-template.entry.ts │ │ │ │ ├── component-need-template.module.ts │ │ │ │ └── component-need-template.component.ts │ │ ├── styles.css │ │ ├── spec-component │ │ │ ├── ng-library-import │ │ │ │ ├── ng-library-import.component.html │ │ │ │ ├── ng-library-import.entry.ts │ │ │ │ ├── ng-library-import.module.ts │ │ │ │ └── ng-library-import.component.ts │ │ │ ├── tag-view-convert │ │ │ │ ├── tag-view-convert.component.html │ │ │ │ ├── tag-view-convert.entry.ts │ │ │ │ ├── tag-view-convert.component.ts │ │ │ │ └── tag-view-convert.module.ts │ │ │ ├── ng-if │ │ │ │ ├── ng-if.component.html │ │ │ │ ├── ng-if.entry.ts │ │ │ │ ├── ng-if.component.ts │ │ │ │ └── ng-if.module.ts │ │ │ ├── ng-for │ │ │ │ ├── ng-for.component.html │ │ │ │ ├── ng-for.entry.ts │ │ │ │ ├── ng-for.component.ts │ │ │ │ └── ng-for.module.ts │ │ │ ├── self-template │ │ │ │ ├── self-template.component.html │ │ │ │ ├── self-template.entry.ts │ │ │ │ ├── self-template.component.ts │ │ │ │ └── self-template.module.ts │ │ │ ├── style-class │ │ │ │ ├── style-class.component.html │ │ │ │ ├── style-class.entry.ts │ │ │ │ ├── style-class.module.ts │ │ │ │ └── style-class.component.ts │ │ │ ├── life-time │ │ │ │ ├── life-time.entry.ts │ │ │ │ ├── life-time.module.ts │ │ │ │ └── life-time.component.ts │ │ │ ├── ng-switch │ │ │ │ ├── ng-switch.entry.ts │ │ │ │ ├── ng-switch.component.html │ │ │ │ ├── ng-switch.component.ts │ │ │ │ └── ng-switch.module.ts │ │ │ ├── ng-content │ │ │ │ ├── ng-content.component.html │ │ │ │ ├── ng-content.entry.ts │ │ │ │ ├── ng-content.module.ts │ │ │ │ └── ng-content.component.ts │ │ │ └── ng-template-outlet │ │ │ │ ├── ng-template-outlet.entry.ts │ │ │ │ ├── ng-template-outlet.component.html │ │ │ │ ├── ng-template-outlet.component.ts │ │ │ │ └── ng-template-outlet.module.ts │ │ ├── spec │ │ │ ├── util │ │ │ │ ├── index.ts │ │ │ │ ├── page-info.ts │ │ │ │ ├── open-component.ts │ │ │ │ └── node-query.ts │ │ │ ├── empty │ │ │ │ ├── empty.component.ts │ │ │ │ ├── empty.entry.ts │ │ │ │ └── empty.module.ts │ │ │ ├── http-spec │ │ │ │ ├── http-spec.entry.ts │ │ │ │ ├── http.module.ts │ │ │ │ ├── http.spec.ts │ │ │ │ └── http.component.ts │ │ │ ├── ng-if-spec │ │ │ │ ├── ng-if-spec.entry.ts │ │ │ │ ├── ng-if.module.ts │ │ │ │ └── ng-if.spec.ts │ │ │ ├── ng-for-spec │ │ │ │ ├── ng-for-spec.entry.ts │ │ │ │ ├── ng-for.module.ts │ │ │ │ └── ng-for.spec.ts │ │ │ ├── life-time-spec │ │ │ │ ├── life-time-spec.entry.ts │ │ │ │ ├── life-time.module.ts │ │ │ │ └── life-time.spec.ts │ │ │ ├── ng-switch-spec │ │ │ │ ├── ng-switch-spec.entry.ts │ │ │ │ ├── ng-switch.module.ts │ │ │ │ └── ng-switch.spec.ts │ │ │ ├── ng-content-spec │ │ │ │ ├── ng-content-spec.entry.ts │ │ │ │ ├── ng-content.module.ts │ │ │ │ └── ng-content.spec.ts │ │ │ ├── style-class-spec │ │ │ │ ├── style-class-spec.entry.ts │ │ │ │ ├── style-class-spec.module.ts │ │ │ │ └── style-class-spec.spec.ts │ │ │ ├── self-template-spec │ │ │ │ ├── self-template-spec.entry.ts │ │ │ │ ├── self-template.module.ts │ │ │ │ └── self-template.spec.ts │ │ │ ├── tag-view-convert-spec │ │ │ │ ├── tag-view-convert-spec.entry.ts │ │ │ │ ├── tag-view-convert.module.ts │ │ │ │ └── tag-view-convert.spec.ts │ │ │ ├── ng-library-import-spec │ │ │ │ ├── ng-library-import-spec.entry.ts │ │ │ │ ├── ng-library-import.module.ts │ │ │ │ └── ng-library-import.spec.ts │ │ │ └── ng-template-outlet-spec │ │ │ │ ├── ng-template-outlet-spec.entry.ts │ │ │ │ ├── ng-template-outlet.module.ts │ │ │ │ └── ng-template-outlet.spec.ts │ │ ├── app.json │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.dev.json │ │ ├── main.module.ts │ │ ├── main-test.module.ts │ │ ├── main.ts │ │ ├── tsconfig.spec.json │ │ ├── typings.d.ts │ │ ├── test.ts │ │ └── project.config.json │ ├── projects │ │ └── test-library │ │ │ ├── src │ │ │ ├── other │ │ │ │ ├── other.component.css │ │ │ │ ├── other.component.html │ │ │ │ ├── other.module.ts │ │ │ │ └── other.component.ts │ │ │ ├── lib-comp1 │ │ │ │ ├── lib-comp1.component.css │ │ │ │ ├── lib-comp1.component.html │ │ │ │ ├── lib-dir1.directive.ts │ │ │ │ ├── lib-comp1.module.ts │ │ │ │ └── lib-comp1.component.ts │ │ │ ├── outside-template │ │ │ │ ├── outside-template.component.css │ │ │ │ ├── outside-template.component.html │ │ │ │ ├── outside-template.module.ts │ │ │ │ └── outside-template.component.ts │ │ │ ├── global-self-template │ │ │ │ ├── global-self-template.component.css │ │ │ │ ├── global-self-template.component.html │ │ │ │ ├── global-self-template.component.ts │ │ │ │ └── global-self-template.module.ts │ │ │ ├── lib │ │ │ │ ├── test-library.component.scss │ │ │ │ ├── test-library.service.ts │ │ │ │ ├── test-library.component.ts │ │ │ │ ├── test-library.service.spec.ts │ │ │ │ ├── test-library.module.ts │ │ │ │ ├── test-library.directive.ts │ │ │ │ └── test-library.component.spec.ts │ │ │ ├── directive │ │ │ │ ├── directive.module.ts │ │ │ │ └── input-output.directive.ts │ │ │ └── public-api.ts │ │ │ ├── ng-package.json │ │ │ ├── package.json │ │ │ ├── tsconfig.lib.prod.json │ │ │ ├── tsconfig.spec.json │ │ │ ├── tsconfig.lib.json │ │ │ └── .browserslistrc │ ├── .gitignore │ ├── tsconfig.json │ ├── .browserslistrc │ ├── tsconfig.base.json │ └── karma.conf.js ├── test-builder │ └── schema.library.json └── util │ └── file.ts ├── .npmrc ├── .prettierrc ├── deploy └── doc │ ├── .gitignore │ ├── index.md │ ├── _config.yml │ ├── _posts │ ├── 2022-02-10-测试.md │ └── 2022-02-10-无时间测试.md │ ├── _includes │ └── language-change.html │ ├── assets │ └── css │ │ └── style.scss │ ├── _layouts │ ├── redirect.html │ └── post.html │ ├── zh-Hans │ └── life-time.md │ ├── en-US │ └── life-time.md │ └── Gemfile ├── src ├── builder │ ├── karma │ │ ├── client │ │ │ ├── index.ts │ │ │ ├── platform │ │ │ │ ├── index.ts │ │ │ │ └── wx │ │ │ │ │ └── index.ts │ │ │ └── tsconfig.json │ │ └── plugin │ │ │ ├── index.ts │ │ │ ├── index.js │ │ │ ├── tsconfig.json │ │ │ └── launcher.ts │ ├── test │ │ └── fixture │ │ │ └── watch │ │ │ └── sub3 │ │ │ ├── sub3.component.html │ │ │ ├── sub3.entry.ts │ │ │ ├── sub3.component.ts │ │ │ └── sub3.module.ts │ ├── application │ │ ├── util │ │ │ ├── index.ts │ │ │ └── set-compilation-asset.ts │ │ ├── loader │ │ │ ├── type.ts │ │ │ └── component-template.loader.ts │ │ ├── const.ts │ │ ├── token.ts │ │ └── type.ts │ ├── library │ │ ├── index.ts │ │ ├── token.ts │ │ ├── const.ts │ │ ├── get-library-path.ts │ │ ├── stylesheet-processor.ts │ │ ├── type.ts │ │ ├── schema.json │ │ ├── merge-using-component-path.ts │ │ └── ng-packagr-factory.ts │ ├── platform │ │ ├── index.ts │ │ ├── type.ts │ │ ├── dd │ │ │ ├── dd.transform.ts │ │ │ └── dd-platform.ts │ │ ├── jd │ │ │ ├── jd.transform.ts │ │ │ └── jd-platform.ts │ │ ├── qq │ │ │ ├── qq.transform.ts │ │ │ └── qq-platform.ts │ │ ├── wx │ │ │ ├── wx.transform.ts │ │ │ └── wx-platform.ts │ │ ├── zjtd │ │ │ ├── zj.transform.ts │ │ │ └── zj-platform.ts │ │ ├── bd │ │ │ ├── bdzn.transform.ts │ │ │ └── bdzn-platform.ts │ │ ├── library │ │ │ ├── library.transform.ts │ │ │ └── library-platform.ts │ │ ├── platform.ts │ │ ├── template-transform-strategy │ │ │ └── transform.base.ts │ │ ├── zfb │ │ │ ├── zfb-platform.ts │ │ │ └── zfb.transform.ts │ │ ├── util │ │ │ └── type-predicate.ts │ │ └── template │ │ │ └── app-template.js │ ├── token │ │ └── component.token.ts │ ├── mini-program-compiler │ │ ├── parse-node │ │ │ ├── index.ts │ │ │ ├── type.ts │ │ │ ├── text.ts │ │ │ ├── bound-text.ts │ │ │ ├── content.ts │ │ │ ├── template.ts │ │ │ └── interface.ts │ │ ├── index.ts │ │ ├── meta-collection.ts │ │ ├── type.ts │ │ └── component-compiler.service.ts │ ├── util │ │ ├── index.ts │ │ ├── library-template-scope-name.ts │ │ ├── run-script.ts │ │ ├── literal-resolve.ts │ │ ├── load_esm.ts │ │ └── raw-updater.spec.ts │ ├── builders.json │ └── angular-internal │ │ ├── ast.type.ts │ │ └── template.ts └── library │ ├── index.ts │ ├── platform │ ├── bd │ │ ├── index.ts │ │ ├── ng-package.json │ │ └── platform-core.ts │ ├── dd │ │ ├── index.ts │ │ ├── platform-core.ts │ │ └── ng-package.json │ ├── jd │ │ ├── index.ts │ │ ├── platform-core.ts │ │ └── ng-package.json │ ├── qq │ │ ├── index.ts │ │ ├── ng-package.json │ │ └── platform-core.ts │ ├── zfb │ │ ├── index.ts │ │ └── ng-package.json │ ├── zjtd │ │ ├── index.ts │ │ ├── platform-core.ts │ │ └── ng-package.json │ ├── wx │ │ ├── index.ts │ │ └── ng-package.json │ ├── type │ │ ├── index.ts │ │ ├── internal-type.ts │ │ └── ng-package.json │ ├── http │ │ ├── index.ts │ │ ├── module.ts │ │ ├── provider.ts │ │ └── README.md │ ├── default │ │ ├── token.ts │ │ ├── ng-package.json │ │ ├── index.ts │ │ ├── mini-program.renderer.factory.ts │ │ └── component-finder.service.ts │ ├── ng-package.json │ ├── token.ts │ ├── index.ts │ ├── platform-miniprogram.ts │ └── mini-program.module.ts │ ├── declaration │ └── index.d.ts │ ├── common │ ├── .gitignore │ ├── ng-package.json │ └── http │ │ └── ng-package.json │ ├── forms │ ├── ng-package.json │ └── .gitignore │ ├── ng-package.json │ └── package.json ├── commitlint.config.js ├── .husky ├── commit-msg └── pre-commit ├── script ├── start-build-library.js ├── tsconfig.startup-jasmine.json ├── tsconfig.json ├── build-ng-package.ts ├── registry-transformer.js ├── startup-jasmine.ts └── schema-merge.ts ├── .gitignore ├── typedoc.json ├── .vscode ├── settings.json └── launch.json ├── jasmine.json ├── tsconfig.internal-schematics.json ├── tsconfig.json ├── .nycrc.json ├── readme.md ├── .eslintignore ├── tsconfig.builder.json ├── tsconfig.spec.json ├── .github └── workflows │ ├── pull_request.yml │ └── deploy.yml ├── LICENSE ├── tsconfig.doc.json └── tsconfig.library.json /.prettierignore: -------------------------------------------------------------------------------- 1 | deploy -------------------------------------------------------------------------------- /test/hello-world-app/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # registry =https://registry.npmmirror.com/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /deploy/doc/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .jekyll-cache 3 | -------------------------------------------------------------------------------- /deploy/doc/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: redirect 3 | --- -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/root/root.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/builder/karma/client/index.ts: -------------------------------------------------------------------------------- 1 | export * from './main'; 2 | -------------------------------------------------------------------------------- /src/builder/karma/client/platform/index.ts: -------------------------------------------------------------------------------- 1 | export * from './wx'; 2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content/content.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-forms/base-forms.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-http/base-http.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-tap/base-tap.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/ng-content/ng-content.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/builder/test/fixture/watch/sub3/sub3.component.html: -------------------------------------------------------------------------------- 1 |
测试
2 | -------------------------------------------------------------------------------- /src/library/index.ts: -------------------------------------------------------------------------------- 1 | export * from 'angular-miniprogram/platform'; 2 | -------------------------------------------------------------------------------- /src/library/platform/bd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /src/library/platform/dd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /src/library/platform/jd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /src/library/platform/qq/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /src/library/platform/zfb/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /src/library/platform/zjtd/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/other/other.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component1/component1.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component2/component2.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component3/component3.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-component/base-component.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/base-directive.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/self-component/self-component.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/builder/application/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './set-compilation-asset'; 2 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib-comp1/lib-comp1.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content-multi/content-multi.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/life-time/life-time.component.html: -------------------------------------------------------------------------------- 1 | 组件生命周期 2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-structure/complex-structure.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deploy/doc/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-tactile 2 | baseurl: /angular-miniprogram 3 | -------------------------------------------------------------------------------- /src/builder/library/index.ts: -------------------------------------------------------------------------------- 1 | export * from './const'; 2 | export * from './type'; 3 | -------------------------------------------------------------------------------- /src/library/platform/wx/index.ts: -------------------------------------------------------------------------------- 1 | export * from 'angular-miniprogram/platform/default' -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/complex-property-event.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/component-use-template/component-use-template.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deploy/doc/_posts/2022-02-10-测试.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "测试" 3 | layout: post 4 | --- 5 | 6 | # 内容 7 | -------------------------------------------------------------------------------- /src/library/platform/dd/platform-core.ts: -------------------------------------------------------------------------------- 1 | export * from 'angular-miniprogram/platform/default'; 2 | -------------------------------------------------------------------------------- /src/library/platform/jd/platform-core.ts: -------------------------------------------------------------------------------- 1 | export * from 'angular-miniprogram/platform/default'; 2 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/outside-template/outside-template.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | }; 4 | -------------------------------------------------------------------------------- /src/library/declaration/index.d.ts: -------------------------------------------------------------------------------- 1 | declare const ngDevMode: null | any; 2 | declare const Zone: any 3 | -------------------------------------------------------------------------------- /src/library/platform/type/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type'; 2 | export * from './internal-type'; 3 | -------------------------------------------------------------------------------- /src/library/platform/zjtd/platform-core.ts: -------------------------------------------------------------------------------- 1 | export * from 'angular-miniprogram/platform/default'; 2 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/global-self-template/global-self-template.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component-need-template/component-need-template.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component3/component3.component.html: -------------------------------------------------------------------------------- 1 |

component3 works!

2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/custom-structural-directive.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deploy/doc/_posts/2022-02-10-无时间测试.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "无时间测试" 3 | layout: post 4 | --- 5 | 6 | # 内容 7 | - 没有 -------------------------------------------------------------------------------- /src/library/common/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !ng-package.json 4 | !/http 5 | !/http/ng-package.json -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/default-structural-directive/default-structural-directive.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/other/other.component.html: -------------------------------------------------------------------------------- 1 |

other works!

2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component1/component1.component.html: -------------------------------------------------------------------------------- 1 |
显示传入input1:{{ input1 }}
2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-http/base-http.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install pretty-quick --staged 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content/content.component.html: -------------------------------------------------------------------------------- 1 |
下面将会有投影内容
2 | 3 | -------------------------------------------------------------------------------- /test/hello-world-app/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.component.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: red; 3 | } 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component2/component2.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page/life-time.component.html: -------------------------------------------------------------------------------- 1 | 页面显示 2 | -------------------------------------------------------------------------------- /src/builder/platform/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-inject-config'; 2 | export * from './type'; 3 | export * from './platform'; 4 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib-comp1/lib-comp1.component.html: -------------------------------------------------------------------------------- 1 |

lib-comp1 works!

2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-library-import/ng-library-import.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/tag-view-convert/tag-view-convert.component.html: -------------------------------------------------------------------------------- 1 |
div->view
2 | span->view 3 | -------------------------------------------------------------------------------- /script/start-build-library.js: -------------------------------------------------------------------------------- 1 | let registerTsNode = require('./registry-transformer'); 2 | registerTsNode(); 3 | require('./build-ng-package'); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page-use-component/life-time.component.html: -------------------------------------------------------------------------------- 1 | 页面显示 2 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './open-component'; 2 | export * from './node-query'; 3 | export * from './page-info'; 4 | -------------------------------------------------------------------------------- /src/builder/karma/plugin/index.ts: -------------------------------------------------------------------------------- 1 | import config from './karma'; 2 | import launcher from './launcher'; 3 | module.exports = { ...config, ...launcher }; 4 | -------------------------------------------------------------------------------- /src/library/platform/type/internal-type.ts: -------------------------------------------------------------------------------- 1 | import type { ɵLContext } from '@angular/core'; 2 | 3 | export type LView = NonNullable<ɵLContext['lView']>; 4 | -------------------------------------------------------------------------------- /src/library/platform/http/index.ts: -------------------------------------------------------------------------------- 1 | export * from './backend'; 2 | export * from './module'; 3 | export * from './provider'; 4 | export * from './response'; 5 | -------------------------------------------------------------------------------- /src/builder/token/component.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from 'static-injector'; 2 | 3 | export const COMPONENT_META = new InjectionToken('COMPONENT_META'); 4 | -------------------------------------------------------------------------------- /src/library/platform/default/token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export const PAGE_TOKEN = new InjectionToken('PAGE_TOKEN'); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-if/ng-if.component.html: -------------------------------------------------------------------------------- 1 |
true
2 |
false
3 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './component-context'; 2 | export * from './template-definition'; 3 | export * from './interface'; 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-for/ng-for.component.html: -------------------------------------------------------------------------------- 1 |
2 | {{ item }} 3 |
4 | -------------------------------------------------------------------------------- /src/library/forms/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/common/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/common/http/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/bd/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/dd/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/jd/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/qq/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/type/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/wx/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/zfb/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/zjtd/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/library/platform/default/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "lib": { 4 | "entryFile": "./index.ts" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/self-template/self-template.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mini-program-compiler.service'; 2 | export * from './meta-collection'; 3 | export * from './type'; 4 | export * from './parse-node'; 5 | -------------------------------------------------------------------------------- /src/builder/platform/type.ts: -------------------------------------------------------------------------------- 1 | export interface PlatformFileExtname { 2 | style: string; 3 | logic: string; 4 | content: string; 5 | contentTemplate: string; 6 | config?: string; 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/style-class/style-class.component.html: -------------------------------------------------------------------------------- 1 |
class-1
2 |
class-2 style-1
3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules* 2 | test-project-host-hello-world-app-* 3 | dist 4 | __test-app 5 | coverage-builder 6 | script/startup-jasmine.js 7 | .temp-git 8 | .nyc_output 9 | docs 10 | deploy/api-doc -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": ["./src/library/platform/index.ts"], 3 | "out": "deploy/api-doc", 4 | "tsconfig": "tsconfig.doc.json", 5 | "excludePrivate": true, 6 | "readme": "none" 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't ignore node_modules, this project is not meant to be installed. 2 | # Also, ~ import path in styles does only looks in the first node_modules found. 3 | # /node_modules 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "editor.codeActionsOnSave": { 4 | "source.fixAll.eslint": "explicit", 5 | "source.fixAll.tslint": "never" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/builder/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './library-template-scope-name'; 2 | export * from './literal-resolve'; 3 | export * from './load_esm'; 4 | export * from './raw-updater'; 5 | export * from './run-script'; 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-if/ng-if.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgIfComponent } from './ng-if.component'; 3 | componentRegistry(NgIfComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-for/ng-for.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgForComponent } from './ng-for.component'; 3 | componentRegistry(NgForComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/empty/empty.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-empty', 5 | template: '', 6 | }) 7 | export class EmptyComponent {} 8 | -------------------------------------------------------------------------------- /jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "src", 3 | "spec_files": ["**/*.spec.ts"], 4 | "failSpecWithNoExpectations": true, 5 | "stopSpecOnExpectationFailure": true, 6 | "stopOnSpecFailure": true, 7 | "random": false 8 | } 9 | -------------------------------------------------------------------------------- /script/tsconfig.startup-jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { "skipLibCheck": true, "outDir": "." }, 4 | "files": ["./startup-jasmine.ts"], 5 | "include": [], 6 | "exclude": [] 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/outside-template/outside-template.component.html: -------------------------------------------------------------------------------- 1 |
下面将传入一个由外部提供的模板
2 |
3 | 4 |
5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content/content.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { ContentComponent } from './content.component'; 3 | 4 | componentRegistry(ContentComponent); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/ng-content/ng-content.component.html: -------------------------------------------------------------------------------- 1 | 这个是投影内容 2 | 3 |
插槽1内容
4 |
插槽2内容
5 |
6 | -------------------------------------------------------------------------------- /script/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "esModuleInterop": true, 5 | "downlevelIteration": true 6 | }, 7 | "include": ["**/*.ts"], 8 | "exclude": [] 9 | } 10 | -------------------------------------------------------------------------------- /src/builder/util/library-template-scope-name.ts: -------------------------------------------------------------------------------- 1 | import { strings } from '@angular-devkit/core'; 2 | 3 | export function libraryTemplateScopeName(library: string) { 4 | return strings.classify(library.replace(/[@/]/g, '')); 5 | } 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/life-time/life-time.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { LifeTimeComponent } from './life-time.component'; 3 | componentRegistry(LifeTimeComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-switch/ng-switch.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgSwitchComponent } from './ng-switch.component'; 3 | componentRegistry(NgSwitchComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-content/ng-content.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 |
7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-content/ng-content.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgContentComponent } from './ng-content.component'; 3 | componentRegistry(NgContentComponent); 4 | -------------------------------------------------------------------------------- /tsconfig.internal-schematics.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "sourceMap": true 5 | }, 6 | "exclude": [], 7 | "files": [], 8 | "include": ["schematics/internal"] 9 | } 10 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/test-library", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root', 5 | }) 6 | export class TestLibraryService { 7 | constructor() {} 8 | } 9 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component1/component1.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { Component1Component } from './component1.component'; 3 | 4 | componentRegistry(Component1Component); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component2/component2.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { Component2Component } from './component2.component'; 3 | 4 | componentRegistry(Component2Component); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component3/component3.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { Component3Component } from './component3.component'; 3 | 4 | componentRegistry(Component3Component); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/life-time/life-time.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry, pageStartup } from 'angular-miniprogram'; 2 | import { LifeTimeComponent } from './life-time.component'; 3 | componentRegistry(LifeTimeComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/style-class/style-class.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { StyleClassComponent } from './style-class.component'; 3 | componentRegistry(StyleClassComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/self-component/self-component.component.html: -------------------------------------------------------------------------------- 1 | 传入模板测试 2 | 5 | -------------------------------------------------------------------------------- /src/builder/test/fixture/watch/sub3/sub3.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { Sub3Component } from './sub3.component'; 3 | import { Sub3Module } from './sub3.module'; 4 | 5 | pageStartup(Sub3Module, Sub3Component); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component-need-template/component-need-template.component.html: -------------------------------------------------------------------------------- 1 | ngTemplateOutlet插入 2 | 3 | ngIf 插入 4 |
5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content-multi/content-multi.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { ContentMultiComponent } from './content-multi.component'; 3 | 4 | componentRegistry(ContentMultiComponent); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/self-template/self-template.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { SelfTemplateComponent } from './self-template.component'; 3 | componentRegistry(SelfTemplateComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/empty/empty.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { EmptyModule } from './empty.module'; 3 | import { EmptyComponent } from './empty.component'; 4 | pageStartup(EmptyModule, EmptyComponent); 5 | -------------------------------------------------------------------------------- /src/builder/karma/plugin/index.js: -------------------------------------------------------------------------------- 1 | require('ts-node').register({ 2 | /* options */ 3 | scope: true, 4 | cwd: __dirname, 5 | }); 6 | let obj = require('./launcher'); 7 | obj = { ...obj.default, ...require('./karma').default }; 8 | module.exports = obj; 9 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-library", 3 | "version": "0.0.1", 4 | "peerDependencies": { 5 | "@angular/core": "^13.0.0" 6 | }, 7 | "dependencies": { 8 | "tslib": "^2.3.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/tag-view-convert/tag-view-convert.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { TagViewConvertComponent } from './tag-view-convert.component'; 3 | componentRegistry(TagViewConvertComponent); 4 | -------------------------------------------------------------------------------- /src/library/platform/token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export const APP_TOKEN = new InjectionToken('APP_TOKEN'); 4 | export const MINIPROGRAM_GLOBAL_TOKEN = new InjectionToken( 5 | 'MINIPROGRAM_GLOBAL_TOKEN' 6 | ); 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-library-import/ng-library-import.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgLibraryImportComponent } from './ng-library-import.component'; 3 | componentRegistry(NgLibraryImportComponent); 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": {}, 3 | "include": [], 4 | "files": [], 5 | "references": [ 6 | { "path": "./tsconfig.library.json" }, 7 | { "path": "./tsconfig.spec.json" }, 8 | { "path": "./tsconfig.builder.json" } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-template-outlet/ng-template-outlet.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { NgTemplateOutletComponent } from './ng-template-outlet.component'; 3 | componentRegistry(NgTemplateOutletComponent); 4 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/root/root.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { RootComponent } from './root.component'; 3 | import { RootModule } from './root.module'; 4 | 5 | pageStartup(RootModule, RootComponent, { useComponent: true }); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/http-spec/http-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { HttpSpecModule } from './http.module'; 3 | import { HttpSpecComponent } from './http.component'; 4 | 5 | pageStartup(HttpSpecModule, HttpSpecComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/base-directive.component.html: -------------------------------------------------------------------------------- 1 |

颜色会变,有tap反应

2 |
---测试内部属性屏蔽---
3 |

10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-tap/base-tap.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { BaseTagComponent } from './base-tap.component'; 3 | import { BaseTagModule } from './base-tap.module'; 4 | 5 | pageStartup(BaseTagModule, BaseTagComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/empty/empty.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { EmptyComponent } from './empty.component'; 4 | 5 | @NgModule({ 6 | imports: [], 7 | declarations: [EmptyComponent], 8 | }) 9 | export class EmptyModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-if-spec/ng-if-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgIfSpecModule } from './ng-if.module'; 3 | import { NgIfSPecComponent } from './ng-if.component'; 4 | 5 | pageStartup(NgIfSpecModule, NgIfSPecComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-http/base-http.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { BaseHttpComponent } from './base-http.component'; 3 | import { BaseHttpModule } from './base-http.module'; 4 | 5 | pageStartup(BaseHttpModule, BaseHttpComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/custom-structural-directive.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 使用自定义指令显示的模板->模板名:{{ name }} 4 | 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-for-spec/ng-for-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgForSpecModule } from './ng-for.module'; 3 | import { NgForSPecComponent } from './ng-for.component'; 4 | 5 | pageStartup(NgForSpecModule, NgForSPecComponent); 6 | -------------------------------------------------------------------------------- /src/builder/platform/dd/dd.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class DdTransform extends WxTransformLike { 6 | directivePrefix = 'a'; 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content-multi/content-multi.component.html: -------------------------------------------------------------------------------- 1 |
下面将会有投影内容(多)
2 |
这个是slot1插槽的
3 | 4 |
这个是slot2插槽的
5 | 6 |
---结束---
7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page/life-time-page.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { LifeTimePageModule } from './life-time.module'; 3 | import { LifeTimePage } from './life-time.component'; 4 | pageStartup(LifeTimePageModule, LifeTimePage); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [], 3 | "window": { 4 | "backgroundTextStyle": "light", 5 | "navigationBarBackgroundColor": "#fff", 6 | "navigationBarTitleText": "Weixin", 7 | "navigationBarTextStyle": "black" 8 | }, 9 | "style": "v2" 10 | } 11 | -------------------------------------------------------------------------------- /src/builder/platform/jd/jd.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class JdTransform extends WxTransformLike { 6 | directivePrefix = 'jd'; 7 | } 8 | -------------------------------------------------------------------------------- /src/builder/platform/qq/qq.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class QqTransform extends WxTransformLike { 6 | directivePrefix = 'qq'; 7 | } 8 | -------------------------------------------------------------------------------- /src/builder/platform/wx/wx.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class WxTransform extends WxTransformLike { 6 | directivePrefix = 'wx'; 7 | } 8 | -------------------------------------------------------------------------------- /src/builder/platform/zjtd/zj.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class ZjTransform extends WxTransformLike { 6 | directivePrefix = 'tt'; 7 | } 8 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-component/base-component.component.html: -------------------------------------------------------------------------------- 1 |
测试引入组件
2 | 3 |
component2中引入了component1
4 | 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-forms/base-forms.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-forms/base-forms.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { BaseFormsComponent } from './base-forms.component'; 3 | import { BaseFormsModule } from './base-forms.module'; 4 | 5 | pageStartup(BaseFormsModule, BaseFormsComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/tag-view-convert/tag-view-convert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-tag-view-convert', 5 | templateUrl: './tag-view-convert.component.html', 6 | }) 7 | export class TagViewConvertComponent {} 8 | -------------------------------------------------------------------------------- /src/builder/util/run-script.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import vm from 'vm'; 3 | 4 | export function runScript(code: string, context?: vm.Context) { 5 | try { 6 | return vm.runInNewContext(code, context); 7 | } catch (error) { 8 | console.error('运行脚本错误'); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component-need-template/component-need-template.entry.ts: -------------------------------------------------------------------------------- 1 | import { componentRegistry } from 'angular-miniprogram'; 2 | import { ComponentNeedTemplateComponent } from './component-need-template.component'; 3 | 4 | componentRegistry(ComponentNeedTemplateComponent); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/ng-content/ng-content.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | 3 | import { NgContentComponent } from './ng-content.component'; 4 | import { NgContentModule } from './ng-content.module'; 5 | 6 | pageStartup(NgContentModule, NgContentComponent); 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/life-time-spec/life-time-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { LifeTimeSpecModule } from './life-time.module'; 3 | import { LifeTimeSPecComponent } from './life-time.component'; 4 | 5 | pageStartup(LifeTimeSpecModule, LifeTimeSPecComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-switch-spec/ng-switch-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgSwitchSpecModule } from './ng-switch.module'; 3 | import { NgSwitchSPecComponent } from './ng-switch.component'; 4 | 5 | pageStartup(NgSwitchSpecModule, NgSwitchSPecComponent); 6 | -------------------------------------------------------------------------------- /src/library/platform/default/index.ts: -------------------------------------------------------------------------------- 1 | export * from './platform-core'; 2 | export * from './token'; 3 | export * from './mini-program.renderer'; 4 | export * from './mini-program.renderer.factory'; 5 | export * from './component-finder.service'; 6 | export { propertyChange } from './component-template-hook.factory'; 7 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/global-self-template/global-self-template.component.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | library内模板 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/complex-property-event.component.html: -------------------------------------------------------------------------------- 1 |
指令事件
2 |
内置组件+内置指令+library指令
3 | 4 |
library组件+内置指令+library指令
5 | 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-content-spec/ng-content-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgContentSpecModule } from './ng-content.module'; 3 | import { NgContentSpecComponent } from './ng-content.component'; 4 | pageStartup(NgContentSpecModule, NgContentSpecComponent); 5 | -------------------------------------------------------------------------------- /src/builder/test/fixture/watch/sub3/sub3.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-sub3', 5 | templateUrl: './sub3.component.html', 6 | }) 7 | export class Sub3Component implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/other/other.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { OtherComponent } from './other.component'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [OtherComponent], 7 | exports: [OtherComponent], 8 | }) 9 | export class OtherModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-component/base-component.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { BaseComponentComponent } from './base-component.component'; 3 | import { BaseComponentModule } from './base-component.module'; 4 | 5 | pageStartup(BaseComponentModule, BaseComponentComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/base-directive.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { BaseDirectiveComponent } from './base-directive.component'; 3 | import { BaseDirectiveModule } from './base-directive.module'; 4 | 5 | pageStartup(BaseDirectiveModule, BaseDirectiveComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/self-component/self-component.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { SelfComponentComponent } from './self-component.component'; 3 | import { SelfComponentModule } from './self-component.module'; 4 | 5 | pageStartup(SelfComponentModule, SelfComponentComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-switch/ng-switch.component.html: -------------------------------------------------------------------------------- 1 | 2 |
case1
3 |
case2
4 |
default
5 |
6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/style-class-spec/style-class-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { StyleClassSpecModule } from './style-class-spec.module'; 3 | import { StyleClassSpecComponent } from './style-class-spec.component'; 4 | pageStartup(StyleClassSpecModule, StyleClassSpecComponent); 5 | -------------------------------------------------------------------------------- /src/builder/application/loader/type.ts: -------------------------------------------------------------------------------- 1 | import { MetaCollection } from '../../mini-program-compiler'; 2 | import type { BuildPlatform } from '../../platform/platform'; 3 | 4 | export interface ComponentTemplateLoaderContext { 5 | buildPlatform: BuildPlatform; 6 | otherMetaGroupPromise: Promise>; 7 | } 8 | -------------------------------------------------------------------------------- /src/builder/util/literal-resolve.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { runScript } from './run-script'; 3 | 4 | export function literalResolve>( 5 | content: string, 6 | options?: T 7 | ) { 8 | return runScript(`(()=>{return ${content}})()`, options); 9 | } 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-if/ng-if.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-if', 5 | templateUrl: './ng-if.component.html', 6 | }) 7 | export class NgIfComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page-use-component/life-time-page-use-component.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { LifeTimePageModule } from './life-time.module'; 3 | import { LifeTimePage } from './life-time.component'; 4 | pageStartup(LifeTimePageModule, LifeTimePage, { useComponent: true }); 5 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/life-time/life-time.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { LifeTimeComponent } from './life-time.component'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [LifeTimeComponent], 7 | exports: [LifeTimeComponent], 8 | }) 9 | export class LifeTimeModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/self-template-spec/self-template-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { SelfTemplateSpecModule } from './self-template.module'; 3 | import { SelfTemplateSPecComponent } from './self-template.component'; 4 | 5 | pageStartup(SelfTemplateSpecModule, SelfTemplateSPecComponent); 6 | -------------------------------------------------------------------------------- /src/builder/application/const.ts: -------------------------------------------------------------------------------- 1 | export const ExportMiniProgramAssetsPluginSymbol = Symbol.for( 2 | 'ExportMiniProgramAssetsPluginSymbol' 3 | ); 4 | export const LibrarySymbol = Symbol.for('LibrarySymbol'); 5 | export const InjectorSymbol = Symbol.for('InjectorSymbol'); 6 | export const TemplateScopeSymbol = Symbol.for('TemplateScopeSymbol'); 7 | -------------------------------------------------------------------------------- /src/builder/test/fixture/watch/sub3/sub3.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { Sub3Component } from './sub3.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [Sub3Component], 8 | }) 9 | export class Sub3Module {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "compilationMode": "full" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/root/root.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { RootComponent } from './root.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [RootComponent], 8 | }) 9 | export class RootModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-content/ng-content.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { NgContentComponent } from './ng-content.component'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [NgContentComponent], 7 | exports: [NgContentComponent], 8 | }) 9 | export class NgContentModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": {}, 3 | "include": [], 4 | "files": [], 5 | "references": [ 6 | { 7 | "path": "./src/tsconfig.app.json" 8 | }, 9 | { 10 | "path": "./src/tsconfig.spec.json" 11 | }, 12 | { 13 | "path": "./src/tsconfig.dev.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-structure/complex-structure.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | 3 | import { ComplexStructureComponent } from './complex-structure.component'; 4 | import { ComplexStructureModule } from './complex-structure.module'; 5 | 6 | pageStartup(ComplexStructureModule, ComplexStructureComponent); 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | export const environment = { 9 | production: true, 10 | }; 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/style-class/style-class.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { StyleClassComponent } from './style-class.component'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [StyleClassComponent], 7 | exports: [StyleClassComponent], 8 | }) 9 | export class StyleClassModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/tag-view-convert-spec/tag-view-convert-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { TagViewConvertSpecModule } from './tag-view-convert.module'; 3 | import { TagViewConvertSpecComponent } from './tag-view-convert.component'; 4 | pageStartup(TagViewConvertSpecModule, TagViewConvertSpecComponent); 5 | -------------------------------------------------------------------------------- /deploy/doc/_includes/language-change.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 12 |
13 | -------------------------------------------------------------------------------- /src/library/platform/http/module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { withInterceptorsFromDi } from 'angular-miniprogram/common/http'; 3 | import { provideHttpClient } from './provider'; 4 | 5 | @NgModule({ 6 | providers: [ 7 | provideHttpClient(withInterceptorsFromDi()) 8 | ] 9 | }) 10 | export class HttpClientModule { } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-content/ng-content.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-content', 5 | templateUrl: './ng-content.component.html', 6 | }) 7 | export class NgContentComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [], 6 | "skipLibCheck": true, 7 | "target": "ES2022" 8 | }, 9 | "files": ["main.ts"], 10 | "include": ["**/*.d.ts", "pages/**/*.entry.ts", "components/**/*.entry.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /.nycrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extension": [".ts"], 3 | "exclude": [ 4 | "**/*.d.ts", 5 | "**/*.js", 6 | "**/*.spec.ts", 7 | "startup-jasmine.js", 8 | "test/**/*", 9 | "src/builder/angular-internal/**/*" 10 | ], 11 | "reporter": ["html", "text", "json-summary", "json"], 12 | "all": false, 13 | "report-dir": "./docs/coverage" 14 | } 15 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |

angular-miniprogram - 使用 Angular 开发小程序

2 | 3 |

尽可能使用 Angular 已有生态,降低跨平台时所需成本

4 | 5 | - 文档 [https://wszgrcy.github.io/angular-miniprogram/](https://wszgrcy.github.io/angular-miniprogram/) 6 | - document [https://wszgrcy.github.io/angular-miniprogram/en-US/](https://wszgrcy.github.io/angular-miniprogram/en-US/) 7 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/style-class/style-class.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-style-class', 5 | templateUrl: './style-class.component.html', 6 | }) 7 | export class StyleClassComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-template-outlet/ng-template-outlet.component.html: -------------------------------------------------------------------------------- 1 | 2 |
template-content-1
3 |
4 | 5 |
template-content-1
6 |
7 | 8 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-library-import-spec/ng-library-import-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgLibraryImportSpecModule } from './ng-library-import.module'; 3 | import { NgLibraryImportSPecComponent } from './ng-library-import.component'; 4 | 5 | pageStartup(NgLibraryImportSpecModule, NgLibraryImportSPecComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-for/ng-for.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-for', 5 | templateUrl: './ng-for.component.html', 6 | }) 7 | export class NgForComponent implements OnInit { 8 | @Input() list: string[]; 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-switch/ng-switch.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-switch', 5 | templateUrl: './ng-switch.component.html', 6 | }) 7 | export class NgSwitchComponent implements OnInit { 8 | case1 = 'case1'; 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [], 6 | "skipLibCheck": true 7 | }, 8 | "files": ["main.ts"], 9 | "include": [ 10 | "**/*.d.ts", 11 | "__pages/**/*.entry.ts", 12 | "__components/**/*.entry.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-template-outlet-spec/ng-template-outlet-spec.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { NgTemplateOutletSpecModule } from './ng-template-outlet.module'; 3 | import { NgTemplateOutletSPecComponent } from './ng-template-outlet.component'; 4 | 5 | pageStartup(NgTemplateOutletSpecModule, NgTemplateOutletSPecComponent); 6 | -------------------------------------------------------------------------------- /src/builder/library/token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from 'static-injector'; 2 | 3 | export const RESOLVED_DATA_GROUP_TOKEN = new InjectionToken( 4 | 'RESOLVED_DATA_GROUP_TOKEN' 5 | ); 6 | export const ENTRY_POINT_TOKEN = new InjectionToken( 7 | 'ENTRY_POINT_TOKEN' 8 | ); 9 | 10 | export const ENTRY_FILE_TOKEN = new InjectionToken('ENTRY_FILE_TOKEN'); 11 | -------------------------------------------------------------------------------- /src/library/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist", 4 | "deleteDestPath": true, 5 | "allowedNonPeerDependencies": [ 6 | "cyia-code-util", 7 | "webpack-bootstrap-assets-plugin", 8 | "static-injector" 9 | ], 10 | "lib": { 11 | "entryFile": "./platform/index.ts" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/directive/directive.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { InputOutputDirective } from './input-output.directive'; 3 | 4 | @NgModule({ 5 | declarations: [InputOutputDirective], 6 | imports: [], 7 | exports: [InputOutputDirective], 8 | providers: [], 9 | }) 10 | export class DirectiveModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/spec", 6 | "types": ["jasmine"] 7 | }, 8 | "files": ["src/test.ts"], 9 | "include": ["**/*.spec.ts", "**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/complex-property-event.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { ComplexPropertyEventComponent } from './complex-property-event.component'; 3 | import { ComplexPropertyEventModule } from './complex-property-event.module'; 4 | 5 | pageStartup(ComplexPropertyEventModule, ComplexPropertyEventComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/component-use-template/component-use-template.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | import { ComponentUseTemplateComponent } from './component-use-template.component'; 3 | import { ComponentUseTemplateModule } from './component-use-template.module'; 4 | 5 | pageStartup(ComponentUseTemplateModule, ComponentUseTemplateComponent); 6 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/tag-view-convert/tag-view-convert.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { TagViewConvertComponent } from './tag-view-convert.component'; 3 | 4 | @NgModule({ 5 | imports: [], 6 | declarations: [TagViewConvertComponent], 7 | exports: [TagViewConvertComponent], 8 | }) 9 | export class TagViewConvertModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content/content.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-content', 5 | templateUrl: './content.component.html', 6 | styleUrls: ['./content.component.css'], 7 | }) 8 | export class ContentComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-if/ng-if.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { NgIfComponent } from './ng-if.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [NgIfComponent], 8 | exports: [NgIfComponent], 9 | }) 10 | export class NgIfModule {} 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /tests/ 2 | .yarn/ 3 | dist/ 4 | node_modules/ 5 | test/test-project-host-hello-world-app-* 6 | test/hello-world-app 7 | jest.builder.config.ts 8 | build-ng-package.ts 9 | schema-merge.ts 10 | test/util 11 | commitlint.config.js 12 | script 13 | **/fixture 14 | *.xspec.ts 15 | src/library/common 16 | src/libary/forms 17 | test 18 | src/library/platform/http 19 | deploy 20 | docs -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-for/ng-for.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { NgForComponent } from './ng-for.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [NgForComponent], 8 | exports: [NgForComponent], 9 | }) 10 | export class NgForModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-template-outlet/ng-template-outlet.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-template-outlet', 5 | templateUrl: './ng-template-outlet.component.html', 6 | }) 7 | export class NgTemplateOutletComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /deploy/doc/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import '{{ site.theme }}'; 5 | 6 | .action-line { 7 | display: flex; 8 | align-items: center; 9 | justify-content: end; 10 | } 11 | 12 | .flex-1 { 13 | flex: 1 1 0%; 14 | } 15 | .flex { 16 | display: flex; 17 | } 18 | 19 | .text-center { 20 | text-align: center; 21 | } 22 | 23 | blockquote p{ 24 | font-size: 0.8em; 25 | } -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/ng-content/ng-content.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-ng-content', 5 | templateUrl: './ng-content.component.html', 6 | styleUrls: ['./ng-content.component.css'], 7 | }) 8 | export class NgContentComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content/content.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ContentComponent } from './content.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [ContentComponent], 8 | exports: [ContentComponent], 9 | }) 10 | export class ContentModule {} 11 | -------------------------------------------------------------------------------- /src/builder/library/const.ts: -------------------------------------------------------------------------------- 1 | export const LIBRARY_OUTPUT_ROOTDIR = 'library'; 2 | export const LIBRARY_DIRECTIVE_LISTENERS_SUFFIX = 'Listeners'; 3 | export const LIBRARY_DIRECTIVE_PROPERTIES_SUFFIX = 'Properties'; 4 | export const LIBRARY_COMPONENT_OUTPUT_PATH_SUFFIX = 'OutputPath'; 5 | export const LIBRARY_COMPONENT_METADATA_SUFFIX = 'ExtraData'; 6 | export const GLOBAL_TEMPLATE_SUFFIX = 'Global_Template'; 7 | -------------------------------------------------------------------------------- /src/builder/library/get-library-path.ts: -------------------------------------------------------------------------------- 1 | import { join, normalize } from '@angular-devkit/core'; 2 | import { camelize, dasherize } from '@angular-devkit/core/src/utils/strings'; 3 | 4 | export function getComponentOutputPath(entry: string, className: string) { 5 | return join( 6 | normalize(entry), 7 | dasherize(camelize(className)), 8 | dasherize(camelize(className)) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-if-spec/ng-if.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { NgIfModule } from '../../spec-component/ng-if/ng-if.module'; 4 | import { NgIfSPecComponent } from './ng-if.component'; 5 | @NgModule({ 6 | imports: [NgIfModule], 7 | declarations: [NgIfSPecComponent], 8 | exports: [NgIfSPecComponent], 9 | }) 10 | export class NgIfSpecModule {} 11 | -------------------------------------------------------------------------------- /script/build-ng-package.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import { ngPackagrFactory } from '../src/builder/library/ng-packagr-factory'; 3 | async function main() { 4 | let packagr = await ngPackagrFactory( 5 | path.resolve(process.cwd(), './src/library/ng-package.json'), 6 | path.resolve(process.cwd(), './tsconfig.library.json') 7 | ); 8 | 9 | await packagr.build(); 10 | } 11 | main(); 12 | -------------------------------------------------------------------------------- /src/builder/platform/bd/bdzn.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 3 | 4 | @Injectable() 5 | export class BdZnTransform extends WxTransformLike { 6 | override directivePrefix = 's'; 7 | override seq = '-'; 8 | override templateInterpolation: [string, string] = ['{{{', '}}}']; 9 | } 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-switch/ng-switch.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { NgSwitchComponent } from './ng-switch.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [NgSwitchComponent], 8 | exports: [NgSwitchComponent], 9 | }) 10 | export class NgSwitchModule {} 11 | -------------------------------------------------------------------------------- /src/builder/application/util/set-compilation-asset.ts: -------------------------------------------------------------------------------- 1 | import * as webpack from 'webpack'; 2 | 3 | export function setCompilationAsset( 4 | compilation: webpack.Compilation, 5 | key: string, 6 | content: webpack.sources.Source 7 | ) { 8 | if (compilation.getAsset(key)) { 9 | compilation.updateAsset(key, content, {}); 10 | } else { 11 | compilation.emitAsset(key, content, {}); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-tap/base-tap.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { BaseTagComponent } from './base-tap.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [BaseTagComponent], 8 | schemas: [NO_ERRORS_SCHEMA], 9 | }) 10 | export class BaseTagModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-content-spec/ng-content.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { NgContentModule } from '../../spec-component/ng-content/ng-content.module'; 3 | import { NgContentSpecComponent } from './ng-content.component'; 4 | 5 | @NgModule({ 6 | imports: [NgContentModule], 7 | declarations: [NgContentSpecComponent], 8 | }) 9 | export class NgContentSpecModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-for-spec/ng-for.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { NgForModule } from '../../spec-component/ng-for/ng-for.module'; 4 | import { NgForSPecComponent } from './ng-for.component'; 5 | @NgModule({ 6 | imports: [NgForModule], 7 | declarations: [NgForSPecComponent], 8 | exports: [NgForSPecComponent], 9 | }) 10 | export class NgForSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component1/component1.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { Component1Component } from './component1.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [Component1Component], 8 | exports: [Component1Component], 9 | }) 10 | export class Component1Module {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content-multi/content-multi.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-content-multi', 5 | templateUrl: './content-multi.component.html', 6 | styleUrls: ['./content-multi.component.css'], 7 | }) 8 | export class ContentMultiComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/self-component/self-component.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-self-component', 5 | templateUrl: './self-component.component.html', 6 | styleUrls: ['./self-component.component.css'], 7 | }) 8 | export class SelfComponentComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/directive/input-output.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, EventEmitter, Input, Output } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[libInputOutput]', 5 | }) 6 | export class InputOutputDirective { 7 | @Input() input1: string; 8 | @Input() input2: number; 9 | @Output() output1 = new EventEmitter(); 10 | @Output() output2 = new EventEmitter(); 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/main.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { DoBootstrap } from '@angular/core'; 3 | import { MiniProgramModule } from 'angular-miniprogram'; 4 | @NgModule({ 5 | declarations: [], 6 | imports: [MiniProgramModule], 7 | exports: [], 8 | providers: [], 9 | }) 10 | export class MainModule implements DoBootstrap { 11 | constructor() {} 12 | ngDoBootstrap() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/http-spec/http.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { HttpClientModule } from 'angular-miniprogram'; 3 | import { CommonModule } from 'angular-miniprogram/common'; 4 | import { HttpSpecComponent } from './http.component'; 5 | @NgModule({ 6 | imports: [CommonModule, HttpClientModule], 7 | declarations: [HttpSpecComponent], 8 | }) 9 | export class HttpSpecModule {} 10 | -------------------------------------------------------------------------------- /deploy/doc/_layouts/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/main-test.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { DoBootstrap } from '@angular/core'; 3 | import { MiniProgramModule } from 'angular-miniprogram'; 4 | @NgModule({ 5 | declarations: [], 6 | imports: [MiniProgramModule], 7 | exports: [], 8 | providers: [], 9 | }) 10 | export class MainTestModule implements DoBootstrap { 11 | constructor() {} 12 | ngDoBootstrap() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/self-template/self-template.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit, TemplateRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-self-template', 5 | templateUrl: './self-template.component.html', 6 | }) 7 | export class SelfTemplateComponent implements OnInit { 8 | @Input() template1: TemplateRef; 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/other/other.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-other', 5 | templateUrl: './other.component.html', 6 | styleUrls: ['./other.component.css'], 7 | }) 8 | export class OtherComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | click() { 13 | console.log('other被点击'); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component1/component1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component1', 5 | templateUrl: './component1.component.html', 6 | styleUrls: ['./component1.component.css'], 7 | }) 8 | export class Component1Component implements OnInit { 9 | @Input() input1 = ''; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component2/component2.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component2', 5 | templateUrl: './component2.component.html', 6 | styleUrls: ['./component2.component.css'], 7 | }) 8 | export class Component2Component implements OnInit { 9 | @Input() cp2Input1 = ''; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/content-multi/content-multi.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ContentMultiComponent } from './content-multi.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [ContentMultiComponent], 8 | exports: [ContentMultiComponent], 9 | }) 10 | export class ContentMultiModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/component-use-template/component-use-template.component.html: -------------------------------------------------------------------------------- 1 | 2 | 这个是外部定义模板 引入组件 5 | 6 | 9 |
下面的是调用library内组件的其他组件模板
10 | 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/self-template/self-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { SelfTemplateComponent } from './self-template.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [SelfTemplateComponent], 8 | exports: [SelfTemplateComponent], 9 | }) 10 | export class SelfTemplateModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/style-class-spec/style-class-spec.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { StyleClassModule } from 'src/spec-component/style-class/style-class.module'; 3 | 4 | import { StyleClassSpecComponent } from './style-class-spec.component'; 5 | 6 | @NgModule({ 7 | imports: [StyleClassModule], 8 | declarations: [StyleClassSpecComponent], 9 | }) 10 | export class StyleClassSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/base-directive.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-base-directive', 5 | templateUrl: './base-directive.component.html', 6 | styleUrls: ['./base-directive.component.css'], 7 | }) 8 | export class BaseDirectiveComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | 13 | event1() {} 14 | } 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-http/base-http.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { HttpClientModule } from 'angular-miniprogram'; 3 | import { CommonModule } from 'angular-miniprogram/common'; 4 | import { BaseHttpComponent } from './base-http.component'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, HttpClientModule], 8 | declarations: [BaseHttpComponent], 9 | }) 10 | export class BaseHttpModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-library-import/ng-library-import.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { NgLibraryImportComponent } from './ng-library-import.component'; 3 | import { LibComp1Module } from 'test-library'; 4 | @NgModule({ 5 | imports: [LibComp1Module], 6 | declarations: [NgLibraryImportComponent], 7 | exports: [NgLibraryImportComponent], 8 | }) 9 | export class NgLibraryImportModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/life-time-spec/life-time.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { LifeTimeModule } from '../../spec-component/life-time/life-time.module'; 4 | import { LifeTimeSPecComponent } from './life-time.component'; 5 | @NgModule({ 6 | imports: [LifeTimeModule], 7 | declarations: [LifeTimeSPecComponent], 8 | exports: [LifeTimeSPecComponent], 9 | }) 10 | export class LifeTimeSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-switch-spec/ng-switch.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { NgSwitchModule } from '../../spec-component/ng-switch/ng-switch.module'; 4 | import { NgSwitchSPecComponent } from './ng-switch.component'; 5 | @NgModule({ 6 | imports: [NgSwitchModule], 7 | declarations: [NgSwitchSPecComponent], 8 | exports: [NgSwitchSPecComponent], 9 | }) 10 | export class NgSwitchSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-component/base-component.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-base-component', 5 | templateUrl: './base-component.component.html', 6 | styleUrls: ['./base-component.component.css'], 7 | }) 8 | export class BaseComponentComponent implements OnInit { 9 | componentInput1 = '由父组件传入'; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/directive1.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostBinding, HostListener } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appDirective1]', 5 | }) 6 | export class Directive1Directive { 7 | @HostBinding('style.color') color = 'red'; 8 | @HostListener('tap', ['$event']) tap(event) { 9 | console.log('tap事件', event); 10 | this.color = 'green'; 11 | } 12 | constructor() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/custom-structural-directive.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | 3 | import { CustomStructuralDirectiveComponent } from './custom-structural-directive.component'; 4 | import { CustomStructuralDirectiveModule } from './custom-structural-directive.module'; 5 | 6 | pageStartup( 7 | CustomStructuralDirectiveModule, 8 | CustomStructuralDirectiveComponent 9 | ); 10 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "outDir": "../../out-tsc/lib", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "inlineSources": true, 9 | "types": [], 10 | "target": "es2022" 11 | }, 12 | "exclude": ["src/test.ts", "**/*.spec.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/complex-property-event.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-complex-property-event', 5 | templateUrl: './complex-property-event.component.html', 6 | styleUrls: ['./complex-property-event.component.css'], 7 | }) 8 | export class ComplexPropertyEventComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-structure/complex-structure.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-complex-structure', 5 | templateUrl: './complex-structure.component.html', 6 | styleUrls: ['./complex-structure.component.css'], 7 | }) 8 | export class ComplexStructureComponent implements OnInit { 9 | list = [1, 2, 3]; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/component-use-template/component-use-template.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component-use-template', 5 | templateUrl: './component-use-template.component.html', 6 | styleUrls: ['./component-use-template.component.css'], 7 | }) 8 | export class ComponentUseTemplateComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/default-structural-directive/default-structural-directive.entry.ts: -------------------------------------------------------------------------------- 1 | import { pageStartup } from 'angular-miniprogram'; 2 | 3 | import { DefaultStructuralDirectiveComponent } from './default-structural-directive.component'; 4 | import { DefaultStructuralDirectiveModule } from './default-structural-directive.module'; 5 | 6 | pageStartup( 7 | DefaultStructuralDirectiveModule, 8 | DefaultStructuralDirectiveComponent 9 | ); 10 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/global-self-template/global-self-template.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-global-self-template', 5 | templateUrl: './global-self-template.component.html', 6 | styleUrls: ['./global-self-template.component.css'], 7 | }) 8 | export class GlobalSelfTemplateComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/outside-template/outside-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { OutsideTemplateComponent } from './outside-template.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [OutsideTemplateComponent], 8 | exports: [OutsideTemplateComponent], 9 | }) 10 | export class OutsideTemplateModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-template-outlet/ng-template-outlet.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { NgTemplateOutletComponent } from './ng-template-outlet.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [NgTemplateOutletComponent], 8 | exports: [NgTemplateOutletComponent], 9 | }) 10 | export class NgTemplateOutletModule {} 11 | -------------------------------------------------------------------------------- /src/builder/karma/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../../../../dist/karma/client", 4 | "strict": false, 5 | "strictNullChecks": false, 6 | "allowUnreachableCode": true, 7 | "noUnusedParameters": false, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "target": "ES2021", 11 | "module": "CommonJS", 12 | "lib": ["ES2021"], 13 | "skipLibCheck": true 14 | }, 15 | "files": ["index.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page/life-time.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { LifeTimeComponent } from '../../__components/life-time/life-time.component'; 4 | import { LifeTimePage } from './life-time.component'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, LifeTimeComponent], 8 | declarations: [LifeTimePage], 9 | }) 10 | export class LifeTimePageModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | 3 | import { MainModule } from './main.module'; 4 | import { environment } from './environments/environment'; 5 | import { platformMiniProgram } from 'angular-miniprogram'; 6 | import 'zone.js'; 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformMiniProgram() 12 | .bootstrapModule(MainModule) 13 | .then((e) => { 14 | console.log(e); 15 | }); 16 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, HostBinding, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'lib-test-library', 5 | template: ``, 6 | styleUrls: ['./test-library.component.scss'], 7 | }) 8 | export class TestLibraryComponent implements OnInit { 9 | @Input() input1; 10 | @HostBinding('property1') property1; 11 | 12 | constructor() {} 13 | 14 | ngOnInit(): void {} 15 | } 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/app-dir1.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostListener } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appDir1]', 5 | }) 6 | export class AppDir1Directive { 7 | @HostListener('tap', ['$event']) tap1(event) { 8 | console.log('内置指令的tap事件', event); 9 | } 10 | @HostListener('bindtap', ['$event']) tap2(event) { 11 | console.log('内置指令的(bind)tap事件', event); 12 | } 13 | constructor() {} 14 | } 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/default-structural-directive/default-structural-directive.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { DefaultStructuralDirectiveComponent } from './default-structural-directive.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [DefaultStructuralDirectiveComponent], 8 | }) 9 | export class DefaultStructuralDirectiveModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-library-import-spec/ng-library-import.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { NgLibraryImportSPecComponent } from './ng-library-import.component'; 4 | import { NgLibraryImportModule } from '../../spec-component/ng-library-import/ng-library-import.module'; 5 | @NgModule({ 6 | imports: [NgLibraryImportModule], 7 | declarations: [NgLibraryImportSPecComponent], 8 | }) 9 | export class NgLibraryImportSpecModule {} 10 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/tag-view-convert-spec/tag-view-convert.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { TagViewConvertModule } from '../../spec-component/tag-view-convert/tag-view-convert.module'; 3 | 4 | import { TagViewConvertSpecComponent } from './tag-view-convert.component'; 5 | 6 | @NgModule({ 7 | imports: [TagViewConvertModule], 8 | declarations: [TagViewConvertSpecComponent], 9 | }) 10 | export class TagViewConvertSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page-use-component/life-time.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { LifeTimeComponent } from '../../__components/life-time/life-time.component'; 4 | import { LifeTimePage } from './life-time.component'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, LifeTimeComponent], 8 | declarations: [LifeTimePage], 9 | }) 10 | export class LifeTimePageModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/self-template-spec/self-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { SelfTemplateModule } from '../../spec-component/self-template/self-template.module'; 4 | import { SelfTemplateSPecComponent } from './self-template.component'; 5 | @NgModule({ 6 | imports: [SelfTemplateModule], 7 | declarations: [SelfTemplateSPecComponent], 8 | exports: [SelfTemplateSPecComponent], 9 | }) 10 | export class SelfTemplateSpecModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib-comp1/lib-dir1.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostListener } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appLibDir1]', 5 | }) 6 | export class LibDir1Directive { 7 | @HostListener('tap', ['$event']) tap1(event) { 8 | console.log('library指令的tap事件', event); 9 | } 10 | @HostListener('bindtap', ['$event']) tap2(event) { 11 | console.log('library指令的(bind)tap事件', event); 12 | } 13 | constructor() {} 14 | } 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-forms/base-forms.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { BaseFormsComponent } from './base-forms.component'; 4 | import { FormsModule } from 'angular-miniprogram/forms'; 5 | @NgModule({ 6 | imports: [CommonModule, FormsModule], 7 | declarations: [BaseFormsComponent], 8 | schemas: [NO_ERRORS_SCHEMA], 9 | }) 10 | export class BaseFormsModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/custom-structural-directive.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-custom-structural-directive', 5 | templateUrl: './custom-structural-directive.component.html', 6 | styleUrls: ['./custom-structural-directive.component.css'], 7 | }) 8 | export class CustomStructuralDirectiveComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.builder.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "noImplicitThis": true, 5 | "outDir": "./dist/builder", 6 | "declaration": false, 7 | "strict": true 8 | }, 9 | "include": ["src/builder"], 10 | "exclude": [ 11 | "./**/fixture", 12 | "./**/*.template.ts", 13 | "./**/*.d.ts", 14 | "**/*.spec.ts", 15 | "**/*.xspec.ts", 16 | "**/*/karma/plugin/**/*", 17 | "**/*/karma/client/**/*" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /script/registry-transformer.js: -------------------------------------------------------------------------------- 1 | let { register } = require('ts-node'); 2 | let path = require('path'); 3 | let { createTransformer } = require('static-injector/transform'); 4 | module.exports = function registerTsNode() { 5 | register({ 6 | project: path.resolve(__dirname, '../tsconfig.spec.json'), 7 | transformers: (program) => { 8 | const transformer = createTransformer(program); 9 | return { 10 | before: [transformer], 11 | }; 12 | }, 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /src/library/forms/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !/src 4 | !/src/directives 5 | !/src/directives/default_value_accessor.ts 6 | !/src/directives/checkbox_value_accessor.ts 7 | !/src/directives/radio_control_value_accessor.ts 8 | !/src/directives.ts 9 | !/readme.md 10 | !/src/directives/picker_view_value_accessor.ts 11 | !/src/directives/switch_value_accessor.ts 12 | !/src/directives/slider_value_accessor.ts 13 | !/src/directives/picker_value_accessor.ts 14 | !/src/forms.ts 15 | !/ng-package.json 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component-need-template/component-need-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ComponentNeedTemplateComponent } from './component-need-template.component'; 4 | 5 | @NgModule({ 6 | imports: [CommonModule], 7 | declarations: [ComponentNeedTemplateComponent], 8 | exports: [ComponentNeedTemplateComponent], 9 | }) 10 | export class ComponentNeedTemplateModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/outside-template/outside-template.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit, TemplateRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-outside-template', 5 | templateUrl: './outside-template.component.html', 6 | styleUrls: ['./outside-template.component.css'], 7 | }) 8 | export class OutsideTemplateComponent implements OnInit { 9 | @Input() template: TemplateRef; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component2/component2.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { Component2Component } from './component2.component'; 4 | import { Component1Module } from '../component1/component1.module'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, Component1Module], 8 | declarations: [Component2Component], 9 | exports: [Component2Component], 10 | }) 11 | export class Component2Module {} 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-structure/complex-structure.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ComplexStructureComponent } from './complex-structure.component'; 4 | import { ContentModule } from '../../__components/content/content.module'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, ContentModule], 8 | declarations: [ComplexStructureComponent], 9 | }) 10 | export class ComplexStructureModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib-comp1/lib-comp1.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { LibComp1Component } from './lib-comp1.component'; 4 | import { LibDir1Directive } from './lib-dir1.directive'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule], 8 | declarations: [LibComp1Component, LibDir1Directive], 9 | exports: [LibComp1Component, LibDir1Directive], 10 | }) 11 | export class LibComp1Module {} 12 | -------------------------------------------------------------------------------- /src/builder/application/token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from 'static-injector'; 2 | 3 | export const TS_CONFIG_TOKEN = new InjectionToken('TS_CONFIG_TOKEN'); 4 | export const PAGE_PATTERN_TOKEN = new InjectionToken('PAGE_PATTERN_TOKEN'); 5 | export const OLD_BUILDER = new InjectionToken('OLD_BUILDER'); 6 | export const TS_SYSTEM = new InjectionToken('TS_SYSTEM'); 7 | export const WEBPACK_COMPILATION = new InjectionToken('WEBPACK_COMPILATION'); 8 | export const WEBPACK_COMPILER = new InjectionToken('WEBPACK_COMPILER'); 9 | -------------------------------------------------------------------------------- /src/library/platform/bd/platform-core.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { MiniProgramCoreFactory as BaseFactory } from 'angular-miniprogram/platform/default'; 3 | 4 | class MiniProgramCoreFactory extends BaseFactory {} 5 | export const MiniProgramCore = new MiniProgramCoreFactory(); 6 | 7 | export { 8 | PAGE_TOKEN, 9 | MiniProgramRenderer, 10 | MiniProgramRendererFactory, 11 | ComponentFinderService, 12 | propertyChange, 13 | } from 'angular-miniprogram/platform/default'; 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/ng-library-import/ng-library-import.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | import { LibComp1Component } from 'test-library'; 3 | @Component({ 4 | selector: 'app-ng-library-import', 5 | templateUrl: './ng-library-import.component.html', 6 | }) 7 | export class NgLibraryImportComponent implements OnInit { 8 | @ViewChild('libComp1', { static: true }) libComp1: LibComp1Component; 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { TestLibraryService } from './test-library.service'; 4 | 5 | describe('TestLibraryService', () => { 6 | let service: TestLibraryService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(TestLibraryService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { OtherModule } from '../other/other.module'; 3 | import { TestLibraryComponent } from './test-library.component'; 4 | import { TestLibraryDirective } from './test-library.directive'; 5 | 6 | @NgModule({ 7 | declarations: [TestLibraryComponent, TestLibraryDirective], 8 | imports: [OtherModule], 9 | exports: [TestLibraryComponent, TestLibraryDirective], 10 | }) 11 | export class TestLibraryModule {} 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-template-outlet-spec/ng-template-outlet.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { NgTemplateOutletModule } from '../../spec-component/ng-template-outlet/ng-template-outlet.module'; 4 | import { NgTemplateOutletSPecComponent } from './ng-template-outlet.component'; 5 | @NgModule({ 6 | imports: [NgTemplateOutletModule], 7 | declarations: [NgTemplateOutletSPecComponent], 8 | exports: [NgTemplateOutletSPecComponent], 9 | }) 10 | export class NgTemplateOutletSpecModule {} 11 | -------------------------------------------------------------------------------- /src/builder/karma/plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../../../../dist/karma/plugin", 4 | "strict": false, 5 | "strictNullChecks": false, 6 | "allowUnreachableCode": true, 7 | "noUnusedParameters": false, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "esModuleInterop": true, 11 | "target": "ES2021", 12 | "module": "CommonJS", 13 | "lib": [ 14 | "ES2021" 15 | ], 16 | "skipLibCheck": true 17 | }, 18 | "files": [ 19 | "./index.ts" 20 | ] 21 | } -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component-need-template/component-need-template.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit, TemplateRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component-need-template', 5 | templateUrl: './component-need-template.component.html', 6 | styleUrls: ['./component-need-template.component.css'], 7 | }) 8 | export class ComponentNeedTemplateComponent implements OnInit { 9 | @Input() templateRef: TemplateRef; 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /src/builder/library/stylesheet-processor.ts: -------------------------------------------------------------------------------- 1 | import { StylesheetProcessor } from 'ng-packagr/lib/styles/stylesheet-processor'; 2 | 3 | export class CustomStyleSheetProcessor extends StylesheetProcessor { 4 | styleMap = new Map(); 5 | async process({ 6 | filePath, 7 | content, 8 | }: { 9 | filePath: string; 10 | content: string; 11 | }): Promise { 12 | const result = await super.process({ filePath, content }); 13 | this.styleMap.set(filePath, result); 14 | return ''; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-directive/base-directive.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { BaseDirectiveComponent } from './base-directive.component'; 4 | import { Directive1Directive } from './directive1.directive'; 5 | import { DirectiveModule } from 'test-library'; 6 | 7 | @NgModule({ 8 | imports: [CommonModule, DirectiveModule], 9 | declarations: [BaseDirectiveComponent, Directive1Directive], 10 | }) 11 | export class BaseDirectiveModule {} 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/self-component/self-component.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ComponentNeedTemplateModule } from '../../__components/component-need-template/component-need-template.module'; 4 | import { SelfComponentComponent } from './self-component.component'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule, ComponentNeedTemplateModule], 8 | declarations: [SelfComponentComponent], 9 | }) 10 | export class SelfComponentModule {} 11 | -------------------------------------------------------------------------------- /src/library/platform/index.ts: -------------------------------------------------------------------------------- 1 | import { MiniProgramCore } from 'angular-miniprogram/platform/wx'; 2 | 3 | export * from './http'; 4 | export * from './mini-program.module'; 5 | export * from './platform-miniprogram'; 6 | export { 7 | propertyChange, 8 | ComponentFinderService, 9 | } from 'angular-miniprogram/platform/wx'; 10 | export const pageStartup = MiniProgramCore.pageStartup; 11 | export const componentRegistry = MiniProgramCore.componentRegistry; 12 | export * from './token'; 13 | export { PAGE_TOKEN } from 'angular-miniprogram/platform/wx'; 14 | -------------------------------------------------------------------------------- /test/hello-world-app/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../tsconfig.base.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": ["jasmine"], 7 | "skipLibCheck": true, 8 | "target": "ES2022" 9 | }, 10 | "files": ["test.ts"], 11 | "include": [ 12 | "**/*.d.ts", 13 | "spec/**/*.entry.ts", 14 | "spec/**/*.spec.ts", 15 | "spec-component/**/*.entry.ts", 16 | "spec-component/**/*.module.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/custom-structural-directive.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { CustomStructuralDirectiveComponent } from './custom-structural-directive.component'; 4 | import { Structural1Directive } from './structural1.directive'; 5 | 6 | @NgModule({ 7 | imports: [CommonModule], 8 | declarations: [CustomStructuralDirectiveComponent, Structural1Directive], 9 | }) 10 | export class CustomStructuralDirectiveModule {} 11 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-forms/base-forms.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-base-forms', 5 | templateUrl: './base-forms.component.html', 6 | styleUrls: ['./base-forms.component.css'], 7 | }) 8 | export class BaseFormsComponent implements OnInit { 9 | value = '默认值'; 10 | checked = ['1']; 11 | constructor() {} 12 | 13 | ngOnInit() {} 14 | modelChange(e) { 15 | console.log('数据变更', e); 16 | } 17 | checkboxChange(e) { 18 | console.log(e); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/library/platform/qq/platform-core.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { MiniProgramCoreFactory as BaseFactory } from 'angular-miniprogram/platform/default'; 3 | 4 | declare const getCurrentPages: Function; 5 | class MiniProgramCoreFactory extends BaseFactory {} 6 | export const MiniProgramCore = new MiniProgramCoreFactory(); 7 | 8 | export { 9 | PAGE_TOKEN, 10 | MiniProgramRenderer, 11 | MiniProgramRendererFactory, 12 | ComponentFinderService, 13 | propertyChange, 14 | } from 'angular-miniprogram/platform/default'; 15 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/type.ts: -------------------------------------------------------------------------------- 1 | export type MatchedMeta = MatchedComponent | MatchedDirective; 2 | export interface MatchedComponent { 3 | isComponent: true; 4 | selector: string; 5 | filePath: string; 6 | exportPath: string; 7 | className: string; 8 | listeners: string[]; 9 | properties: string[]; 10 | inputs: string[]; 11 | outputs: string[]; 12 | } 13 | export interface MatchedDirective { 14 | isComponent: false; 15 | listeners: string[]; 16 | properties: string[]; 17 | inputs: string[]; 18 | outputs: string[]; 19 | } 20 | -------------------------------------------------------------------------------- /src/builder/karma/plugin/launcher.ts: -------------------------------------------------------------------------------- 1 | const miniProgram = function ( 2 | this: any, 3 | baseBrowserDecorator: any, 4 | config: any 5 | ) { 6 | baseBrowserDecorator(this); 7 | const self = this; 8 | this.name = 'miniprogram'; 9 | this._start = function (url: string) {}; 10 | this.on('kill', function (done: any) { 11 | self.emit('done'); 12 | process.nextTick(done); 13 | }); 14 | }; 15 | 16 | miniProgram.$inject = ['baseBrowserDecorator', 'config.jsdomLauncher']; 17 | 18 | export default { 19 | 'launcher:miniprogram': ['type', miniProgram], 20 | }; 21 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/ng-content/ng-content.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { NgContentComponent } from './ng-content.component'; 4 | import { ContentModule } from '../../__components/content/content.module'; 5 | import { ContentMultiModule } from '../../__components/content-multi/content-multi.module'; 6 | 7 | @NgModule({ 8 | imports: [CommonModule, ContentModule, ContentMultiModule], 9 | declarations: [NgContentComponent], 10 | }) 11 | export class NgContentModule {} 12 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/meta-collection.ts: -------------------------------------------------------------------------------- 1 | import { UseComponent } from './type'; 2 | 3 | export class MetaCollection { 4 | localPath: Set = new Set(); 5 | libraryPath: Set = new Set(); 6 | templateList: { name: string; content: string }[] = []; 7 | merge(other: MetaCollection) { 8 | other.localPath.forEach((item) => { 9 | this.localPath.add(item); 10 | }); 11 | other.libraryPath.forEach((item) => { 12 | this.libraryPath.add(item); 13 | }); 14 | this.templateList.push(...other.templateList); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/global-self-template/global-self-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { GlobalSelfTemplateComponent } from './global-self-template.component'; 3 | import { OutsideTemplateModule } from '../outside-template/outside-template.module'; 4 | import { OtherModule } from '../other/other.module'; 5 | 6 | @NgModule({ 7 | imports: [OutsideTemplateModule, OtherModule], 8 | declarations: [GlobalSelfTemplateComponent], 9 | exports: [GlobalSelfTemplateComponent], 10 | }) 11 | export class GlobalSelfTemplateModule {} 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-component/base-component.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { BaseComponentComponent } from './base-component.component'; 4 | import { Component1Module } from '../../__components/component1/component1.module'; 5 | import { Component2Module } from '../../__components/component2/component2.module'; 6 | 7 | @NgModule({ 8 | imports: [CommonModule, Component1Module, Component2Module], 9 | declarations: [BaseComponentComponent], 10 | }) 11 | export class BaseComponentModule {} 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/custom-structural-directive/structural1.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appStructural1]', 5 | }) 6 | export class Structural1Directive { 7 | @Input() appStructural1: TemplateRef; 8 | @Input() appStructural1Name: string; 9 | constructor(private viewContainerRef: ViewContainerRef) {} 10 | ngOnInit(): void { 11 | this.viewContainerRef.createEmbeddedView(this.appStructural1, { 12 | __templateName: this.appStructural1Name, 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-if-spec/ng-if.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgIfSPecComponent } from './ng-if.component'; 3 | describe('NgIfSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/ng-if-spec/ng-if-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/library/platform/http/provider.ts: -------------------------------------------------------------------------------- 1 | import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core'; 2 | import { HttpBackend, HttpFeature, HttpFeatureKind, provideHttpClient as ngProvideHttpClient } from 'angular-miniprogram/common/http'; 3 | import { MiniprogramHttpBackend } from './backend'; 4 | 5 | export function provideHttpClient(...features: HttpFeature[]): EnvironmentProviders { 6 | return makeEnvironmentProviders([ 7 | ngProvideHttpClient(...features), 8 | MiniprogramHttpBackend, 9 | { provide: HttpBackend, useExisting: MiniprogramHttpBackend } 10 | ]); 11 | } 12 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-for-spec/ng-for.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgForSPecComponent } from './ng-for.component'; 3 | describe('NgForSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/ng-for-spec/ng-for-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/text.ts: -------------------------------------------------------------------------------- 1 | import type { Text } from '../../angular-internal/ast.type'; 2 | import { NgNodeKind, NgNodeMeta, NgTextMeta, ParsedNode } from './interface'; 3 | 4 | export class ParsedNgText implements ParsedNode { 5 | kind = NgNodeKind.Text; 6 | 7 | constructor( 8 | private node: Text, 9 | public parent: ParsedNode | undefined, 10 | public index: number 11 | ) {} 12 | 13 | getNodeMeta(): NgTextMeta { 14 | return { 15 | kind: NgNodeKind.Text, 16 | value: this.node.value, 17 | index: this.index, 18 | }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/component-use-template/component-use-template.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { GlobalSelfTemplateModule } from 'test-library'; 3 | import { OutsideTemplateModule } from 'test-library'; 4 | import { Component1Module } from '../../__components/component1/component1.module'; 5 | import { ComponentUseTemplateComponent } from './component-use-template.component'; 6 | 7 | @NgModule({ 8 | imports: [OutsideTemplateModule, Component1Module, GlobalSelfTemplateModule], 9 | declarations: [ComponentUseTemplateComponent], 10 | }) 11 | export class ComponentUseTemplateModule {} 12 | -------------------------------------------------------------------------------- /src/builder/builders.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/@angular-devkit/architect/src/builders-schema.json", 3 | "builders": { 4 | "application": { 5 | "implementation": "./application", 6 | "schema": "./application/schema.json", 7 | "description": "小程序构建builder" 8 | }, 9 | "library": { 10 | "implementation": "./library/builder", 11 | "schema": "./library/schema.json", 12 | "description": "小程序构建library" 13 | }, 14 | "karma": { 15 | "implementation": "./karma", 16 | "schema": "./karma/schema.json", 17 | "description": "小程序测试" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/builder/platform/library/library.transform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { 3 | EVENT_PREFIX_REGEXP, 4 | WxTransformLike, 5 | } from '../template-transform-strategy/wx-like/wx-transform.base'; 6 | 7 | @Injectable() 8 | export class LibraryTransform extends WxTransformLike { 9 | directivePrefix = '${directivePrefix}'; 10 | templateInterpolation: [string, string] = [ 11 | '${templateInterpolation[0]}', 12 | '${templateInterpolation[1]}', 13 | ]; 14 | 15 | override eventListConvert = (list: string[]) => { 16 | return `\${eventListConvert(${JSON.stringify(list)})}`; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib-comp1/lib-comp1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, HostListener, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-lib-comp1', 5 | templateUrl: './lib-comp1.component.html', 6 | styleUrls: ['./lib-comp1.component.css'], 7 | }) 8 | export class LibComp1Component implements OnInit { 9 | @HostListener('tap', ['$event']) tap1(event) { 10 | console.log('library组件的tap事件', event); 11 | } 12 | @HostListener('bindtap', ['$event']) tap2(event) { 13 | console.log('library组件的(bind)tap事件', event); 14 | } 15 | constructor() {} 16 | 17 | ngOnInit() {} 18 | } 19 | -------------------------------------------------------------------------------- /src/builder/library/type.ts: -------------------------------------------------------------------------------- 1 | export interface ExtraTemplateData { 2 | template: string; 3 | useComponents?: Record; 4 | templateName?: string; 5 | outputPath?: string; 6 | } 7 | 8 | export interface ExportLibraryComponentMeta { 9 | id: string; 10 | content: string; 11 | contentTemplate?: string; 12 | style?: string; 13 | className: string; 14 | libraryPath: string; 15 | useComponents: Record; 16 | moduleId: string; 17 | } 18 | export interface LibraryComponentEntryMeta extends ExportLibraryComponentMeta { 19 | importPath: string; 20 | context: string; 21 | contextPath: string; 22 | } 23 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/life-time-spec/life-time.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { LifeTimeSPecComponent } from './life-time.component'; 3 | describe('LifeTimeSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/life-time-spec/life-time-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-switch-spec/ng-switch.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgSwitchSPecComponent } from './ng-switch.component'; 3 | describe('NgSwitchSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/ng-switch-spec/ng-switch-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/builder/karma/client/platform/wx/index.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { Socket } from 'socket.io-client'; 4 | 5 | const io = require('weapp.socket.io/lib/weapp.socket.io'); 6 | 7 | declare const KARMA_PORT: number; 8 | export class IO { 9 | instance: Socket; 10 | constructor() { 11 | this.instance = io(`http://localhost:${KARMA_PORT}`); 12 | } 13 | on(data: string, callback: (...args: any[]) => void) { 14 | this.instance.on(data, (...args) => { 15 | callback(...args); 16 | }); 17 | } 18 | emit(type: string, data: any) { 19 | this.instance.emit(type, data); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__components/component3/component3.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, HostListener, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component3', 5 | templateUrl: './component3.component.html', 6 | styleUrls: ['./component3.component.css'], 7 | standalone: true, 8 | }) 9 | export class Component3Component implements OnInit { 10 | @HostListener('tap', ['$event']) tap1(event) { 11 | console.log('内置组件的tap事件', event); 12 | } 13 | @HostListener('bindtap', ['$event']) tap2(event) { 14 | console.log('内置组件的(bind)tap事件', event); 15 | } 16 | constructor() {} 17 | 18 | ngOnInit() {} 19 | } 20 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-content-spec/ng-content.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgContentSpecComponent } from './ng-content.component'; 3 | describe('NgContentSpecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/ng-content-spec/ng-content-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/bound-text.ts: -------------------------------------------------------------------------------- 1 | import type { BoundText } from '../../angular-internal/ast.type'; 2 | import { 3 | NgBoundTextMeta, 4 | NgNodeKind, 5 | NgNodeMeta, 6 | ParsedNode, 7 | } from './interface'; 8 | 9 | export class ParsedNgBoundText implements ParsedNode { 10 | kind = NgNodeKind.BoundText; 11 | 12 | constructor( 13 | private node: BoundText, 14 | public parent: ParsedNode | undefined, 15 | public index: number 16 | ) {} 17 | getNodeMeta(): NgBoundTextMeta { 18 | return { 19 | kind: NgNodeKind.BoundText, 20 | index: this.index, 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/builder/application/loader/component-template.loader.ts: -------------------------------------------------------------------------------- 1 | import * as webpack from 'webpack'; 2 | import { changeComponent } from '../../component-template-inject/change-component'; 3 | 4 | export default async function ( 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 6 | this: webpack.LoaderContext, 7 | data: string, 8 | map: string 9 | ) { 10 | const callback = this.async(); 11 | const changeData = changeComponent(data)!; 12 | 13 | if (typeof data === 'undefined' || typeof changeData === 'undefined') { 14 | callback(undefined, data, map); 15 | return; 16 | } 17 | 18 | callback(undefined, changeData.content); 19 | } 20 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-http/base-http.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { HttpClient } from 'angular-miniprogram/common/http'; 3 | 4 | @Component({ 5 | selector: 'app-base-http', 6 | templateUrl: './base-http.component.html', 7 | styleUrls: ['./base-http.component.css'], 8 | }) 9 | export class BaseHttpComponent implements OnInit { 10 | constructor(private http: HttpClient) {} 11 | 12 | ngOnInit() {} 13 | request() { 14 | this.http 15 | .get('https://api.realworld.io/api/articles?limit=10&offset=0') 16 | .subscribe((item) => { 17 | console.log(item); 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/self-template-spec/self-template.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { SelfTemplateSPecComponent } from './self-template.component'; 3 | describe('SelfTemplateSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent(`/spec/self-template-spec/self-template-spec-entry`); 6 | }); 7 | it('run', (done) => { 8 | let pages = getCurrentPages(); 9 | let page = pages[0]; 10 | let component = getComponent(page); 11 | componentTestComplete(component.testFinish$$).then(() => { 12 | done(); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/style-class-spec/style-class-spec.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { StyleClassSpecComponent } from './style-class-spec.component'; 3 | 4 | describe('StyleClassSpecComponent', () => { 5 | beforeEach(async () => { 6 | await openComponent(`/spec/style-class-spec/style-class-spec-entry`); 7 | }); 8 | it('run', (done) => { 9 | let pages = getCurrentPages(); 10 | let page = pages[0]; 11 | let component = getComponent(page); 12 | componentTestComplete(component.testFinish$$).then(() => { 13 | done(); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/hello-world-app/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | /* SystemJS module definition */ 9 | import 'miniprogram-api-typings'; 10 | // declare var module: NodeModule; 11 | interface NodeModule { 12 | id: string; 13 | } 14 | // declare interface Type extends Function { 15 | // new (...args: any[]): T; 16 | // } 17 | // declare function ngStartPage(module: Type, component: Type): C; 18 | declare global { 19 | const ngDevMode: null | any; 20 | } 21 | -------------------------------------------------------------------------------- /test/hello-world-app/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-property-event/complex-property-event.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from 'angular-miniprogram/common'; 3 | import { ComplexPropertyEventComponent } from './complex-property-event.component'; 4 | import { AppDir1Directive } from './app-dir1.directive'; 5 | import { LibComp1Module } from 'test-library'; 6 | import { Component3Component } from '../../__components/component3/component3.component'; 7 | 8 | @NgModule({ 9 | imports: [CommonModule, LibComp1Module, Component3Component], 10 | declarations: [ComplexPropertyEventComponent, AppDir1Directive], 11 | }) 12 | export class ComplexPropertyEventModule {} 13 | -------------------------------------------------------------------------------- /script/startup-jasmine.ts: -------------------------------------------------------------------------------- 1 | import { register } from 'ts-node'; 2 | import { createTransformer } from 'static-injector/transform'; 3 | import Jasmine from 'jasmine'; 4 | import path from 'path'; 5 | 6 | register({ 7 | project: path.resolve(__dirname, '../tsconfig.spec.json'), 8 | transformers: (program) => { 9 | const transformer = createTransformer(program); 10 | return { 11 | before: [transformer], 12 | }; 13 | }, 14 | logError: true, 15 | }); 16 | let jasmineInstance = new Jasmine(); 17 | let args = process.argv.slice(2) || []; 18 | jasmineInstance.loadConfigFile(path.resolve(__dirname, '../jasmine.json')); 19 | jasmineInstance.execute(undefined, args[0] || undefined); 20 | -------------------------------------------------------------------------------- /test/hello-world-app/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright Google Inc. All Rights Reserved. 4 | * 5 | * Use of this source code is governed by an MIT-style license that can be 6 | * found in the LICENSE file at https://angular.io/license 7 | */ 8 | // The file contents for the current environment will overwrite these during build. 9 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 10 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 11 | // The list of which env maps to which file can be found in `.angular-cli.json`. 12 | 13 | export const environment = { 14 | production: false, 15 | }; 16 | -------------------------------------------------------------------------------- /src/library/platform/platform-miniprogram.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StaticProvider, 3 | createPlatformFactory, 4 | platformCore, 5 | } from '@angular/core'; 6 | import { MiniProgramCore } from 'angular-miniprogram/platform/wx'; 7 | import { APP_TOKEN, MINIPROGRAM_GLOBAL_TOKEN } from './token'; 8 | 9 | export function platformMiniProgram( 10 | extraProviders: StaticProvider[] = [], 11 | app?: T 12 | ) { 13 | return createPlatformFactory(platformCore, 'miniProgram', [ 14 | { provide: APP_TOKEN, useValue: MiniProgramCore.loadApp(app || {}) }, 15 | { 16 | provide: MINIPROGRAM_GLOBAL_TOKEN, 17 | useValue: MiniProgramCore.MINIPROGRAM_GLOBAL, 18 | }, 19 | ])(extraProviders); 20 | } 21 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/complex-structure/complex-structure.component.html: -------------------------------------------------------------------------------- 1 |
ngIf->ngIf
2 |
3 | 第一层 4 |
第二层
5 |
6 |
ngIf->ngFor
7 |
8 |
9 | 内容:item:{{ item }},index:{{ i }} 10 |
11 |
12 |
ngFor->ngFor
13 |
14 |
内容item1:{{ item1 }},item2:{{ item2 }}
15 |
16 | 17 |
ngFor->ng-content
18 |
19 | 投影内容:{{ item }} 20 |
21 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, HostBinding, HostListener, Output } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[libTestLibrary]', 5 | host: { 6 | '(tap)': 'hostTap($event)', 7 | }, 8 | }) 9 | export class TestLibraryDirective { 10 | @HostListener('touchstart', ['$event']) methodDecoratorTouchstart(event) { 11 | console.log('HostListener-touchstart', event); 12 | } 13 | @HostBinding('value') value; 14 | constructor() { 15 | setTimeout(() => { 16 | this.value = 'sdfsdf'; 17 | console.log('数据更改'); 18 | }, 3000); 19 | } 20 | hostTap(event) { 21 | console.log('tap', event); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/tag-view-convert-spec/tag-view-convert.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { TagViewConvertSpecComponent } from './tag-view-convert.component'; 3 | 4 | describe('TagViewConvertSpecComponent', () => { 5 | beforeEach(async () => { 6 | await openComponent( 7 | `/spec/tag-view-convert-spec/tag-view-convert-spec-entry` 8 | ); 9 | }); 10 | it('run', (done) => { 11 | let pages = getCurrentPages(); 12 | let page = pages[0]; 13 | let component = getComponent(page); 14 | componentTestComplete(component.testFinish$$).then(() => { 15 | done(); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-library-import-spec/ng-library-import.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgLibraryImportSPecComponent } from './ng-library-import.component'; 3 | describe('NgLibraryImportSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent( 6 | `/spec/ng-library-import-spec/ng-library-import-spec-entry` 7 | ); 8 | }); 9 | it('run', (done) => { 10 | let pages = getCurrentPages(); 11 | let page = pages[0]; 12 | let component = getComponent(page); 13 | componentTestComplete(component.testFinish$$).then(() => { 14 | done(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/ng-template-outlet-spec/ng-template-outlet.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { NgTemplateOutletSPecComponent } from './ng-template-outlet.component'; 3 | describe('NgTemplateOutletSPecComponent', () => { 4 | beforeEach(async () => { 5 | await openComponent( 6 | `/spec/ng-template-outlet-spec/ng-template-outlet-spec-entry` 7 | ); 8 | }); 9 | it('run', (done) => { 10 | let pages = getCurrentPages(); 11 | let page = pages[0]; 12 | let component = getComponent(page); 13 | componentTestComplete(component.testFinish$$).then(() => { 14 | done(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-tap/base-tap.component.html: -------------------------------------------------------------------------------- 1 | 直接插值({{ interpolation }}) 2 | 原生组件需要在module加入`schemas:[NO_ERRORS_SCHEMA]` 3 |
div组件转换为view
4 | span组件转换为view 5 |
组件定义的点击
6 |
字符串->字体颜色红色
7 |
变量->字体颜色红色
8 |
字符串->颜色背景绿色
9 |
变量->颜色背景绿色
10 | 11 |
mut-bind使用
12 |
catch使用
13 |
capture-bind使用
14 | 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/http-spec/http.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentTestComplete, getComponent, openComponent } from '../util'; 2 | import { HttpSpecComponent } from './http.component'; 3 | 4 | describe('http', () => { 5 | let oldTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 6 | beforeEach(async () => { 7 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100 * 1000; 8 | await openComponent(`/spec/http-spec/http-spec-entry`); 9 | }); 10 | it('run', (done) => { 11 | let pages = getCurrentPages(); 12 | let page = pages[0]; 13 | let component = getComponent(page); 14 | componentTestComplete(component.testFinish$$).then(() => { 15 | done(); 16 | jasmine.DEFAULT_TIMEOUT_INTERVAL = oldTimeout; 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/builder/platform/library/library-platform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { BuildPlatform } from '../platform'; 3 | import { LibraryTransform } from './library.transform'; 4 | 5 | export const ERROR_VALUE = '!!!library_can_not_use!!!'; 6 | @Injectable() 7 | export class LibraryBuildPlatform extends BuildPlatform { 8 | globalObject = ERROR_VALUE; 9 | globalVariablePrefix = ERROR_VALUE; 10 | fileExtname = { 11 | style: '${fileExtname.style}', 12 | logic: '${fileExtname.logic}', 13 | content: '${fileExtname.content}', 14 | contentTemplate: '${fileExtname.contentTemplate}', 15 | }; 16 | importTemplate = ERROR_VALUE; 17 | constructor(public templateTransform: LibraryTransform) { 18 | super(templateTransform); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/builder/platform/platform.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from 'static-injector'; 2 | import { TemplateTransformBase } from './template-transform-strategy/transform.base'; 3 | import { PlatformFileExtname } from './type'; 4 | 5 | export enum PlatformType { 6 | wx = 'wx', 7 | zj = 'zj', 8 | jd = 'jd', 9 | bdzn = 'bdzn', 10 | zfb = 'zfb', 11 | qq = 'qq', 12 | dd = 'dd', 13 | /** 这个属性只会在内部被使用 */ 14 | library = 'library', 15 | } 16 | @Injectable() 17 | export class BuildPlatform { 18 | packageName!: string; 19 | globalObject!: string; 20 | globalVariablePrefix!: string; 21 | fileExtname!: PlatformFileExtname; 22 | importTemplate!: string; 23 | constructor(public templateTransform: TemplateTransformBase) { 24 | this.templateTransform.init(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/library/platform/default/mini-program.renderer.factory.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Injectable, 3 | Renderer2, 4 | RendererFactory2, 5 | RendererType2, 6 | } from '@angular/core'; 7 | import { AgentNode } from './agent-node'; 8 | import { endRender } from './component-template-hook.factory'; 9 | import { MiniProgramRenderer } from './mini-program.renderer'; 10 | 11 | @Injectable() 12 | export class MiniProgramRendererFactory implements RendererFactory2 { 13 | defaultRenderer!: MiniProgramRenderer; 14 | constructor() { 15 | this.defaultRenderer = new MiniProgramRenderer(); 16 | } 17 | 18 | createRenderer(element: AgentNode, type: RendererType2 | null): Renderer2 { 19 | return this.defaultRenderer; 20 | } 21 | begin() {} 22 | end() { 23 | endRender(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/builder/util/load_esm.ts: -------------------------------------------------------------------------------- 1 | async function loadEsmModule(modulePath: string): Promise { 2 | const namespaceObject = await new Function( 3 | 'modulePath', 4 | `return import(modulePath);` 5 | )(modulePath); 6 | 7 | // If it is not ESM then the values needed will be stored in the `default` property. 8 | // TODO_ESM: This can be removed once `@angular/*` packages are ESM only. 9 | if (namespaceObject.default) { 10 | return namespaceObject.default; 11 | } else { 12 | return namespaceObject; 13 | } 14 | } 15 | 16 | export const angularCompilerPromise = 17 | loadEsmModule('@angular/compiler'); 18 | export const angularCompilerCliPromise = loadEsmModule< 19 | typeof import('@angular/compiler-cli') 20 | >('@angular/compiler-cli'); 21 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "sourceMap": true, 5 | "paths": { 6 | "angular-miniprogram/platform/default": [ 7 | "./src/library/platform/default/index.ts" 8 | ], 9 | "angular-miniprogram/platform/wx": ["./src/library/platform/wx/index.ts"], 10 | "angular-miniprogram/platform/type": [ 11 | "./src/library/platform/type/index.ts" 12 | ], 13 | "angular-miniprogram/platform": ["./src/library/platform/index.ts"], 14 | "angular-miniprogram/common": ["./src/library/common/index.ts"], 15 | "angular-miniprogram/common/http": ["./src/library/common/http/index.ts"] 16 | } 17 | }, 18 | "exclude": ["**/fixture/**"], 19 | "files": [], 20 | "include": ["src/**/*.spec.ts"] 21 | } 22 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/root/root.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/http-spec/http.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { HttpClient } from 'angular-miniprogram/common/http'; 3 | import { BehaviorSubject } from 'rxjs'; 4 | 5 | @Component({ 6 | selector: 'app-http-spec', 7 | template: ``, 8 | }) 9 | export class HttpSpecComponent implements OnInit { 10 | testFinish$$ = new BehaviorSubject(undefined); 11 | 12 | constructor(private http: HttpClient) {} 13 | 14 | ngOnInit() { 15 | this.request(); 16 | } 17 | request() { 18 | this.http 19 | .get('https://api.realworld.io/api/articles?limit=10&offset=0') 20 | .subscribe((item) => { 21 | expect(item).toBeTruthy(); 22 | expect(typeof item).toBe('object'); 23 | this.testFinish$$.complete(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - alpha 8 | 9 | jobs: 10 | pr-test: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: pull-code 15 | uses: actions/checkout@v2 16 | - name: install-node 17 | uses: actions/setup-node@v2 18 | with: 19 | node-version: 16.x 20 | cache: "npm" 21 | - name: install-dependencies 22 | run: | 23 | npm ci --legacy-peer-deps 24 | - name: lint 25 | run: | 26 | npm run lint 27 | - name: hook-code 28 | run: | 29 | npm run sync 30 | - name: test 31 | run: | 32 | npm run test:ci 33 | - name: build 34 | run: | 35 | npm run build 36 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/util/page-info.ts: -------------------------------------------------------------------------------- 1 | import type { MiniProgramComponentVariable } from 'angular-miniprogram/platform/type'; 2 | import { BehaviorSubject } from 'rxjs'; 3 | 4 | export function assertMiniProgramComponent( 5 | page 6 | ): page is MiniProgramComponentVariable { 7 | return page.__ngComponentInstance ? true : false; 8 | } 9 | 10 | export function getComponent( 11 | page: WechatMiniprogram.Page.Instance< 12 | WechatMiniprogram.IAnyObject, 13 | WechatMiniprogram.IAnyObject 14 | > 15 | ): T { 16 | return page.__ngComponentInstance; 17 | } 18 | 19 | export function componentTestComplete(subject: BehaviorSubject) { 20 | return new Promise((res) => { 21 | subject.subscribe({ 22 | complete: () => { 23 | res(); 24 | }, 25 | }); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /src/builder/platform/template-transform-strategy/transform.base.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import { Injectable } from 'static-injector'; 3 | import type { NgNodeMeta } from '../../mini-program-compiler'; 4 | import { MetaCollection, UseComponent } from '../../mini-program-compiler'; 5 | 6 | @Injectable() 7 | export abstract class TemplateTransformBase { 8 | abstract init(): any; 9 | abstract compile(nodes: NgNodeMeta[]): { 10 | content: string; 11 | useComponentPath: { 12 | localPath: UseComponent[]; 13 | libraryPath: UseComponent[]; 14 | }; 15 | otherMetaGroup: Record; 16 | }; 17 | abstract getData(): any; 18 | 19 | abstract templateInterpolation: [string, string]; 20 | abstract eventListConvert: (list: string[]) => string; 21 | } 22 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/lib/test-library.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TestLibraryComponent } from './test-library.component'; 4 | 5 | describe('TestLibraryComponent', () => { 6 | let component: TestLibraryComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [TestLibraryComponent], 12 | }).compileComponents(); 13 | }); 14 | 15 | beforeEach(() => { 16 | fixture = TestBed.createComponent(TestLibraryComponent); 17 | component = fixture.componentInstance; 18 | fixture.detectChanges(); 19 | }); 20 | 21 | it('should create', () => { 22 | expect(component).toBeTruthy(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/builder/platform/qq/qq-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { QqTransform } from './qq.transform'; 6 | 7 | @Injectable() 8 | export class QqBuildPlatform extends BuildPlatform { 9 | packageName = 'qq'; 10 | globalObject = 'qq'; 11 | globalVariablePrefix = 'qq.__window'; 12 | fileExtname = { 13 | style: '.qss', 14 | logic: '.js', 15 | content: '.qml', 16 | contentTemplate: '.qml', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | qq.__global = qq.__window = obj;`; 22 | constructor(public templateTransform: QqTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/builder/platform/dd/dd-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { DdTransform } from './dd.transform'; 6 | 7 | @Injectable() 8 | export class DdBuildPlatform extends BuildPlatform { 9 | packageName = 'dd'; 10 | globalObject = 'dd'; 11 | globalVariablePrefix = 'dd.__window'; 12 | fileExtname = { 13 | style: '.acss', 14 | logic: '.js', 15 | content: '.axml', 16 | contentTemplate: '.axml', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | dd.__global = dd.__window = obj;`; 22 | constructor(public templateTransform: DdTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/builder/platform/jd/jd-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { JdTransform } from './jd.transform'; 6 | 7 | @Injectable() 8 | export class JdBuildPlatform extends BuildPlatform { 9 | packageName = 'jd'; 10 | globalObject = 'jd'; 11 | globalVariablePrefix = 'jd.__window'; 12 | fileExtname = { 13 | style: '.jxss', 14 | logic: '.js', 15 | content: '.jxml', 16 | contentTemplate: '.jxml', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | jd.__global = jd.__window = obj;`; 22 | constructor(public templateTransform: JdTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/builder/platform/wx/wx-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { WxTransform } from './wx.transform'; 6 | 7 | @Injectable() 8 | export class WxBuildPlatform extends BuildPlatform { 9 | packageName = 'wx'; 10 | globalObject = 'wx'; 11 | globalVariablePrefix = 'wx.__window'; 12 | fileExtname = { 13 | style: '.wxss', 14 | logic: '.js', 15 | content: '.wxml', 16 | contentTemplate: '.wxml', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | wx.__global = wx.__window = obj;`; 22 | constructor(public templateTransform: WxTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/builder/library/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "title": "ng-packagr Target", 4 | "description": "ng-packagr target options for Build Architect. Use to build library projects.", 5 | "type": "object", 6 | "properties": { 7 | "project": { 8 | "type": "string", 9 | "description": "The file path for the ng-packagr configuration file, relative to the current workspace." 10 | }, 11 | "tsConfig": { 12 | "type": "string", 13 | "description": "The full path for the TypeScript configuration file, relative to the current workspace." 14 | }, 15 | "watch": { 16 | "type": "boolean", 17 | "description": "Run build when files change.", 18 | "default": false 19 | } 20 | }, 21 | "additionalProperties": false, 22 | "required": ["project"] 23 | } 24 | -------------------------------------------------------------------------------- /src/builder/platform/zfb/zfb-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { ZfbTransform } from './zfb.transform'; 6 | 7 | @Injectable() 8 | export class ZfbBuildPlatform extends BuildPlatform { 9 | packageName = 'zfb'; 10 | globalObject = 'my'; 11 | globalVariablePrefix = 'my.__window'; 12 | fileExtname = { 13 | style: '.acss', 14 | logic: '.js', 15 | content: '.axml', 16 | contentTemplate: '.axml', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | my.__global = my.__window = obj;`; 22 | constructor(public templateTransform: ZfbTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/test-builder/schema.library.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema", 3 | "title": "ng-packagr Target", 4 | "description": "ng-packagr target options for Build Architect. Use to build library projects.", 5 | "type": "object", 6 | "properties": { 7 | "project": { 8 | "type": "string", 9 | "description": "The file path for the ng-packagr configuration file, relative to the current workspace." 10 | }, 11 | "tsConfig": { 12 | "type": "string", 13 | "description": "The full path for the TypeScript configuration file, relative to the current workspace." 14 | }, 15 | "watch": { 16 | "type": "boolean", 17 | "description": "Run build when files change.", 18 | "default": false 19 | } 20 | }, 21 | "additionalProperties": false, 22 | "required": ["project"] 23 | } 24 | -------------------------------------------------------------------------------- /src/builder/platform/bd/bdzn-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { BdZnTransform } from './bdzn.transform'; 6 | 7 | @Injectable() 8 | export class BdZnBuildPlatform extends BuildPlatform { 9 | packageName = 'bd'; 10 | globalObject = 'swan'; 11 | globalVariablePrefix = 'swan.__window'; 12 | fileExtname = { 13 | style: '.css', 14 | logic: '.js', 15 | content: '.swan', 16 | contentTemplate: '.swan', 17 | }; 18 | importTemplate = `${fs 19 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 20 | .toString()}; 21 | swan.__global = swan.__window = obj;`; 22 | constructor(public templateTransform: BdZnTransform) { 23 | super(templateTransform); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/util/open-component.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | import { filter, take, tap } from 'rxjs/operators'; 3 | 4 | export function routeEvent() { 5 | return new Observable((ob) => { 6 | (wx as any).onAppRoute((result) => { 7 | ob.next(result); 8 | }); 9 | }); 10 | } 11 | 12 | export async function openComponent(url: string) { 13 | try { 14 | await new Promise((res, rej) => 15 | wx.reLaunch({ 16 | url: url, 17 | fail: rej, 18 | success: res, 19 | }) 20 | ); 21 | } catch (error) { 22 | throw new Error(error); 23 | } 24 | await routeEvent() 25 | .pipe( 26 | tap((res) => { 27 | console.log('生命周期', res); 28 | }), 29 | filter((item) => item.openType === 'reLaunch'), 30 | take(1) 31 | ) 32 | .toPromise(); 33 | } 34 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/base-tap/base-tap.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-base-tap', 5 | templateUrl: './base-tap.component.html', 6 | styleUrls: ['./base-tap.component.css'], 7 | }) 8 | export class BaseTagComponent implements OnInit { 9 | color = 'red'; 10 | backgroundColor = 'green'; 11 | interpolation = '这个是插值内容'; 12 | constructor() {} 13 | 14 | ngOnInit() {} 15 | tap1(event) { 16 | console.log('tap事件', event); 17 | } 18 | mutBindTap1(event) { 19 | console.log('mut-bindtap事件', event); 20 | } 21 | catchTap1(event) { 22 | console.log('catchtap事件', event); 23 | } 24 | captureBindTap1(event) { 25 | console.log('capture-bind事件', event); 26 | } 27 | // captureCatchTap1(event) { 28 | // console.log('capture-catch事件', event); 29 | // } 30 | } 31 | -------------------------------------------------------------------------------- /src/builder/library/merge-using-component-path.ts: -------------------------------------------------------------------------------- 1 | import { join, normalize, resolve } from '@angular-devkit/core'; 2 | import { UseComponent } from '../mini-program-compiler'; 3 | import { LIBRARY_OUTPUT_ROOTDIR } from './const'; 4 | import { getComponentOutputPath } from './get-library-path'; 5 | 6 | export function getUseComponents( 7 | libraryPath: UseComponent[], 8 | localPath: UseComponent[], 9 | moduleId: string 10 | ) { 11 | const list = [...libraryPath]; 12 | list.push( 13 | ...localPath.map((item) => { 14 | item.path = getComponentOutputPath(moduleId, item.className); 15 | return item; 16 | }) 17 | ); 18 | return list.reduce((pre, cur) => { 19 | pre[cur.selector] = resolve( 20 | normalize('/'), 21 | join(normalize(LIBRARY_OUTPUT_ROOTDIR), cur.path) 22 | ); 23 | return pre; 24 | }, {} as Record); 25 | } 26 | -------------------------------------------------------------------------------- /test/util/file.ts: -------------------------------------------------------------------------------- 1 | export const ALL_PAGE_NAME_LIST = [ 2 | `root`, 3 | `base-component`, 4 | `base-directive`, 5 | `base-tap`, 6 | `complex-property-event`, 7 | `complex-structure`, 8 | `custom-structural-directive`, 9 | `default-structural-directive`, 10 | `ng-content`, 11 | `base-forms`, 12 | `component-use-template`, 13 | `base-http`, 14 | `self-component`, 15 | `life-time-page`, 16 | `life-time-page-use-component`, 17 | ]; 18 | export const ALL_COMPONENT_NAME_LIST = [ 19 | `component1`, 20 | `component2`, 21 | `component3`, 22 | `content`, 23 | `content-multi`, 24 | `component-need-template`, 25 | `life-time`, 26 | ]; 27 | 28 | export const TEST_LIBRARY_COMPONENT_LIST = [ 29 | 'global-self-template-component', 30 | 'test-library-component', 31 | 'lib-comp1-component', 32 | 'other-component', 33 | 'outside-template-component', 34 | ]; 35 | -------------------------------------------------------------------------------- /src/builder/platform/zjtd/zj-platform.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs-extra'; 2 | import * as path from 'path'; 3 | import { Injectable } from 'static-injector'; 4 | import { BuildPlatform } from '../platform'; 5 | import { ZjTransform } from './zj.transform'; 6 | /** 字节小程序适配 */ 7 | @Injectable() 8 | export class ZjBuildPlatform extends BuildPlatform { 9 | packageName = 'zjtd'; 10 | globalObject = 'tt'; 11 | globalVariablePrefix = 'tt.__window'; 12 | fileExtname = { 13 | style: '.ttss', 14 | logic: '.js', 15 | content: '.ttml', 16 | contentTemplate: '.ttml', 17 | config: '.json', 18 | }; 19 | importTemplate = `${fs 20 | .readFileSync(path.resolve(__dirname, '../template/app-template.js')) 21 | .toString()}; 22 | tt.__global = tt.__window = obj;`; 23 | constructor(public templateTransform: ZjTransform) { 24 | super(templateTransform); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/builder/platform/util/type-predicate.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NgBoundTextMeta, 3 | NgContentMeta, 4 | NgElementMeta, 5 | NgNodeKind, 6 | NgNodeMeta, 7 | NgTemplateMeta, 8 | NgTextMeta, 9 | } from '../../mini-program-compiler'; 10 | 11 | export function isNgElementMeta(node: NgNodeMeta): node is NgElementMeta { 12 | return node.kind === NgNodeKind.Element; 13 | } 14 | export function isNgBoundTextMeta(node: NgNodeMeta): node is NgBoundTextMeta { 15 | return node.kind === NgNodeKind.BoundText; 16 | } 17 | export function isNgContentMeta(node: NgNodeMeta): node is NgContentMeta { 18 | return node.kind === NgNodeKind.Content; 19 | } 20 | export function isNgTemplateMeta(node: NgNodeMeta): node is NgTemplateMeta { 21 | return node.kind === NgNodeKind.Template; 22 | } 23 | export function isNgTextMeta(node: NgNodeMeta): node is NgTextMeta { 24 | return node.kind === NgNodeKind.Text; 25 | } 26 | -------------------------------------------------------------------------------- /test/hello-world-app/projects/test-library/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of test-library 3 | */ 4 | 5 | export * from './lib/test-library.service'; 6 | export * from './lib/test-library.component'; 7 | export * from './lib/test-library.module'; 8 | export * from './lib/test-library.directive'; 9 | export * from './other/other.component'; 10 | export * from './lib-comp1/lib-comp1.module'; 11 | export * from './lib-comp1/lib-comp1.component'; 12 | export * from './lib-comp1/lib-dir1.directive'; 13 | export * from './directive/directive.module'; 14 | export * from './directive/input-output.directive'; 15 | export * from './other/other.module'; 16 | export * from './outside-template/outside-template.module'; 17 | export * from './outside-template/outside-template.component'; 18 | export * from './global-self-template/global-self-template.module'; 19 | export * from './global-self-template/global-self-template.component'; 20 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/type.ts: -------------------------------------------------------------------------------- 1 | import { MetaCollection } from './meta-collection'; 2 | 3 | export interface ComponentMetaFromLibrary { 4 | isComponent: true; 5 | exportPath: string; 6 | listeners: string[]; 7 | properties: string[]; 8 | } 9 | export interface DirectiveMetaFromLibrary { 10 | isComponent: false; 11 | listeners: string[]; 12 | properties: string[]; 13 | } 14 | export type MetaFromLibrary = 15 | | ComponentMetaFromLibrary 16 | | DirectiveMetaFromLibrary; 17 | 18 | export interface UseComponent { 19 | selector: string; 20 | className: string; 21 | path: string; 22 | } 23 | export interface ResolvedDataGroup { 24 | style: Map; 25 | outputContent: Map; 26 | useComponentPath: Map< 27 | string, 28 | { 29 | localPath: UseComponent[]; 30 | libraryPath: UseComponent[]; 31 | } 32 | >; 33 | otherMetaCollectionGroup: Record; 34 | } 35 | -------------------------------------------------------------------------------- /deploy/doc/zh-Hans/life-time.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 生命周期 4 | --- 5 | # 组件(Component) 6 | 7 | - created 8 | > 等待链接(小程序 Component 与 ng Component 关联) 9 | - properties 变更(第一次) 10 | > 链接(ng自动初始化) 11 | - attached 12 | - ready 13 | 14 | # 页面(Page) 15 | 16 | - onLoad 17 | > 初始化并链接 18 | - onShow(第一次) 19 | - onReady 20 | 21 | # 页面(Component) 22 | 23 | - onLoad 24 | - onShow(第一次) 25 | - created 26 | > 初始化 27 | - attached 28 | > 链接 29 | - onReady 30 | 31 | 32 | # 组件(Component)在页面(Page)中 33 | 34 | - ng-constructor(onLoad 开始) 35 | > 页面组件 36 | > 初始化并链接 37 | - ng-constructor(component) 38 | > 子组件 39 | - ng-ngOnInit 40 | - ng-ngAfterContentInit 41 | - ng-ngOnInit(component) 42 | - ng-ngAfterContentInit(component) 43 | - ng-ngAfterViewInit(component) 44 | - ng-ngAfterViewInit 45 | - mp-created(component) 46 | > 子组件链接(created之后,attached之前) 47 | - mp-attached(component) 48 | - mp-onLoad(onLoad 末尾) 49 | - mp-onShow 50 | - mp-onReady 51 | - mp-ready(component) 52 | -------------------------------------------------------------------------------- /src/builder/library/ng-packagr-factory.ts: -------------------------------------------------------------------------------- 1 | import { COMPILE_NGC_TRANSFORM } from 'ng-packagr/lib/ng-package/entry-point/compile-ngc.di'; 2 | import { STYLESHEET_PROCESSOR } from 'ng-packagr/lib/styles/stylesheet-processor.di'; 3 | import { myCompileNgcTransformFactory } from './compile-ngc.transform'; 4 | import { hookWritePackage } from './remove-publish-only'; 5 | import { CustomStyleSheetProcessor } from './stylesheet-processor'; 6 | 7 | export async function ngPackagrFactory( 8 | project: string, 9 | tsConfig: string | undefined 10 | ) { 11 | const packager = (await import('ng-packagr')).ngPackagr(); 12 | 13 | packager.forProject(project); 14 | 15 | if (tsConfig) { 16 | packager.withTsConfig(tsConfig); 17 | } 18 | 19 | COMPILE_NGC_TRANSFORM.useFactory = myCompileNgcTransformFactory; 20 | STYLESHEET_PROCESSOR.useFactory = () => CustomStyleSheetProcessor; 21 | packager.withProviders([COMPILE_NGC_TRANSFORM, hookWritePackage()]); 22 | return packager; 23 | } 24 | -------------------------------------------------------------------------------- /src/builder/angular-internal/ast.type.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | TmplAstBoundAttribute, 3 | TmplAstBoundEvent, 4 | TmplAstBoundText, 5 | TmplAstContent, 6 | TmplAstElement, 7 | TmplAstIcu, 8 | TmplAstNode, 9 | TmplAstRecursiveVisitor, 10 | TmplAstReference, 11 | TmplAstTemplate, 12 | TmplAstText, 13 | TmplAstTextAttribute, 14 | TmplAstVariable, 15 | } from '@angular/compiler'; 16 | 17 | export type Element = TmplAstElement; 18 | export type Template = TmplAstTemplate; 19 | 20 | export type Content = TmplAstContent; 21 | export type Variable = TmplAstVariable; 22 | export type Reference = TmplAstReference; 23 | export type TextAttribute = TmplAstTextAttribute; 24 | export type BoundAttribute = Parameters< 25 | TmplAstRecursiveVisitor['visitBoundAttribute'] 26 | >[0]; 27 | export type BoundEvent = TmplAstBoundEvent; 28 | export type Text = TmplAstText; 29 | export type BoundText = TmplAstBoundText; 30 | export type Icu = TmplAstIcu; 31 | export type Node = TmplAstNode; 32 | -------------------------------------------------------------------------------- /src/library/platform/default/component-finder.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class ComponentFinderService { 5 | private map = new Map(); 6 | private mapPromise = new Map(); 7 | async get(component: unknown) { 8 | if (this.map.has(component)) { 9 | return this.map.get(component); 10 | } 11 | let fn: Function; 12 | const promise = new Promise((res) => { 13 | fn = res; 14 | }); 15 | this.mapPromise.set(component, fn!); 16 | return promise.then((result) => { 17 | this.mapPromise.delete(component); 18 | return result; 19 | }); 20 | } 21 | /** @internal */ 22 | set(component: unknown, instance: T): void { 23 | if (this.mapPromise.has(component)) { 24 | this.mapPromise.get(component)!(); 25 | } 26 | this.map.set(component, instance); 27 | } 28 | /** @internal */ 29 | remove(component: unknown) { 30 | return this.map.delete(component); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /script/schema-merge.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | function merge(origin: string, additional: string, output: string) { 4 | origin = require.resolve(origin); 5 | additional = require.resolve(additional); 6 | let originFile = JSON.parse(fs.readFileSync(origin).toString()); 7 | let additionalFile = JSON.parse(fs.readFileSync(additional).toString()); 8 | let outputAbsolutePath = path.resolve(path.dirname(additional), output); 9 | originFile['properties'] = { 10 | ...additionalFile['properties'], 11 | ...originFile['properties'], 12 | }; 13 | originFile['definitions'] = { 14 | ...originFile['definitions'], 15 | ...additionalFile['definitions'], 16 | }; 17 | fs.writeFileSync( 18 | outputAbsolutePath, 19 | JSON.stringify(originFile, undefined, 2) 20 | ); 21 | } 22 | function main() { 23 | merge( 24 | '@angular-devkit/build-angular/src/browser/schema.json', 25 | '../src/builder/application/schema.base.json', 26 | './schema.json' 27 | ); 28 | } 29 | main(); 30 | -------------------------------------------------------------------------------- /deploy/doc/en-US/life-time.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Life Time 4 | --- 5 | # Component(Component) 6 | 7 | - created 8 | > Wait for link (miniprogram component is associated with ng component) 9 | - properties Change(first) 10 | > link(init with ng auto) 11 | - attached 12 | - ready 13 | 14 | # Page(Page) 15 | 16 | - onLoad 17 | > init and link 18 | - onShow(first) 19 | - onReady 20 | 21 | # Page(Component) 22 | 23 | - onLoad 24 | - onShow(first) 25 | - created 26 | > init 27 | - attached 28 | > link 29 | - onReady 30 | 31 | # Component(Component) in Page(Page) 32 | 33 | 34 | - ng-constructor(onLoad start) 35 | > ng page Component 36 | > init and link 37 | - ng-constructor(component) 38 | > ng component Component 39 | - ng-ngOnInit 40 | - ng-ngAfterContentInit 41 | - ng-ngOnInit(component) 42 | - ng-ngAfterContentInit(component) 43 | - ng-ngAfterViewInit(component) 44 | - ng-ngAfterViewInit 45 | - mp-created(component) 46 | - mp-attached(component) 47 | > sub component link(after created ,before created) 48 | - mp-onLoad(onLoad end) 49 | - mp-onShow 50 | - mp-onReady 51 | - mp-ready(component) 52 | -------------------------------------------------------------------------------- /src/builder/platform/zfb/zfb.transform.ts: -------------------------------------------------------------------------------- 1 | import { capitalize } from '@angular-devkit/core/src/utils/strings'; 2 | import { Injectable } from 'static-injector'; 3 | import { WxTransformLike } from '../template-transform-strategy/wx-like/wx-transform.base'; 4 | 5 | const BIND_PREFIX_REGEXP = /^(bind|mut-bind|capture-bind)(.*)/; 6 | const CATCH_PREFIX_REGEXP = /^(catch|capture-catch)(.*)/; 7 | @Injectable() 8 | export class ZfbTransform extends WxTransformLike { 9 | directivePrefix = 'a'; 10 | override eventNameConvert(name: string) { 11 | let result = name.match(BIND_PREFIX_REGEXP); 12 | if (result) { 13 | return { 14 | prefix: 'on', 15 | type: result[2], 16 | name: `on${capitalize(result[2])}`, 17 | }; 18 | } 19 | result = name.match(CATCH_PREFIX_REGEXP); 20 | if (result) { 21 | return { 22 | prefix: 'catch', 23 | type: result[2], 24 | name: `catch${capitalize(result[2])}`, 25 | }; 26 | } 27 | return { 28 | prefix: 'on', 29 | type: name, 30 | name: `on${capitalize(name)}`, 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/builder/application/type.ts: -------------------------------------------------------------------------------- 1 | import type { AssetPattern } from '@angular-devkit/build-angular'; 2 | import { LibraryComponentEntryMeta } from '../library'; 3 | import { BuildPlatform, PlatformFileExtname } from '../platform'; 4 | 5 | export interface LibraryTemplateLiteralConvertOptions { 6 | directivePrefix: string; 7 | eventListConvert: (name: string[]) => string; 8 | templateInterpolation: [string, string]; 9 | fileExtname: PlatformFileExtname; 10 | } 11 | 12 | export interface PagePattern extends Exclude { 13 | /** 入口名 */ 14 | entryName: string; 15 | /** 匹配文件,相对于input */ 16 | fileName: string; 17 | /** 要输出的js出口 */ 18 | output: string; 19 | /** 绝对路径,path.join */ 20 | src: string; 21 | outputFiles: { 22 | content: string; 23 | style: string; 24 | logic: string; 25 | path: string; 26 | config: string; 27 | }; 28 | inputFiles: { 29 | config: string; 30 | }; 31 | type: 'component' | 'page'; 32 | } 33 | 34 | export interface LibraryLoaderContext { 35 | libraryMetaList: LibraryComponentEntryMeta[]; 36 | buildPlatform: BuildPlatform; 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 chen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/content.ts: -------------------------------------------------------------------------------- 1 | import type { Content } from '../../angular-internal/ast.type'; 2 | import { NgContentMeta, NgNodeKind, NgNodeMeta, ParsedNode } from './interface'; 3 | 4 | const SELECT_NAME_VALUE_REGEXP = /^\[slot=["']?([^"']*)["']?\]$/; 5 | export class ParsedNgContent implements ParsedNode { 6 | kind = NgNodeKind.Content; 7 | 8 | constructor( 9 | private node: Content, 10 | public parent: ParsedNode | undefined, 11 | public index: number 12 | ) {} 13 | getNodeMeta(): NgContentMeta { 14 | const nameAttr = this.node.attributes.find( 15 | (item) => item.name === 'select' 16 | ); 17 | let value: string | undefined; 18 | if (nameAttr) { 19 | const result = nameAttr.value.match(SELECT_NAME_VALUE_REGEXP); 20 | if (!result) { 21 | throw new Error( 22 | `ng-content未匹配到指定格式的select,value:${nameAttr.value},需要格式为[slot="xxxx"]` 23 | ); 24 | } 25 | value = result[1]; 26 | } 27 | return { 28 | kind: NgNodeKind.Content, 29 | name: value, 30 | index: this.index, 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/library/platform/mini-program.module.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationModule, 3 | ErrorHandler, 4 | NgModule, 5 | RendererFactory2, 6 | ɵINJECTOR_SCOPE, 7 | } from '@angular/core'; 8 | import { CommonModule } from 'angular-miniprogram/common'; 9 | import { 10 | ComponentFinderService, 11 | MiniProgramRendererFactory, 12 | } from 'angular-miniprogram/platform/wx'; 13 | import { PageService } from './page.service'; 14 | 15 | function errorHandler(): ErrorHandler { 16 | return new ErrorHandler(); 17 | } 18 | 19 | @NgModule({ 20 | declarations: [], 21 | imports: [CommonModule, ApplicationModule], 22 | providers: [ 23 | { provide: ɵINJECTOR_SCOPE, useValue: 'root' }, 24 | { provide: ErrorHandler, useFactory: errorHandler, deps: [] }, 25 | MiniProgramRendererFactory, 26 | { 27 | provide: RendererFactory2, 28 | useExisting: MiniProgramRendererFactory, 29 | }, 30 | PageService, 31 | ComponentFinderService, 32 | ], 33 | exports: [CommonModule, ApplicationModule], 34 | }) 35 | export class MiniProgramModule { 36 | constructor(pageService: PageService) { 37 | pageService.register(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/hello-world-app/src/test.ts: -------------------------------------------------------------------------------- 1 | import { platformMiniProgram } from 'angular-miniprogram'; 2 | import { startupTest } from 'angular-miniprogram/karma/client'; 3 | import { MainTestModule } from './main-test.module'; 4 | import 'zone.js'; 5 | 6 | let jasmineRequire = require('jasmine-core/lib/jasmine-core/jasmine.js'); 7 | 8 | function bootWithoutGlobals() { 9 | let jasmineInterface; 10 | const jasmine = jasmineRequire.core(jasmineRequire); 11 | const env = jasmine.getEnv({ suppressLoadErrors: true }); 12 | jasmineInterface = jasmineRequire.interface(jasmine, env); 13 | 14 | return jasmineInterface; 15 | } 16 | 17 | let obj = bootWithoutGlobals(); 18 | for (const key in obj) { 19 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 20 | (wx as any).__global[key] = obj[key]; 21 | } 22 | } 23 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 10 * 1000; 24 | 25 | platformMiniProgram() 26 | .bootstrapModule(MainTestModule) 27 | .then((e) => {}); 28 | // Then we find all the tests. 29 | // And load the modules. 30 | // 因为ng修改了test的获取实例的时机,改为拼在最后面,而启动操作要在最后面的后面,所以使用了延时(网页端正常是因为spec=>component,而小程序目前设计是component spec平行) 31 | setTimeout(() => { 32 | startupTest(); 33 | }, 1000); 34 | -------------------------------------------------------------------------------- /src/library/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-miniprogram", 3 | "version": "1.5.2", 4 | "description": "使用Angular开发小程序", 5 | "keywords": [ 6 | "Angular", 7 | "miniprogram", 8 | "wechat", 9 | "weixin", 10 | "Angular 17" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/wszgrcy/angular-miniprogram.git" 15 | }, 16 | "author": "wszgrcy", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/wszgrcy/angular-miniprogram/issues" 20 | }, 21 | "homepage": "https://github.com/wszgrcy/angular-miniprogram#readme", 22 | "dependencies": { 23 | "cyia-code-util": "1.8.0", 24 | "webpack-bootstrap-assets-plugin": "2.0.3", 25 | "static-injector": "4.0.2" 26 | }, 27 | "peerDependencies": { 28 | "ng-packagr": "^17.3.0", 29 | "@angular/core": "^17.3.1", 30 | "jasmine-core": "5.1.2" 31 | }, 32 | "exports": { 33 | "./karma/client": { 34 | "default": "./karma/client/index.js" 35 | }, 36 | "./karma/plugin": { 37 | "default": "./karma/plugin/index.js", 38 | "types": "./karma/plugin/index.d.ts" 39 | } 40 | }, 41 | "builders": "./builder/builders.json" 42 | } 43 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/life-time-page/life-time.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { MiniProgramComponentInstance } from 'angular-miniprogram/platform/type'; 3 | 4 | @Component({ 5 | selector: 'app-life-time', 6 | templateUrl: './life-time.component.html', 7 | }) 8 | export class LifeTimePage implements OnInit { 9 | static mpPageOptions: WechatMiniprogram.Page.Options<{}, {}> = { 10 | onLoad: function (this: MiniProgramComponentInstance) { 11 | console.log('mp-onLoad', this.__ngComponentInstance); 12 | }, 13 | onShow: function () { 14 | console.log('mp-onShow', this.__ngComponentInstance); 15 | }, 16 | onReady: function ( 17 | this: WechatMiniprogram.Page.Instance<{}, {}> & 18 | MiniProgramComponentInstance 19 | ) { 20 | console.log('mp-onReady'); 21 | }, 22 | }; 23 | constructor() { 24 | console.log('ng-constructor'); 25 | } 26 | 27 | ngOnInit() { 28 | console.log('ng-ngOnInit'); 29 | } 30 | ngAfterViewInit(): void { 31 | console.log('ng-ngAfterViewInit'); 32 | } 33 | ngAfterContentInit(): void { 34 | console.log('ng-ngAfterContentInit'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/component-compiler.service.ts: -------------------------------------------------------------------------------- 1 | import type { R3ComponentMetadata } from '@angular/compiler'; 2 | import { Inject, Injectable } from 'static-injector'; 3 | import { BuildPlatform } from '../platform/platform'; 4 | import { COMPONENT_META } from '../token/component.token'; 5 | import { ComponentContext, TemplateDefinition } from './parse-node'; 6 | 7 | @Injectable() 8 | export class ComponentCompilerService { 9 | constructor( 10 | private buildPlatform: BuildPlatform, 11 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 12 | @Inject(COMPONENT_META) private componentMeta: R3ComponentMetadata, 13 | private componentContext: ComponentContext 14 | ) {} 15 | 16 | private collectionNode() { 17 | const nodes = this.componentMeta.template.nodes; 18 | const templateDefinition = new TemplateDefinition( 19 | nodes, 20 | this.componentContext 21 | ); 22 | const list = templateDefinition.run(); 23 | return list.map((item) => item.getNodeMeta()); 24 | } 25 | 26 | compile() { 27 | const nodeList = this.collectionNode(); 28 | const result = this.buildPlatform.templateTransform.compile(nodeList); 29 | return result; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tsconfig.doc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "files": ["./src/library/platform/index.ts"], 4 | 5 | "compilerOptions": { 6 | "baseUrl": "./src/library", 7 | "noImplicitThis": true, 8 | "outDir": "dist", 9 | "declaration": true, 10 | "target": "ES2015", 11 | "module": "esnext", 12 | "strict": true, 13 | "useUnknownInCatchVariables": false, 14 | "stripInternal": true, 15 | "lib": ["es2019", "dom"], 16 | "typeRoots": ["./src/library"], 17 | "types": ["declaration"], 18 | "paths": { 19 | "angular-miniprogram/platform/default": ["./platform/default/index.ts"], 20 | "angular-miniprogram/platform/wx": ["./platform/wx/index.ts"], 21 | "angular-miniprogram/platform/type": ["./platform/type/index.ts"], 22 | "angular-miniprogram/platform": ["./platform/index.ts"], 23 | "angular-miniprogram/common": ["./common/index.ts"], 24 | "angular-miniprogram/common/http": ["./common/http/index.ts"] 25 | } 26 | }, 27 | "exclude": [ 28 | "./src/**/*.template.ts", 29 | "./src/**/*.d.ts", 30 | "**/*.spec.ts", 31 | "test" 32 | ], 33 | "angularCompilerOptions": { 34 | "enableIvy": true, 35 | "compilationMode": "full" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/template.ts: -------------------------------------------------------------------------------- 1 | import type { Template } from '../../angular-internal/ast.type'; 2 | import { 3 | NgNodeKind, 4 | NgNodeMeta, 5 | NgTemplateMeta, 6 | ParsedNode, 7 | } from './interface'; 8 | 9 | export class ParsedNgTemplate implements ParsedNode { 10 | kind = NgNodeKind.Template; 11 | private children: ParsedNode[] = []; 12 | 13 | constructor( 14 | private node: Template, 15 | public parent: ParsedNode | undefined, 16 | public index: number 17 | ) {} 18 | 19 | appendNgNodeChild(child: ParsedNode) { 20 | this.children.push(child); 21 | } 22 | private getTemplateName(): string { 23 | if (this.node.references && this.node.references.length) { 24 | return this.node.references[0].name; 25 | } else { 26 | return `ngDefault_${this.index}`; 27 | } 28 | } 29 | 30 | getNodeMeta(): NgTemplateMeta { 31 | const directive = this.getTemplateName()!; 32 | const meta: NgTemplateMeta = { 33 | kind: NgNodeKind.Template, 34 | children: this.children.map((child) => child.getNodeMeta()), 35 | index: this.index, 36 | defineTemplateName: directive, 37 | }; 38 | 39 | return meta; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec/util/node-query.ts: -------------------------------------------------------------------------------- 1 | export function nodeExist( 2 | query: WechatMiniprogram.SelectorQuery, 3 | selector: string 4 | ) { 5 | return new Promise((res, rej) => { 6 | try { 7 | query 8 | .select(selector) 9 | .context((data) => { 10 | res(!!data); 11 | }) 12 | .exec(); 13 | } catch (error) { 14 | rej(error); 15 | } 16 | }); 17 | } 18 | export function nodeNotEmpty( 19 | query: WechatMiniprogram.SelectorQuery, 20 | selector: string 21 | ) { 22 | return new Promise((res, rej) => { 23 | try { 24 | query 25 | .select(selector) 26 | .boundingClientRect((data) => { 27 | res(!!data.height); 28 | }) 29 | .exec(); 30 | } catch (error) { 31 | rej(error); 32 | } 33 | }); 34 | } 35 | 36 | export function fields( 37 | query: WechatMiniprogram.SelectorQuery, 38 | selector: string, 39 | fields: WechatMiniprogram.Fields 40 | ) { 41 | return new Promise((res, rej) => { 42 | try { 43 | query 44 | .select(selector) 45 | .fields(fields, (data) => { 46 | res(data); 47 | }) 48 | .exec(); 49 | } catch (error) { 50 | rej(error); 51 | } 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /src/library/platform/http/README.md: -------------------------------------------------------------------------------- 1 | # 小程序 HTTP 2 | 3 | ## 注意事项 4 | 5 | ### 导入 6 | 7 | ```ts 8 | import { HttpClientModule } from 'angular-miniprogram'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | HttpClientModule 13 | ] 14 | }) 15 | export class AppModule { } 16 | ``` 17 | 18 | 或 19 | 20 | ```ts 21 | import { provideHttpClient } from 'angular-miniprogram'; 22 | 23 | bootstrapApplication(AppComponent, { 24 | providers: [ 25 | provideHttpClient() 26 | ] 27 | }); 28 | ``` 29 | 30 | ### 小程序额外参数 31 | 32 | 为保持 API 的统一,需要借助 `HttpContext` 来传递小程序额外的参数。 33 | 34 | ```ts 35 | import { 36 | UPLOAD_FILE_TOKEN, 37 | DOWNLOAD_FILE_TOKEN, 38 | REQUSET_TOKEN, 39 | } from 'angular-miniprogram'; 40 | import { HttpContext, HttpContextToken } from 'angular-miniprogram/common/http'; 41 | 42 | // ... 43 | 44 | // 小程序开启 HTTP2 45 | http.get('url', { 46 | context: new HttpContext().set(REQUSET_TOKEN, { 47 | enableHttp2: true, 48 | }), 49 | }); 50 | 51 | // 小程序文件上传 52 | http.post('url', null, { 53 | context: new HttpContext().set(UPLOAD_FILE_TOKEN, { 54 | filePath: 'filePath', 55 | fileName: 'fileName', 56 | }), 57 | }); 58 | 59 | // 小程序文件下载 60 | http.get('url', { 61 | context: new HttpContext().set(DOWNLOAD_FILE_TOKEN, { 62 | filePath: 'filePath', 63 | }), 64 | }); 65 | ``` 66 | -------------------------------------------------------------------------------- /test/hello-world-app/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strictNullChecks": true, 14 | "target": "es2022", 15 | "module": "es2020", 16 | "typeRoots": ["node_modules/@types"], 17 | "lib": ["es2018", "dom"], 18 | "paths": { 19 | "angular-miniprogram": ["../../dist"], 20 | "angular-miniprogram/platform": ["../../dist/platform"], 21 | "angular-miniprogram/platform/type": ["../../dist/platform/type"], 22 | "angular-miniprogram/platform/wx": ["../../dist/platform/wx"], 23 | "angular-miniprogram/platform/default": ["../../dist/platform/default"], 24 | "angular-miniprogram/platform/zjtd": ["../../dist/platform/zjtd"], 25 | "angular-miniprogram/forms": ["../../dist/forms"], 26 | "angular-miniprogram/common": ["../../dist/common"], 27 | "angular-miniprogram/common/http": ["../../dist/common/http"], 28 | "angular-miniprogram/karma/client": ["../../src/builder/karma/client"] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/builder/angular-internal/template.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | /** 3 | * @license 4 | * Copyright Google LLC All Rights Reserved. 5 | * 6 | * Use of this source code is governed by an MIT-style license that can be 7 | * found in the LICENSE file at https://angular.io/license 8 | */ 9 | 10 | import type { CssSelector as CssSelectorType } from '@angular/compiler'; 11 | import { CssSelector } from './selector'; 12 | import { splitNsName } from './tags'; 13 | /** 14 | * Creates a `CssSelector` given a tag name and a map of attributes 15 | */ 16 | export function createCssSelector( 17 | elementName: string, 18 | attributes: { [name: string]: string } 19 | ): CssSelectorType { 20 | const cssSelector = new CssSelector(); 21 | const elementNameNoNs = splitNsName(elementName)[1]; 22 | 23 | cssSelector.setElement(elementNameNoNs); 24 | 25 | Object.getOwnPropertyNames(attributes).forEach((name) => { 26 | const nameNoNs = splitNsName(name)[1]; 27 | const value = attributes[name]; 28 | 29 | cssSelector.addAttribute(nameNoNs, value); 30 | if (name.toLowerCase() === 'class') { 31 | const classes = value.trim().split(/\s+/); 32 | classes.forEach((className) => cssSelector.addClassName(className)); 33 | } 34 | }); 35 | 36 | return cssSelector as any; 37 | } 38 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "测试(jasmine)-library", 9 | "type": "node", 10 | "request": "launch", 11 | "cwd": "${workspaceRoot}", 12 | "runtimeExecutable": "npm", 13 | "runtimeArgs": ["run-script", "test", "library"], 14 | "port": 7899 15 | }, 16 | { 17 | "name": "测试(jasmine)-browser", 18 | "type": "node", 19 | "request": "launch", 20 | "cwd": "${workspaceRoot}", 21 | "runtimeExecutable": "npm", 22 | "runtimeArgs": ["run-script", "test", "builder-dev"], 23 | "port": 7899 24 | }, 25 | { 26 | "name": "测试(jasmine)-builder-prod", 27 | "type": "node", 28 | "request": "launch", 29 | "cwd": "${workspaceRoot}", 30 | "runtimeExecutable": "npm", 31 | "runtimeArgs": ["run-script", "test", "builder-prod"], 32 | "port": 7899 33 | }, 34 | { 35 | "name": "测试(jasmine)-browser-watch", 36 | "type": "node", 37 | "request": "launch", 38 | "cwd": "${workspaceRoot}", 39 | "runtimeExecutable": "npm", 40 | "runtimeArgs": ["run-script", "test", "watch"], 41 | "port": 7899 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /src/builder/platform/template/app-template.js: -------------------------------------------------------------------------------- 1 | const obj = { 2 | Zone: typeof Zone !== 'undefined' && Zone, 3 | setTimeout: typeof setTimeout !== 'undefined' && setTimeout, 4 | clearTimeout: 5 | typeof clearTimeout !== 'undefined' && 6 | function (id) { 7 | return clearTimeout(id); 8 | }, 9 | setInterval: typeof setInterval !== 'undefined' && setInterval, 10 | clearInterval: 11 | typeof clearInterval !== 'undefined' && 12 | function (id) { 13 | return clearInterval(id); 14 | }, 15 | Promise: typeof Promise !== 'undefined' && Promise, 16 | Reflect: typeof Reflect !== 'undefined' && Reflect, 17 | requestAnimationFrame: 18 | typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame, 19 | cancelAnimationFrame: 20 | typeof cancelAnimationFrame !== 'undefined' && 21 | function (id) { 22 | return cancelAnimationFrame(id); 23 | }, 24 | performance: typeof performance !== 'undefined' && performance, 25 | navigator: typeof navigator !== 'undefined' && navigator, 26 | // 来自 queue-microtask 因为引入太麻烦直接复制了 27 | queueMicrotask:typeof queueMicrotask === 'function' 28 | ? queueMicrotask.bind(typeof window !== 'undefined' ? window : global) 29 | // reuse resolved promise, and allocate it lazily 30 | : cb => (promise || (promise = Promise.resolve())) 31 | .then(cb) 32 | .catch(err => setTimeout(() => { throw err }, 0)) 33 | }; 34 | -------------------------------------------------------------------------------- /test/hello-world-app/src/spec-component/life-time/life-time.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { MiniProgramComponentInstance } from 'angular-miniprogram/platform/type'; 3 | 4 | @Component({ 5 | selector: 'app-life-time', 6 | template: '', 7 | }) 8 | export class LifeTimeComponent implements OnInit { 9 | static mpComponentOptions: WechatMiniprogram.Component.Options<{}, {}, {}> = { 10 | lifetimes: { 11 | created: function (this: MiniProgramComponentInstance) { 12 | console.log('created', this.__isLink); 13 | }, 14 | attached: function () { 15 | console.log('attached', this.__isLink); 16 | }, 17 | ready: function () { 18 | console.log('ready'); 19 | }, 20 | moved: function () { 21 | console.log('moved'); 22 | }, 23 | detached: function () { 24 | console.log('detached'); 25 | }, 26 | error: function () { 27 | console.log('error'); 28 | }, 29 | }, 30 | pageLifetimes: { 31 | show: function () { 32 | console.log('page-show'); 33 | }, 34 | hide: function () { 35 | console.log('page-hide'); 36 | }, 37 | resize: function () { 38 | console.log('page-resize'); 39 | }, 40 | }, 41 | }; 42 | constructor() {} 43 | 44 | ngOnInit() { 45 | console.log('ngOnInit'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /deploy/doc/_layouts/post.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% seo %} 11 | {% include head-custom.html %} 12 | 13 | 14 |
15 | 20 |
21 |

{{ page.title | default: site.title | default: site.github.repository_name }}

22 | 23 | 24 | 25 | 26 |
27 |
{{ content }}
28 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /src/builder/mini-program-compiler/parse-node/interface.ts: -------------------------------------------------------------------------------- 1 | import type { MatchedComponent, MatchedDirective } from './type'; 2 | 3 | export interface ParsedNode { 4 | kind: NgNodeKind; 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 6 | parent: ParsedNode | undefined; 7 | getNodeMeta(): T; 8 | index: number; 9 | } 10 | export enum NgNodeKind { 11 | Element, 12 | BoundText, 13 | Text, 14 | Template, 15 | Content, 16 | } 17 | export interface NgNodeMeta { 18 | kind: NgNodeKind; 19 | index: number; 20 | } 21 | export interface NgElementMeta extends NgNodeMeta { 22 | kind: NgNodeKind.Element; 23 | tagName: string; 24 | children: NgNodeMeta[]; 25 | attributes: Record; 26 | inputs: string[]; 27 | outputs: string[]; 28 | singleClosedTag: boolean; 29 | componentMeta: MatchedComponent | undefined; 30 | directiveMeta: MatchedDirective | undefined; 31 | } 32 | export interface NgBoundTextMeta extends NgNodeMeta { 33 | kind: NgNodeKind.BoundText; 34 | } 35 | export interface NgTextMeta extends NgNodeMeta { 36 | kind: NgNodeKind.Text; 37 | value: string; 38 | } 39 | 40 | export interface NgTemplateMeta extends NgNodeMeta { 41 | kind: NgNodeKind.Template; 42 | children: NgNodeMeta[]; 43 | defineTemplateName: string; 44 | } 45 | export interface NgContentMeta extends NgNodeMeta { 46 | kind: NgNodeKind.Content; 47 | name: string | undefined; 48 | } 49 | -------------------------------------------------------------------------------- /src/builder/util/raw-updater.spec.ts: -------------------------------------------------------------------------------- 1 | import { DeleteChange, InsertChange, ReplaceChange } from 'cyia-code-util'; 2 | import { RawUpdater } from './raw-updater'; 3 | 4 | const originContent = '123456789'; 5 | describe('raw-updater', () => { 6 | it('default', () => { 7 | const result = RawUpdater.update(originContent, []); 8 | expect(result).toBe(originContent); 9 | }); 10 | it('insert', () => { 11 | const result = RawUpdater.update(originContent, [ 12 | new InsertChange(0, '000'), 13 | new InsertChange(5, '000'), 14 | new InsertChange(8, '000'), 15 | ]); 16 | expect(result).toBe(`000123450006780009`); 17 | }); 18 | it('delete', () => { 19 | const result = RawUpdater.update(originContent, [ 20 | new DeleteChange(0, 1), 21 | new DeleteChange(5, 1), 22 | new DeleteChange(8, 1), 23 | ]); 24 | expect(result).toBe(`234578`); 25 | }); 26 | it('replace', () => { 27 | const result = RawUpdater.update(originContent, [ 28 | new ReplaceChange(0, 1, '000'), 29 | new ReplaceChange(5, 1, '000'), 30 | new ReplaceChange(8, 1, '000'), 31 | ]); 32 | expect(result).toBe(`000234500078000`); 33 | }); 34 | it('混合', () => { 35 | const result = RawUpdater.update(originContent, [ 36 | new InsertChange(0, '000'), 37 | new DeleteChange(5, 1), 38 | new ReplaceChange(8, 1, '000'), 39 | ]); 40 | expect(result).toBe(`0001234578000`); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/hello-world-app/src/__pages/default-structural-directive/default-structural-directive.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-default-structural-directive', 5 | templateUrl: './default-structural-directive.component.html', 6 | styleUrls: ['./default-structural-directive.component.css'], 7 | }) 8 | export class DefaultStructuralDirectiveComponent implements OnInit { 9 | flag = { 10 | if: true, 11 | ifElse: true, 12 | ifDefault: true, 13 | }; 14 | list = [0, 1, 2]; 15 | ngSwitchValue: boolean | number = 0; 16 | ngSwitchValueList = [0, 1, 2]; 17 | ngSwitchValueIndex = 0; 18 | constructor() {} 19 | 20 | ngOnInit() {} 21 | ngIfControl() { 22 | this.flag.if = !this.flag.if; 23 | } 24 | ngIfElseControl() { 25 | this.flag.ifElse = !this.flag.ifElse; 26 | } 27 | ngIfDefault() { 28 | this.flag.ifDefault = !this.flag.ifDefault; 29 | } 30 | addList() { 31 | this.list.push(this.list.length); 32 | this.list = this.list.slice(); 33 | } 34 | removeList() { 35 | this.list.pop(); 36 | this.list = this.list.slice(); 37 | } 38 | changeSwitch() { 39 | this.ngSwitchValueIndex = 40 | this.ngSwitchValueList.length === this.ngSwitchValueIndex + 1 41 | ? 0 42 | : ++this.ngSwitchValueIndex; 43 | this.ngSwitchValue = this.ngSwitchValueList[this.ngSwitchValueIndex]; 44 | console.log(this.ngSwitchValue); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/hello-world-app/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['@angular-devkit/build-angular'], 8 | plugins: [ 9 | // require('karma-coverage'), 10 | require('../../src/builder/karma/plugin/index'), 11 | ], 12 | client: { 13 | jasmine: { 14 | // you can add configuration options for Jasmine here 15 | // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html 16 | // for example, you can disable the random execution with `random: false` 17 | // or set a specific seed with `seed: 4321` 18 | }, 19 | clearContext: false, // leave Jasmine Spec Runner output visible in browser 20 | }, 21 | jasmineHtmlReporter: { 22 | suppressAll: true, // removes the duplicated traces 23 | }, 24 | coverageReporter: { 25 | dir: require('path').join(__dirname, './coverage/ng13-demo'), 26 | subdir: '.', 27 | reporters: [{ type: 'html' }, { type: 'text-summary' }], 28 | }, 29 | reporters: ['progress'], 30 | port: 9876, 31 | colors: true, 32 | logLevel: config.LOG_INFO, 33 | autoWatch: true, 34 | browsers: ['miniprogram'], 35 | singleRun: false, 36 | restartOnFileChange: true, 37 | captureTimeout: 300_000, 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /tsconfig.library.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | // "files": ["./src/library/index.ts"], 4 | "include": [ 5 | "./src/library" 6 | ], 7 | "compilerOptions": { 8 | "baseUrl": "./src/library", 9 | "noImplicitThis": true, 10 | "outDir": "dist", 11 | "declaration": true, 12 | "target": "ES2015", 13 | "module": "esnext", 14 | "strict": true, 15 | "useUnknownInCatchVariables": false, 16 | "lib": [ 17 | "es2019", 18 | "dom" 19 | ], 20 | "typeRoots": [ 21 | "./src/library" 22 | ], 23 | "types": [ 24 | "declaration" 25 | ], 26 | "paths": { 27 | "angular-miniprogram/platform/default": [ 28 | "./platform/default/index.ts" 29 | ], 30 | "angular-miniprogram/platform/wx": [ 31 | "./platform/wx/index.ts" 32 | ], 33 | "angular-miniprogram/platform/type": [ 34 | "./platform/type/index.ts" 35 | ], 36 | "angular-miniprogram/platform": [ 37 | "./platform/index.ts" 38 | ], 39 | "angular-miniprogram/common": [ 40 | "./common/index.ts" 41 | ], 42 | "angular-miniprogram/common/http": [ 43 | "./common/http/index.ts" 44 | ], 45 | } 46 | }, 47 | "exclude": [ 48 | "./src/**/*.template.ts", 49 | "./src/**/*.d.ts", 50 | "**/*.spec.ts", 51 | "test" 52 | ], 53 | "angularCompilerOptions": { 54 | "enableIvy": true, 55 | "compilationMode": "full" 56 | } 57 | } -------------------------------------------------------------------------------- /deploy/doc/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://mirrors.tuna.tsinghua.edu.cn/rubygems/" 2 | # Hello! This is where you manage which Jekyll version is used to run. 3 | # When you want to use a different version, change it below, save the 4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 5 | # 6 | # bundle exec jekyll serve 7 | # 8 | # This will help ensure the proper Jekyll version is running. 9 | # Happy Jekylling! 10 | #gem "jekyll", "~> 4.2.2" 11 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 12 | gem "minima", "~> 2.5" 13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 14 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 15 | gem "github-pages", "~> 226", group: :jekyll_plugins 16 | 17 | # If you have any plugins, put them here! 18 | group :jekyll_plugins do 19 | gem "jekyll-feed", "~> 0.12" 20 | end 21 | 22 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem 23 | # and associated library. 24 | platforms :mingw, :x64_mingw, :mswin, :jruby do 25 | gem "tzinfo", "~> 1.2" 26 | gem "tzinfo-data" 27 | end 28 | 29 | # Performance-booster for watching directories on Windows 30 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] 31 | 32 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem 33 | # do not have a Java counterpart. 34 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] 35 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | env: 8 | REPOSITORY_PATH: https://${{secrets.ACCESS_TOKEN}}@github.com/ 9 | # GITHUB_TOKEN: ${{secrets.ACCESS_TOKEN}} 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: init 15 | run: | 16 | git config --global user.name "${GITHUB_ACTOR}" 17 | git config --global user.email "${GITHUB_ACTOR}@gmail.com" 18 | - name: pull-code 19 | uses: actions/checkout@v2 20 | - name: install-node 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: 16.x 24 | cache: "npm" 25 | - name: install-dependencies 26 | run: | 27 | npm ci --legacy-peer-deps 28 | - name: hook-code 29 | run: | 30 | npm run sync 31 | - name: build-docs 32 | continue-on-error: true 33 | run: | 34 | npm run deploy 35 | cp -rp docs/ ../dist 36 | git branch gh-pages 37 | git checkout gh-pages 38 | rm -rf * 39 | cp -rp ../dist/* . 40 | cp ./index.html 404.html 41 | env: 42 | INPUT_TOKEN: '' 43 | - name: tag 44 | run: | 45 | git status 46 | git add -A 47 | HUSKY=0 git commit -m 'build: 页面构建' 48 | HUSKY=0 git push --force "${REPOSITORY_PATH}${GITHUB_REPOSITORY}.git" gh-pages 49 | # git pull 50 | -------------------------------------------------------------------------------- /test/hello-world-app/src/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "miniprogramRoot": "/", 7 | "compileType": "miniprogram", 8 | "libVersion": "2.8.2", 9 | "projectname": "miniprogram-1", 10 | "scripts": { 11 | "beforeCompile": "", 12 | "beforePreview": "", 13 | "beforeUpload": "" 14 | }, 15 | "setting": { 16 | "urlCheck": true, 17 | "es6": false, 18 | "enhance": false, 19 | "postcss": false, 20 | "preloadBackgroundData": false, 21 | "minified": false, 22 | "newFeature": false, 23 | "coverView": true, 24 | "nodeModules": false, 25 | "autoAudits": false, 26 | "showShadowRootInWxmlPanel": false, 27 | "scopeDataCheck": false, 28 | "uglifyFileName": false, 29 | "checkInvalidKey": true, 30 | "checkSiteMap": true, 31 | "uploadWithSourceMap": true, 32 | "compileHotReLoad": false, 33 | "useMultiFrameRuntime": true, 34 | "useApiHook": true, 35 | "useApiHostProcess": true, 36 | "babelSetting": { 37 | "ignore": [], 38 | "disablePlugins": [], 39 | "outputPath": "" 40 | }, 41 | "enableEngineNative": false, 42 | "useIsolateContext": true, 43 | "useCompilerModule": true, 44 | "userConfirmedUseCompilerModuleSwitch": false, 45 | "userConfirmedBundleSwitch": false, 46 | "packNpmManually": false, 47 | "packNpmRelationList": [], 48 | "minifyWXSS": false 49 | }, 50 | "simulatorType": "wechat", 51 | "simulatorPluginLibVersion": {}, 52 | "appid": "touristappid", 53 | "condition": {} 54 | } 55 | --------------------------------------------------------------------------------