Angular 5 - 如何生成定义文件
Angular 5 - How to generate definition files
我已经尝试了几种方法,但我无法理解如何为我的项目生成定义文件。我有两个 angular-cli 生成的应用程序 A 和 B,我希望 A 将 B 作为一个包使用(使用 npm link)。据我了解,我需要在项目 B 中创建一个 index.ts 文件,其中包含我要导出的所有模块和 运行 'ng build' 命令。我已经看到只创建包而不创建定义文件,如何生成定义文件?这是正确的做法吗?
我尝试了一些其他选项,例如 'rollup' 和 'ngmakelib',但似乎很难完成这个简单的任务。我们是否有一种简单的方法来生成 Angular 5 个项目作为库并使用来自其他项目的库?
在高层次上,以下是创建可重用 Angular 模块所需执行的步骤(全部在没有 webpack 的情况下完成):
在您的 src
文件夹中创建一个 public_api.ts
文件。这应该包含所有导出的符号,以便您的库的用户可以执行:import { symbol } from 'your-library'
将您的 src
文件夹复制到 build/dist
文件夹,确保内联您的模板。我为此使用 gulp
和 gulp-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 ...
- 为
ngc
创建一个 tsconfig 文件。您将使用 ngc
生成必要的元数据文件。这是我使用的设置。该文件位于 "build" 文件夹中(注意 typeRoots
和 paths
的相对路径)。
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)。
使用ngc
从构建文件夹编译模块。确保安装 @angular/compiler
和 @angular/compiler-cli
:
../node_modules/.bin/ngc -p tsconfig.json
只部署需要的文件。我从 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();
});
});
});
确保将 package.json 修改为指向 index.js:
{
"name": "ng-module-template",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
}
可选:创建捆绑包
这里是一个 gulp 构建目标,用于使用带有 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 (installed locally if you are publishing to a local folder)
https://github.com/angular-patterns/ng-module-template
构建目标
npm 运行dev
为了发展
npm 运行 构建
用于生产应用程序构建(输出到 dist 文件夹)
npm 运行 构建模块
对于模块构建(输出到 dist 文件夹)
npm 运行 发布
使用 git 发布到 c:\packages
。或者,运行 npm publish
发布到 npm
.
npm 运行 name-module -- --(module-name)
用于命名模块。这修改了源。
从 c:\packages 安装
npm install c:\packages\<module-name>
我已经尝试了几种方法,但我无法理解如何为我的项目生成定义文件。我有两个 angular-cli 生成的应用程序 A 和 B,我希望 A 将 B 作为一个包使用(使用 npm link)。据我了解,我需要在项目 B 中创建一个 index.ts 文件,其中包含我要导出的所有模块和 运行 'ng build' 命令。我已经看到只创建包而不创建定义文件,如何生成定义文件?这是正确的做法吗?
我尝试了一些其他选项,例如 'rollup' 和 'ngmakelib',但似乎很难完成这个简单的任务。我们是否有一种简单的方法来生成 Angular 5 个项目作为库并使用来自其他项目的库?
在高层次上,以下是创建可重用 Angular 模块所需执行的步骤(全部在没有 webpack 的情况下完成):
在您的
src
文件夹中创建一个public_api.ts
文件。这应该包含所有导出的符号,以便您的库的用户可以执行:import { symbol } from 'your-library'
将您的
src
文件夹复制到build/dist
文件夹,确保内联您的模板。我为此使用gulp
和gulp-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 ...
- 为
ngc
创建一个 tsconfig 文件。您将使用ngc
生成必要的元数据文件。这是我使用的设置。该文件位于 "build" 文件夹中(注意typeRoots
和paths
的相对路径)。
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)。
使用
ngc
从构建文件夹编译模块。确保安装@angular/compiler
和@angular/compiler-cli
:../node_modules/.bin/ngc -p tsconfig.json
只部署需要的文件。我从
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(); }); }); });
确保将 package.json 修改为指向 index.js:
{ "name": "ng-module-template", "version": "1.0.0", "description": "", "main": "dist/index.js", "typings": "dist/index.d.ts", }
可选:创建捆绑包
这里是一个 gulp 构建目标,用于使用带有 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 (installed locally if you are publishing to a local folder)
https://github.com/angular-patterns/ng-module-template
构建目标
npm 运行dev
为了发展
npm 运行 构建
用于生产应用程序构建(输出到 dist 文件夹)
npm 运行 构建模块
对于模块构建(输出到 dist 文件夹)
npm 运行 发布
使用 git 发布到 c:\packages
。或者,运行 npm publish
发布到 npm
.
npm 运行 name-module -- --(module-name)
用于命名模块。这修改了源。
从 c:\packages 安装
npm install c:\packages\<module-name>