├── .gitignore ├── LICENSE ├── README.md ├── package-dist.json ├── package.json ├── rollup.config.js ├── src ├── index.ts ├── seed.component.ts ├── seed.module.ts └── seed.service.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | dist 3 | node_modules 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 David Guijarro 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular NPM Module Seed 2 | ## What's this? 3 | This project intends to give an easy-to-use starter for developing and publishing an Angular NPM module, so that it then be installed through the regular `npm install` command by other users. 4 | 5 | The whole project is heavily inspired by [Cyrille Tuzi](https://github.com/cyrilletuzi), through his [How to build and publish an Angular module](https://medium.com/@cyrilletuzi/how-to-build-and-publish-an-angular-module-7ad19c0b4464#.qcwybm3pa) Medium post. 6 | 7 | ## Getting ready 8 | * `fork` this repo and change its name to match your module's 9 | * `clone` your fork 10 | * review the `package.json` file contents and include your name, your module's name and any other information you find necessary. Also, make sure the listed dependencies and their version numbers are what you need them to be 11 | 12 | > Don't pay attention to the `package-dist.json` file by now, we will get there later on. 13 | 14 | * `npm install` to install all dependencies or `yarn` 15 | 16 | ## Coding time! 17 | You'll probably want to write some awesome code now. 18 | 19 | The seed includes a sample module file (`seed.module.ts`), as well as a sample service (`seed.service.ts`) and a sample public component (`seed.component.ts`), to get you inspired. 20 | 21 | So now it's the time to either rename those files and the classes inside them to your liking, or ditching them and writing your stuff from scratch. 22 | 23 | ## Now compile it! 24 | Once you have some nice amount of code put into your services, components, filters..., it's probably a good time to compile your module and taste the rewards for your hard work. These are the steps: 25 | * open the `tsconfig.json` file and include in the `paths` value **all the modules** your project depends on, as the final bundle won’t include them directly 26 | * open the `rollup.config.js` file and change the following values 27 | ```js 28 | export default { 29 | // (...) 30 | dest: 'dist/bundles/npm-module-seed.umd.js', // change this to your module's name 31 | // (...) 32 | moduleName: 'ng.npm-module-seed', // change this to your module's name 33 | globals: { 34 | // Your module use Angular things (at least the NgModule decorator), 35 | // but your bundle should not include Angular. 36 | // So you need to set Angular as a global. And you need to know the UMD module 37 | // name for each module. It follows this convention: ng.modulename 38 | // Also, include the RXJS only if your module uses them. 39 | '@angular/core': 'ng.core', 40 | '@angular/common': 'ng.common', 41 | 'rxjs/Observable': 'Rx', 42 | 'rxjs/ReplaySubject': 'Rx', 43 | 'rxjs/add/operator/map': 'Rx.Observable.prototype', 44 | 'rxjs/add/operator/mergeMap': 'Rx.Observable.prototype', 45 | 'rxjs/add/observable/fromEvent': 'Rx.Observable', 46 | 'rxjs/add/observable/of': 'Rx.Observable' 47 | } 48 | } 49 | ``` 50 | * open the `package-dist.json` file (now is the right time to do it!) and change the details there. Keep in mind that **these details will only apply to the package you will publish to NPM.** Since we will only publish our generated `dist` folder, the building process will copy this file to the said folder and change its name. Make sure you include your module's dependencies (i.e. `@angular/core` and so on) as `peerDependencies`. 51 | * finally, `npm run build` will compile, tree-shake, uglify... your module's code into the `dist` folder. 52 | 53 | ## Use your code locally 54 | 55 | It would probably be a good idea to test your new module locally before publishing it to the NPM repository. 56 | 57 | I suggest creating a separate Angular project and importing your module into it. To do that, you'll need to run `npm link` inside your module's `dist` folder; then navigate to your testing project root and run `npm link {name-of-module}`. This will symlink your original module to the `node_modules` folder of your testing project. 58 | 59 | Just remember to run `npm run build` in your original module root folder so that its symlinked `dist` folder grabs the changes you make. 60 | 61 | ## Publish your awesome module (finally!) 62 | 63 | Once you're ready to publish your hard work so that the rest of us can take advantage of it, please follow this easy steps: 64 | * configure your NPM acount, if you haven't done it already, following [these instructions](https://docs.npmjs.com/getting-started/publishing-npm-packages) 65 | * navigate to your module's `dist` folder and run `npm publish` 66 | 67 | Anytime you need to update your module, just rebuild, change the version number and publish again. 68 | 69 | ## Other stuff 70 | ### To-do 71 | 72 | * Adding unit tests. 73 | * Explore using OpaqueTokens for referencing services. 74 | 75 | ### Get in touch 76 | 77 | Feel free to drop me a line if you have an issue, doubt, problem or suggestion, even just to tell me what you think. You can leave an issue here or give me a shout on [Twitter](http://twitter.com/davguij). 78 | 79 | ### License 80 | 81 | MIT 82 | -------------------------------------------------------------------------------- /package-dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-npm-module-seed", 3 | "version": "1.0.0", 4 | "description": "Wot!", 5 | "main": "bundles/npm-module-seed.umd.min.js", 6 | "module": "index.js", 7 | "typings": "index.d.ts", 8 | "keywords": [ 9 | "angular", 10 | "angular2", 11 | "angular 2" 12 | ], 13 | "author": { 14 | "name": "", 15 | "email": "" 16 | }, 17 | "license": "", 18 | "repository": { 19 | "type": "git", 20 | "url": "" 21 | }, 22 | "homepage": "", 23 | "bugs": { 24 | "url": "" 25 | }, 26 | "peerDependencies": { 27 | "@angular/core": "^2.4.0", 28 | "reflect-metadata": "^0.1.8", 29 | "rxjs": "^5.0.1", 30 | "zone.js": "^0.7.2" 31 | } 32 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-npm-module-seed", 3 | "version": "1.0.0", 4 | "description": "Starting point for developing Angular modules and publishing them on NPM", 5 | "keywords": [ 6 | "angular 2" 7 | ], 8 | "main": "index.js", 9 | "scripts": { 10 | "clean": "rimraf .tmp && rimraf dist", 11 | "transpile": "ngc", 12 | "package": "rollup -c", 13 | "minify": "./node_modules/uglify-js/bin/uglifyjs dist/bundles/npm-module-seed.umd.js --screw-ie8 --compress --mangle --comments --output dist/bundles/npm-module-seed.umd.min.js", 14 | "copy": "cpx './package-dist.json' dist && renamer --find 'package-dist.json' --replace 'package.json' ./dist/*", 15 | "build": "npm run clean && npm run transpile && npm run package && npm run minify && npm run copy" 16 | }, 17 | "license": "MIT", 18 | "homepage": "https://github.com/davguij/angular-npm-module-seed", 19 | "bugs": { 20 | "url": "https://github.com/davguij/angular-npm-module-seed/issues" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/davguij/angular-npm-module-seed.git" 25 | }, 26 | "devDependencies": { 27 | "@angular/compiler": "^2.4.4", 28 | "@angular/compiler-cli": "^2.4.4", 29 | "cpx": "^1.5.0", 30 | "renamer": "^0.6.1", 31 | "rimraf": "^2.5.4", 32 | "rollup": "^0.41.4", 33 | "typescript": "~2.0.0", 34 | "uglify-js": "^2.7.5" 35 | }, 36 | "dependencies": { 37 | "@angular/common": "^2.4.4", 38 | "@angular/core": "^2.4.4", 39 | "rxjs": "^5.0.3", 40 | "zone.js": "^0.7.6" 41 | } 42 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | entry: 'dist/index.js', 3 | dest: 'dist/bundles/npm-module-seed.umd.js', 4 | sourceMap: false, 5 | format: 'umd', 6 | moduleName: 'ng.npm-module-seed', 7 | globals: { 8 | '@angular/core': 'ng.core', 9 | '@angular/common': 'ng.common', 10 | 'rxjs/Observable': 'Rx', 11 | 'rxjs/ReplaySubject': 'Rx', 12 | 'rxjs/add/operator/map': 'Rx.Observable.prototype', 13 | 'rxjs/add/operator/mergeMap': 'Rx.Observable.prototype', 14 | 'rxjs/add/observable/fromEvent': 'Rx.Observable', 15 | 'rxjs/add/observable/of': 'Rx.Observable' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { SeedModule } from './seed.module'; 2 | export { SeedService } from './seed.service'; 3 | export { SeedComponent } from './seed.component'; -------------------------------------------------------------------------------- /src/seed.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { SeedService } from './seed.service'; 4 | 5 | @Component({ 6 | selector: 'seed-component', 7 | template: '{{greeting}}' 8 | }) 9 | export class SeedComponent implements OnInit { 10 | 11 | greeting: string; 12 | 13 | constructor(private service: SeedService) { } 14 | 15 | ngOnInit() { 16 | this.greeting = this.service.sayHello(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/seed.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SeedService } from './seed.service'; 5 | import { SeedComponent } from './seed.component'; 6 | 7 | export function seedServiceFactory() { 8 | return new SeedService(); 9 | } 10 | 11 | @NgModule({ 12 | imports: [CommonModule], 13 | providers: [ 14 | { provide: SeedService, useFactory: seedServiceFactory } 15 | ], 16 | declarations: [SeedComponent], 17 | exports: [SeedComponent] 18 | }) 19 | export class SeedModule { } 20 | -------------------------------------------------------------------------------- /src/seed.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class SeedService { 5 | 6 | constructor() { } 7 | 8 | sayHello() { 9 | return "Hello!"; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "", 4 | "declaration": true, 5 | "stripInternal": true, 6 | "experimentalDecorators": true, 7 | "strictNullChecks": true, 8 | "noImplicitAny": true, 9 | "module": "es2015", 10 | "moduleResolution": "node", 11 | "paths": { 12 | "@angular/core": [ 13 | "node_modules/@angular/core" 14 | ], 15 | "@angular/common": [ 16 | "node_modules/@angular/common" 17 | ], 18 | "rxjs/*": [ 19 | "node_modules/rxjs/*" 20 | ] 21 | }, 22 | "rootDir": "src", 23 | "outDir": "dist", 24 | "sourceMap": true, 25 | "inlineSources": true, 26 | "target": "es5", 27 | "skipLibCheck": true, 28 | "lib": [ 29 | "es2015", 30 | "dom" 31 | ] 32 | }, 33 | "files": [ 34 | "./src/index.ts" 35 | ], 36 | "angularCompilerOptions": { 37 | "strictMetadataEmit": true, 38 | "genDir": ".tmp" 39 | } 40 | } --------------------------------------------------------------------------------