Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement official Angular Package Format #60

Merged
merged 19 commits into from
Apr 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 59 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@

If you want to create an Angular library with directives, services and/or pipes, then this generator is just what you need.

The generator:
This generator aligns with the [official Angular Package Format](https://goo.gl/AMOU5G) and automatically generates a [Flat ES Module](http://angularjs.blogspot.be/2017/03/angular-400-now-available.html), a single metadata.json and type definitions to make your library ready for AOT compilation by the consuming Angular application.

- creates and configures `package.json` for your library
- creates and configures `tsconfig.json` for your library
- creates and configures `tslint.json` for your library
Watch [Jason Aden's talk](https://www.youtube.com/watch?v=unICbsPGFIA) to learn more about the Angular Package Format.

More specifically, this generator:

- creates and configures `package.json` for the development of your library
- creates and configures a second `package.json` for the distribution of your library
- creates and configures `tsconfig.json` for your editor during development
- creates and configures `tslint.json` for linting purposes
- creates and configures `.gitignore`, `.npmignore` and `.travis.yml`
- creates the main library file
- creates a sample directive, component, service and pipe
- creates a default export for future compatibility with angular cli, see this [discussion for more](https://github.com/angular/angular-cli/issues/96)
- creates the main library file, a sample directive, a sample component, a sample service and a sample pipe
- configures [tslint](https://palantir.github.io/tslint/) for you with [codelyzer](https://github.com/mgechev/codelyzer) support
- supports [@types](https://www.npmjs.com/~types)
- creates and configures build scripts to generate type definitions and metadata files to make library ready for AOT compilation

This generator is built for Angular version 2 and above, hence the name generator-angular2-library. If you are looking for a similar generator for AngularJS 1.x, please visit [generator-angularjs-library](https://github.com/jvandemo/generator-angularjs-library).

Expand Down Expand Up @@ -57,34 +60,65 @@ and create the following files for you:
```bash
.
├── README.MD
├── index.ts
├── build.sh
├── package.json
├── src
│   ├── index.ts
│   ├── package.json
│   ├── sample.component.ts
│   ├── sample.directive.ts
│   ├── sample.pipe.ts
│   └── sample.service.ts
│   ├── sample.service.ts
│   └── tsconfig.es5.json
├── tsconfig.json
├── tslint.json
└── typings.json
└── tslint.json
```

You can then add or edit `*.ts` files in the `src/` directory and run:

```bash
$ npm run tsc
$ npm run build
```

to automatically create all `*.js`, `*.js.map` and `*.d.ts` files in the `dist/` directory.
to automatically create all `*.js`, `*.d.ts` and `*.metadata.json` files in the `dist/` directory.

## Tslint
## Linting your code

Everything comes pre-configured with tslint and codelyzer support. To lint your code:

```bash
$ npm run lint
```

## Building your library

From the root of your library directory, run:

```bash
$ npm run build
```

This will generate a `dist` directory with:

- a `package.json` file specifically for distribution with Angular listed in the `peerDependencies`
- `sample-library.js`: a Flat ES Module (FESM) file that contains all your library code in a single file
- `*.d.ts`: type definitions for you library
- `sample-library.metadata.json`: metadata for your library to support AOT compilation

## Publishing your library to NPM

To publish your library to NPM, first generate the `dist` directory:

```bash
$ npm run build
```

and then publish the contents of the `dist` directory to NPM:

```bash
$ npm publish dist
```

## Consuming your library

Once you have published your library to the NPM registry, you can import it in any Angular application by first installing it using NPM:
Expand Down Expand Up @@ -170,11 +204,12 @@ To consume your library before you publish it to npm, you can follow the followi

3. Compile your library files:
```
$ npm run tsc
$ npm run build
```

4. From the `sample-library` directory, create a symlink in the global node_modules directory to this library:
4. From the `sample-library/dist` directory, create a symlink in the global node_modules directory to the `dist` directory of your library:
```
$ cd dist
$ npm link
```

Expand Down Expand Up @@ -254,10 +289,9 @@ To consume your library before you publish it to npm, you can follow the followi

10. When you make a change to your library, recompile your library files again from your `sample-library` directory:
```
$ npm run tsc
```
$ npm run build
```


## To do

- Create process for running unit tests
Expand All @@ -280,6 +314,11 @@ MIT © [Jurgen Van de Moere](http://www.jvandemo.com)

## Change log

### v8.0.0

- Update build process
- Add support for AOT compilation

### v7.0.0

- Update to Angular 4
Expand Down
36 changes: 27 additions & 9 deletions generators/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ module.exports = class extends Generator {
this.destinationPath('.travis.yml')
);

// Copy src folder
this.fs.copy(
this.templatePath('src/**/*'),
this.destinationPath('src')
);

// Copy tsconfig.json
this.fs.copyTpl(
this.templatePath('_tsconfig.json'),
Expand Down Expand Up @@ -143,10 +137,34 @@ module.exports = class extends Generator {
}
);

// Copy index.ts
// Copy build.sh
this.fs.copyTpl(
this.templatePath('build.sh'),
this.destinationPath('build.sh'),
{
props: this.props
}
);

// Copy src folder
this.fs.copy(
this.templatePath('src/**/*.ts'),
this.destinationPath('src')
);

// Copy src/package.json
this.fs.copyTpl(
this.templatePath('src/_package.json'),
this.destinationPath('src/package.json'),
{
props: this.props
}
);

// Copy src/tsconfig.es5.json
this.fs.copyTpl(
this.templatePath('index.ts'),
this.destinationPath('index.ts'),
this.templatePath('src/_tsconfig.es5.json'),
this.destinationPath('src/tsconfig.es5.json'),
{
props: this.props
}
Expand Down
4 changes: 2 additions & 2 deletions generators/app/templates/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ Once your library is imported, you can use its components, directives and pipes

## Development

To generate all `*.js`, `*.js.map` and `*.d.ts` files:
To generate all `*.js`, `*.d.ts` and `*.metadata.json` files:

```bash
$ npm run tsc
$ npm run build
```

To lint all `*.ts` files:
Expand Down
11 changes: 4 additions & 7 deletions generators/app/templates/_package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
"name": "<%= props.libraryName.kebabCase %>",
"version": "0.1.0",
"scripts": {
"build": "ngc -p tsconfig.json",
"build": "./build.sh",
"lint": "tslint --type-check --project tsconfig.json src/**/*.ts",
"test": "tsc && karma start",
"prepublish": "tsc",
"tsc": "tsc"
"prepublish": "echo \"Publish aborted: please run 'npm publish' from the dist directory\" && exit 1"
},
"repository": {
"type": "git",
Expand All @@ -23,9 +22,6 @@
"bugs": {
"url": "<%= props.gitRepositoryUrl %>/issues"
},
"main": "./dist/index.js",
"dependencies": {
},
"devDependencies": {
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
Expand All @@ -42,10 +38,11 @@
"karma": "~1.4.1",
"karma-chrome-launcher": "~2.0.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^0.2.0",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-coverage-istanbul-reporter": "^0.2.0",
"protractor": "~5.1.0",
"rollup": "^0.41.6",
"rxjs": "^5.1.0",
"ts-node": "~2.0.0",
"tslint": "~4.5.0",
Expand Down
32 changes: 12 additions & 20 deletions generators/app/templates/_tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
// This file is only used to configure the editor during development.
// It is NOT used for building the library.
{
"compilerOptions": {
"noImplicitAny": true,
"module": "commonjs",
"target": "ES6",
"emitDecoratorMetadata": true,
"baseUrl": "./src",
"experimentalDecorators": true,
"allowUnusedLabels": false,
"noImplicitReturns": true,
"sourceMap": true,
"declaration": true,
"outDir": "./dist",
"typeRoots": [
"node_modules/@types"
]
},
"exclude": [
"node_modules",
"dist",
"**/*.spec.ts"
],
"angularCompilerOptions": {
"strictMetadataEmit": true
"moduleResolution": "node",
"rootDir": "./src",
"lib": [
"es2015",
"dom"
],
"skipLibCheck": true,
// Don't auto-discover @types/node, it results in a ///<reference in the .d.ts output
"types": []
}
}
22 changes: 22 additions & 0 deletions generators/app/templates/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Clean up previous build files
rm -rf build
rm -rf dist

# Define commands
NGC="node node_modules/.bin/ngc"
ROLLUP="node node_modules/.bin/rollup"

# Run Angular Compiler to generate build directory
$NGC -p src/tsconfig.es5.json

# Run rollup to generate dist directory
$ROLLUP build/index.js -o dist/index.js

# Copy all files from build to dist, except for JavaScript files
rsync -a --exclude=*.js build/ dist

# Copy package.json to dist
cp src/package.json dist/package.json

# Clean up build directory
rm -rf build
7 changes: 7 additions & 0 deletions generators/app/templates/npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,10 @@ Desktop.ini
# Mac
.DS_Store
**/.DS_Store

# Ngc generated files
**/*.ngfactory.ts

# Library files
src/*
build/*
26 changes: 26 additions & 0 deletions generators/app/templates/src/_package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "<%= props.libraryName.kebabCase %>",
"version": "0.1.0",
"repository": {
"type": "git",
"url": "<%= props.gitRepositoryUrl %>"
},
"author": {
"name": "<%= props.author.name %>",
"email": "<%= props.author.email %>"
},
"keywords": [
"angular"
],
"license": "MIT",
"bugs": {
"url": "<%= props.gitRepositoryUrl %>/issues"
},
"module": "<%= props.libraryName.kebabCase %>.js",
"typings": "<%= props.libraryName.kebabCase %>.d.ts",
"peerDependencies": {
"@angular/core": "^4.0.0",
"rxjs": "^5.1.0",
"zone.js": "^0.8.4"
}
}
32 changes: 32 additions & 0 deletions generators/app/templates/src/_tsconfig.es5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// This file is used by ngc to create the files in the build directory
{
"compilerOptions": {
"declaration": true,
"module": "es2015",
"target": "es5",
"baseUrl": ".",
"stripInternal": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"outDir": "../build",
"rootDir": ".",
"lib": [
"es2015",
"dom"
],
"skipLibCheck": true,
// Don't auto-discover @types/node, it results in a ///<reference in the .d.ts output
"types": []
},
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"skipTemplateCodegen": true,
"flatModuleOutFile": "<%= props.libraryName.kebabCase %>.js",
"flatModuleId": "<%= props.libraryName.kebabCase %>"
},
"files": [
"./index.ts"
]
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SampleComponent } from './src/sample.component';
import { SampleDirective } from './src/sample.directive';
import { SamplePipe } from './src/sample.pipe';
import { SampleService } from './src/sample.service';
import { SampleComponent } from './sample.component';
import { SampleDirective } from './sample.directive';
import { SamplePipe } from './sample.pipe';
import { SampleService } from './sample.service';

export * from './src/sample.component';
export * from './src/sample.directive';
export * from './src/sample.pipe';
export * from './src/sample.service';
export * from './sample.component';
export * from './sample.directive';
export * from './sample.pipe';
export * from './sample.service';

@NgModule({
imports: [
Expand Down
Loading