【问题标题】:Angular 5 - How to generate definition filesAngular 5 - 如何生成定义文件
【发布时间】:2018-04-28 23:50:38
【问题描述】:

我一直在尝试几种方法,但我无法理解如何为我的项目生成定义文件。我有两个 angular-cli 生成的应用程序 A 和 B,我希望 A 将 B 作为一个包使用(带有 npm 链接)。据我了解,我需要在项目 B 中创建一个 index.ts 文件,其中包含我要导出的所有模块并运行“ng build”命令。我已经看到只创建捆绑包而不创建定义文件,我怎样才能生成定义文件?这是正确的方法吗?

我已经尝试了一些其他选项,例如“rollup”和“ngmakelib”,但似乎很难完成这个简单的任务。我们是否有一种简单的方法可以将 Angular 5 项目生成为库并从其他项目中使用这些库?

【问题讨论】:

  • 为什么不能使用 ngmakelib?它应该很简单:ngmakelib src/app/mymodule/mymodule.module.ts mymodule-library 然后您应该能够在生成的 tar.gz 文件上使用 npm install。
  • @PeterSalomonsen 这没用,因为我需要安装 tar.gz 文件,我想使用“npm link”,所以如果库更改所有组件将在使用“npm install”时选择最新更改"
  • 好的,如果输出是文件夹而不是 tar.gz,它会起作用吗?
  • 我不记得为什么我拒绝使用ngmakelib,我猜是因为它不使用rollup,这就是我最终使用ngpackgr的原因
  • 它确实使用汇总。不过没有压力。只是好奇为什么它不起作用。

标签: angular angular5 npm-link


【解决方案1】:

概括地说,以下是创建可重用 Angular 模块所需执行的步骤(所有这些都无需 webpack 完成):

  1. 在您的 src 文件夹中创建一个 public_api.ts 文件。这应该包含您导出的所有符号,以便您库的用户可以执行以下操作:import { symbol } from 'your-library'

  2. 将您的 src 文件夹复制到 build/dist 文件夹,确保内联您的模板。我为此使用gulpgulp-inline-ng2-template

gulpfile.js

    const gulp = require('gulp');
    const replace = require('gulp-replace');
    const inlineNg2Template = require('gulp-inline-ng2-template');
    const del = require('del');

    gulp.task('clean', function () {
        return del([
           "dist/**"
        ], { force: true });
    });


    gulp.task('copy-public-api', ['clean'], function () {
        return gulp.src([
            '../src/public_api.ts'
        ])
        .pipe(replace('./app', './src'))
        .pipe(gulp.dest('dist'))

    });
    gulp.task('copy-src', ['copy-public-api'], function () {
        return gulp.src([
           '../src/app/**/*.ts',
           '!../src/app/**/*.spec.ts'
        ])
        .pipe(inlineNg2Template({ base: '../src', useRelativePaths: true }))
        .pipe(gulp.dest('dist/src'))
    });

public_api.ts

    export * from './app/app.module';
    // ... other exports ...
  1. ngc 创建一个tsconfig 文件。您将使用ngc 生成必要的元数据文件。这是我使用的设置。该文件位于“build”文件夹中(注意typeRootspaths 的相对路径)。

build/tsconfig.json

    {
        "compilerOptions": {
            "baseUrl": ".",
            "rootDir": ".",
            "outDir": "",
            "paths": {
                "*": [
                    "../node_modules/*"
                ]
            },             
            "declaration": true,
            "stripInternal": true,
            "noImplicitAny": true,
            "strictNullChecks": true,
            "noFallthroughCasesInSwitch": true,
            "moduleResolution": "node",
            "module": "es2015",
            "target": "es5",
            "lib": [
                "es2015",
                "dom"
            ],
            "skipLibCheck": true,
            "typeRoots": [     
                "../node_modules/@types/"  
            ], 
            "experimentalDecorators": true,
            "emitDecoratorMetadata": true,
            "sourceMap": true,
            "inlineSources": true
        },
        "files": [
            "dist/public_api.ts"
        ],
        "angularCompilerOptions": {
            "annotateForClosureCompiler": true,
            "strictMetadataEmit": false,
            "skipTemplateCodegen": true,
            "flatModuleOutFile": "index.js",
            "flatModuleId": "ng-module-template"
        }    

    }

