Skip to content
This repository has been archived by the owner on Dec 4, 2017. It is now read-only.

Commit

Permalink
docs(cb-third-party-lib) create a third party lib
Browse files Browse the repository at this point in the history
s

s

s

s

s

c

s

c

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s

s
  • Loading branch information
thelgevold committed Nov 5, 2016
1 parent 74ef87f commit ab8e8ed
Show file tree
Hide file tree
Showing 30 changed files with 728 additions and 3 deletions.
6 changes: 5 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ var regularPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/regularPl
var embeddedPlunker = require(path.resolve(TOOLS_PATH, 'plunker-builder/embeddedPlunker'));
var fsUtils = require(path.resolve(TOOLS_PATH, 'fs-utils/fsUtils'));

var publish = require(path.resolve(EXAMPLES_PATH + '/cb-third-party-lib/hero-profile/publish'));

const WWW = argv.page ? 'www-pages' : 'www'

const isSilent = !!argv.silent;
Expand Down Expand Up @@ -464,7 +466,9 @@ gulp.task('add-example-boilerplate', function(done) {
fsUtils.addSymlink(realPath, linkPath);
});

return buildStyles(copyExampleBoilerplate, done);
publish().then(function(){
return buildStyles(copyExampleBoilerplate, done);
});
});


Expand Down
1 change: 1 addition & 0 deletions public/docs/_examples/_boilerplate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
"build:cli": "ng build",
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
"build:aot:jit": "npm run build:aot && npm run tsc",
"copy-dist-files": "node ./copy-dist-files.js",
"i18n": "ng-xi18n"
},
Expand Down
3 changes: 2 additions & 1 deletion public/docs/_examples/_boilerplate/systemjs.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'hero-profile': 'npm:hero-profile/bundles/hero-profile.umd.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
Expand Down
3 changes: 2 additions & 1 deletion public/docs/_examples/_boilerplate/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"compileOnSave": true,
"exclude": [
"node_modules/*",
"**/*-aot.ts"
"**/*-aot.ts",
"app-aot"
]
}
9 changes: 9 additions & 0 deletions public/docs/_examples/cb-third-party-lib/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**/*.ngfactory.ts
**/*.metadata.json
**/*.css.shim.ts
*.js
!/hero-profile/rollup-config.js
!/hero-profile/publish.js
!/hero-profile/inline-resources.js
!/hero-profile/package.json
!ts/rollup-config.js
22 changes: 22 additions & 0 deletions public/docs/_examples/cb-third-party-lib/e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict'; // necessary for es6 output in node

import { browser, element, by } from 'protractor';

describe('Third Party Lib Cookbook', function () {

let expectedMsgAoT = 'Library consumed by AoT application';
let expectedMsgJiT = 'Library consumed by JiT application';

beforeEach(function () {
browser.get('');
});

it(`should load AoT compiled version`, function () {
expect(element(by.css('.aot')).getText()).toEqual(expectedMsgAoT);
});

it('should load JiT compiled version', function () {
expect(element(by.css('.jit')).getText()).toEqual(expectedMsgJiT);
});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*#docregion*/
.bio {
border: 1px solid black;
padding: 10px;
width: 300px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--#docregion-->
<div class="bio">
<h1>Featured Hero</h1>

<h3>{{hero.name}}</h3>
<div>{{hero.bio}}</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// #docregion
import { Component, Input } from '@angular/core';

import { Hero } from './hero';

@Component({
moduleId: module.id,
selector: 'hero-profile',
templateUrl: 'hero-profile.component.html',
styleUrls: ['hero-profile.component.css']
})
export class HeroProfileComponent {
@Input() hero: Hero;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// #docregion
import { NgModule } from '@angular/core';

import { HeroProfileComponent } from './hero-profile.component';

@NgModule({
declarations: [HeroProfileComponent],
exports: [HeroProfileComponent]
})
export class HeroProfileModule {

}
4 changes: 4 additions & 0 deletions public/docs/_examples/cb-third-party-lib/hero-profile/hero.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// #docregion
export class Hero {
constructor(public name: string, public bio: string) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// #docregion
export { HeroProfileComponent } from './hero-profile.component';
export { HeroProfileModule } from './hero-profile.module';
export { Hero } from './hero';
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// #docregion
'use strict';

const fs = require('fs');
const path = require('path');
const glob = require('glob');

/**
* Simple Promiseify function that takes a Node API and return a version that supports promises.
* We use promises instead of synchronized functions to make the process less I/O bound and
* faster. It also simplify the code.
*/
function promiseify(fn) {
return function() {
const args = [].slice.call(arguments, 0);
return new Promise((resolve, reject) => {
fn.apply(this, args.concat([function (err, value) {
if (err) {
reject(err);
} else {
resolve(value);
}
}]));
});
};
}

const readFile = promiseify(fs.readFile);
const writeFile = promiseify(fs.writeFile);


function inlineResources(globs) {
if (typeof globs == 'string') {
globs = [globs];
}

/**
* For every argument, inline the templates and styles under it and write the new file.
*/
return Promise.all(globs.map(pattern => {
if (pattern.indexOf('*') < 0) {
// Argument is a directory target, add glob patterns to include every files.
pattern = path.join(pattern, '**', '*');
}

const files = glob.sync(pattern, {})
.filter(name => /\.js$/.test(name)); // Matches only JavaScript files.

// Generate all files content with inlined templates.
return Promise.all(files.map(filePath => {
return readFile(filePath, 'utf-8')
.then(content => inlineResourcesFromString(content, url => {
return path.join(path.dirname(filePath), url);
}))
.then(content => writeFile(filePath, content))
.catch(err => {
console.error('An error occured: ', err);
});
}));
}));
}

/**
* Inline resources from a string content.
* @param content {string} The source file's content.
* @param urlResolver {Function} A resolver that takes a URL and return a path.
* @returns {string} The content with resources inlined.
*/
function inlineResourcesFromString(content, urlResolver) {
// Curry through the inlining functions.
return [
inlineTemplate,
inlineStyle,
removeModuleId
].reduce((content, fn) => fn(content, urlResolver), content);
}

if (require.main === module) {
inlineResources(process.argv.slice(2));
}


/**
* Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
* replace with `template: ...` (with the content of the file included).
* @param content {string} The source file's content.
* @param urlResolver {Function} A resolver that takes a URL and return a path.
* @return {string} The content with all templates inlined.
*/
function inlineTemplate(content, urlResolver) {
return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function(m, templateUrl) {
const templateFile = urlResolver(templateUrl);
const templateContent = fs.readFileSync(templateFile, 'utf-8');
const shortenedTemplate = templateContent
.replace(/([\n\r]\s*)+/gm, ' ')
.replace(/"/g, '\\"');
return `template: "${shortenedTemplate}"`;
});
}


/**
* Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
* replace with `styles: [...]` (with the content of the file included).
* @param urlResolver {Function} A resolver that takes a URL and return a path.
* @param content {string} The source file's content.
* @return {string} The content with all styles inlined.
*/
function inlineStyle(content, urlResolver) {
return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function(m, styleUrls) {
const urls = eval(styleUrls);
return 'styles: ['
+ urls.map(styleUrl => {
const styleFile = urlResolver(styleUrl);
const styleContent = fs.readFileSync(styleFile, 'utf-8');
const shortenedStyle = styleContent
.replace(/([\n\r]\s*)+/gm, ' ')
.replace(/"/g, '\\"');
return `"${shortenedStyle}"`;
})
.join(',\n')
+ ']';
});
}


/**
* Remove every mention of `moduleId: module.id`.
* @param content {string} The source file's content.
* @returns {string} The content with all moduleId: mentions removed.
*/
function removeModuleId(content) {
return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
}

module.exports = inlineResources;
module.exports.inlineResourcesFromString = inlineResourcesFromString;
14 changes: 14 additions & 0 deletions public/docs/_examples/cb-third-party-lib/hero-profile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "hero-profile",
"version": "0.0.1",
"main": "bundles/hero-profile.umd.js",
"module": "index.js",
"typings": "index.d.ts",
"author": "",
"licenses": [
{
"type": "MIT",
"url": "https://github.com/angular/angular.io/blob/master/LICENSE"
}
]
}
59 changes: 59 additions & 0 deletions public/docs/_examples/cb-third-party-lib/hero-profile/publish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// #docregion
function publish() {
var inlineResources = require('./inline-resources');

// AoT compile
var spawnNgc = require( 'child_process' ).spawnSync;
var ngc = spawnNgc('./public/docs/_examples/node_modules/.bin/ngc', ['-p', './public/docs/_examples/cb-third-party-lib/hero-profile/tsconfig-aot.json']);

// Copy to node_modules
var fs = require('fs');
var del = require('del');

var node_modules_root = './public/docs/_examples/node_modules/hero-profile/';

del.sync(node_modules_root, {force:true});

fs.mkdirSync(node_modules_root);
fs.mkdirSync(node_modules_root + 'bundles');

var aotFiles = [
'hero-profile.component.html',
'hero-profile.component.css',

'hero-profile.component.d.ts',
'hero-profile.module.d.ts',
'hero.d.ts',
'index.d.ts',

'hero-profile.component.js',
'hero-profile.module.js',
'hero.js',
'index.js',

'index.metadata.json',
'hero-profile.module.metadata.json',
'hero-profile.component.metadata.json',

'package.json'
]

aotFiles.map(function(f) {
var path = f.split('/');
var release = node_modules_root + path[path.length-1];
fs.createReadStream('./public/docs/_examples/cb-third-party-lib/hero-profile/' + f).pipe(fs.createWriteStream(release));
});

return inlineResources('./public/docs/_examples/cb-third-party-lib/hero-profile/hero-profile.component.*').then(function(){

// Create umd bundle
var spawnRollup = require( 'child_process' ).spawnSync;
var rollup = spawnRollup('./public/docs/_examples/node_modules/.bin/rollup', ['-c', './public/docs/_examples/cb-third-party-lib/hero-profile/rollup-config.js']);

var umd = './public/docs/_examples/cb-third-party-lib/hero-profile/bundles/hero-profile.umd.js';
fs.createReadStream(umd).pipe(fs.createWriteStream(node_modules_root + 'bundles/hero-profile.umd.js'));

});
}

module.exports = publish;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// #docregion
export default {
entry: './public/docs/_examples/cb-third-party-lib/hero-profile/index.js',
dest: './public/docs/_examples/cb-third-party-lib/hero-profile/bundles/hero-profile.umd.js',
format: 'umd',
moduleName: 'ng.heroProfile',
globals: {
'@angular/core': 'ng.core'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"declaration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"typeRoots": [
"../../node_modules/@types/"
]
},
"files": [
"index.ts"
],
"angularCompilerOptions": {
"genDir": "aot",
"skipMetadataEmit" : false
}
}
Loading

0 comments on commit ab8e8ed

Please sign in to comment.