angularCompilerOptions 确保创建一个元数据文件 (index.js)。

  1. 使用ngc 从构建文件夹编译模块。确保安装@angular/compiler@angular/compiler-cli:

    ../node_modules/.bin/ngc -p tsconfig.json
    
  2. 仅部署需要的文件。我从build\dist 部署到dist

    gulp.task('build', [], function (done) {
        gulp.src([
            'dist/index.js',
            'dist/public_api.js',
            'dist/index.metadata.json',
            'dist/**/*.d.ts',
            '!../src/app/**/*.spec.ts'
        ], { base: 'dist' })
            .pipe(gulp.dest('../dist'))
            .on('end', function () {
                del('dist/**', { force: true }).then(function () {
                    done();
                });
            });
    });
    
  3. 确保修改你的 package.json 以指向 index.js:

    {
      "name": "ng-module-template",
      "version": "1.0.0",
      "description": "",
      "main": "dist/index.js",
      "typings": "dist/index.d.ts",
    }
    

可选:创建捆绑包

这是一个 gulp 构建目标,用于使用 rollup 和 treeshaking 编译和创建包:

gulp.task('compile', ['copy-src'], function (done) {
    gulp.src('tsconfig.json')
        .pipe(shell(['"../node_modules/.bin/ngc" -p <%= file.path %>']))
        .on('end', function () {
            del('node_modules/**', { force: true }).then(function () {
                done();
            });
        });
});

gulp.task('bundle', ['compile'], function (done) {
    var external = [
        '@angular/core',
        '@angular/common',
        '@angular/compiler',
        '@angular/core',
        '@angular/http',
        '@angular/platform-browser',
        '@angular/platform-browser-dynamic',
        '@angular/router',
        '@angular/router-deprecated'
    ];

    var globals = {
        '@angular/core': 'vendor._angular_core',
        '@angular/http': 'vendor._angular_http',
        '@angular/platform-browser': 'vendor._angular_platformBrowser',
        '@angular/platform-browser-dynamic': 'vendor._angular_platformBrowserDynamic',
        '@angular/router-deprecated': 'vendor._angular_routerDeprecated'
    };

    rollup.rollup({
        input: 'dist/index.js',
        onwarn: function (warning) {
            if (warning.message.indexOf("treating it as an external dependency") > -1)
                return;


            console.warn(warning.message);
        }

    }).then(function (bundle) {
        var umd = bundle.write({
            file: `dist/bundles/${pkg.name}.umd.js`,
            format: 'umd',
            exports: 'named',
            name: pkg.name,
            sourcemap: true,
            external: external,
            globals: globals
        });
        var cjs = bundle.write({
            file: `dist/bundles/${pkg.name}.cjs.js`,
            format: 'cjs',
            exports: 'named',
            name: pkg.name,
            sourcemap: true,
            external: external,
            globals: globals
        });
        var amd = bundle.write({
            file: `dist/bundles/${pkg.name}.amd.js`,
            format: 'amd',
            exports: 'named',
            name: pkg.name,
            sourcemap: true,
            external: external,
            globals: globals
        });

        var es = bundle.write({
            file: `dist/index.es5.js`,
            format: 'es',
            exports: 'named',
            name: pkg.name,
            sourcemap: true,
            external: external,
            globals: globals

        });

        return Promise.all([umd, cjs, amd, es]).then(function () {
            done();
        });

    });
});

源代码演示

先决条件

Angular5+
Git(如果您要发布到本地文件夹,则在本地安装)

https://github.com/angular-patterns/ng-module-template

构建目标

npm run dev

开发

npm 运行构建

用于生产应用构建(输出到 dist 文件夹)

npm 运行构建模块

对于模块构建(输出到 dist 文件夹)

npm 运行发布

使用 git 发布到c:\packages。或者,运行npm publish 发布到npm

npm run name-module -- --(module-name)

用于命名模块。这会修改源代码。

从 c:\packages 安装

npm install c:\packages\<module-name>

【讨论】:

  • 感谢您提供这么好的答案!我会尽快尝试,但我认为我需要将其适应 webpack,我正在尝试使用 angular-cli 生成的项目来做到这一点,而且它变得如此困难。
  • 链接 'ng-module-template' 中的生成器似乎无法正常工作,它向我显示了以下错误 'Unexpected value 'TestComponent' 由模块 'AppModule' 导入。请添加 NgModule 注释。'
  • 源码中没有TestComponent。你确定你克隆了 repo?
  • 我已经创建了自己的组件,你使用的是什么版本的 angular cli?
  • 据我所知,没有办法使用 Angular cli 创建可重用模块
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 2021-12-09
  • 2018-07-28
  • 1970-01-01
相关资源
最近更新 更多