Compare commits
62 Commits
Author | SHA1 | Date | |
---|---|---|---|
e81982ef90 | |||
776bc38999 | |||
7e7ef8ee25 | |||
dd90d92573 | |||
1b862820e9 | |||
1a642231cd | |||
138e0d79cd | |||
f0a43716e2 | |||
2be27fb888 | |||
74f07f40e0 | |||
aa66e84e44 | |||
e1bc3f5c1a | |||
f5b366147b | |||
3147a92ee9 | |||
ffedbde0b3 | |||
e543c734ab | |||
fbe6871a94 | |||
f43cb9398c | |||
1e04df9ac7 | |||
840ca05fe8 | |||
facc9d498d | |||
9d0999027f | |||
c00dd5a3f3 | |||
3908a63381 | |||
20f9e51b8f | |||
232203242a | |||
0ca634e697 | |||
7fd9918024 | |||
b0aacb81d4 | |||
6c850eb031 | |||
0df61ad107 | |||
fa985ac067 | |||
06f9197361 | |||
c2bad1249e | |||
9d69ff8ddd | |||
3fd33f8eb0 | |||
501a243b3f | |||
b91b9efc91 | |||
03718c95ce | |||
0834710c18 | |||
9a9a7de9a4 | |||
ff51691221 | |||
2ad90ab0d3 | |||
c5872e6782 | |||
d20877bf3f | |||
b3089b4963 | |||
880b03101e | |||
451d996414 | |||
ea3669e334 | |||
ea2987c7af | |||
5b823dedcc | |||
80f7c83bdd | |||
53072b10da | |||
30c2f560b1 | |||
18c4976f3b | |||
0139173c7c | |||
f3c9954a68 | |||
e8765352e8 | |||
9e61ad897e | |||
0d81151cbc | |||
70319722a1 | |||
cfa5b6567d |
@ -12,8 +12,8 @@
|
||||
## IMPORTANT
|
||||
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
|
||||
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
|
||||
var_1: &docker_image angular/ngcontainer:0.3.0
|
||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.0
|
||||
var_1: &docker_image angular/ngcontainer:0.3.2
|
||||
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
|
||||
|
||||
# Define common ENV vars
|
||||
var_3: &define_env_vars
|
||||
@ -149,6 +149,10 @@ jobs:
|
||||
# See comments inside the integration/run_tests.sh script.
|
||||
integration_test:
|
||||
<<: *job_defaults
|
||||
# Note: we run Bazel in one of the integration tests, and it can consume >2G
|
||||
# of memory. Together with the system under test, this can exhaust the RAM
|
||||
# on a 4G worker so we use a larger machine here too.
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- *define_env_vars
|
||||
- checkout:
|
||||
|
25
CHANGELOG.md
25
CHANGELOG.md
@ -1,3 +1,28 @@
|
||||
<a name="6.0.6"></a>
|
||||
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
|
||||
|
||||
|
||||
|
||||
<a name="6.0.5"></a>
|
||||
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
|
||||
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
|
||||
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
|
||||
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
|
||||
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||
|
||||
|
||||
|
||||
<a name="6.0.4"></a>
|
||||
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)
|
||||
|
||||
|
@ -227,10 +227,15 @@ The following is the list of supported scopes:
|
||||
|
||||
There are currently a few exceptions to the "use package name" rule:
|
||||
|
||||
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
|
||||
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
|
||||
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
|
||||
to bundles, etc.
|
||||
* **changelog**: used for updating the release notes in CHANGELOG.md
|
||||
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
|
||||
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
|
||||
repo
|
||||
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
|
||||
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
|
||||
specific package (e.g. `docs: fix typo in tutorial`).
|
||||
|
||||
### Subject
|
||||
The subject contains a succinct description of the change:
|
||||
@ -269,7 +274,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
|
||||
* https://help.github.com/articles/about-commit-email-addresses/
|
||||
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
|
||||
|
||||
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
|
||||
|
||||
<hr>
|
||||
|
||||
|
@ -34,13 +34,13 @@ http_archive(
|
||||
# This commit matches the version of buildifier in angular/ngcontainer
|
||||
# If you change this, also check if it matches the version in the angular/ngcontainer
|
||||
# version in /.circleci/config.yml
|
||||
BAZEL_BUILDTOOLS_VERSION = "fd9878fd5de921e0bbab3dcdcb932c2627812ee1"
|
||||
BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
|
||||
|
||||
http_archive(
|
||||
name = "com_github_bazelbuild_buildtools",
|
||||
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
|
||||
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
|
||||
sha256 = "27bb461ade23fd44ba98723ad98f84ee9c83cd3540b773b186a1bc5037f3d862",
|
||||
sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
|
||||
)
|
||||
|
||||
# Fetching the Bazel source code allows us to compile the Skylark linter
|
||||
@ -77,7 +77,7 @@ http_archive(
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
|
||||
|
||||
check_bazel_version("0.13.0")
|
||||
check_bazel_version("0.14.0")
|
||||
node_repositories(package_json = ["//:package.json"])
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||
|
@ -52,8 +52,7 @@ export class BuildCleaner {
|
||||
protected removeDir(dir: string) {
|
||||
try {
|
||||
if (shell.test('-d', dir)) {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a+w', dir);
|
||||
shell.chmod('-R', 'a+w', dir);
|
||||
shell.rm('-rf', dir);
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -106,8 +106,7 @@ export class BuildCreator extends EventEmitter {
|
||||
}
|
||||
|
||||
try {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a-w', outputDir);
|
||||
shell.chmod('-R', 'a-w', outputDir);
|
||||
shell.rm('-f', inputFile);
|
||||
resolve();
|
||||
} catch (err) {
|
||||
|
@ -98,8 +98,7 @@ class Helper {
|
||||
const prDir = this.getPrDir(pr, isPublic);
|
||||
|
||||
if (fs.existsSync(prDir)) {
|
||||
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
|
||||
(shell as any).chmod('-R', 'a+w', prDir);
|
||||
shell.chmod('-R', 'a+w', prDir);
|
||||
shell.rm('-rf', prDir);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
"scripts": {
|
||||
"prebuild": "yarn clean-dist",
|
||||
"build": "tsc",
|
||||
"build-watch": "yarn tsc --watch",
|
||||
"build-watch": "yarn build --watch",
|
||||
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
|
||||
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
|
||||
"lint": "tslint --project tsconfig.json",
|
||||
@ -33,7 +33,7 @@
|
||||
"@types/jasmine": "^2.6.0",
|
||||
"@types/jsonwebtoken": "^7.2.3",
|
||||
"@types/node": "^8.0.30",
|
||||
"@types/shelljs": "^0.7.4",
|
||||
"@types/shelljs": "^0.8.0",
|
||||
"@types/supertest": "^2.0.3",
|
||||
"concurrently": "^3.5.0",
|
||||
"nodemon": "^1.12.1",
|
||||
|
@ -69,9 +69,9 @@
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/mime" "*"
|
||||
|
||||
"@types/shelljs@^0.7.4":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
|
||||
"@types/shelljs@^0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632"
|
||||
dependencies:
|
||||
"@types/glob" "*"
|
||||
"@types/node" "*"
|
||||
|
@ -15,6 +15,7 @@ export class ComposeMessageComponent {
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
|
||||
details: string;
|
||||
message: string;
|
||||
sending = false;
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
@ -18,11 +18,11 @@ nav a {
|
||||
border-radius: 4px;
|
||||
}
|
||||
nav a:visited, a:link {
|
||||
color: #607D8B;
|
||||
color: #607d8b;
|
||||
}
|
||||
nav a:hover {
|
||||
color: #039be5;
|
||||
background-color: #CFD8DC;
|
||||
background-color: #cfd8dc;
|
||||
}
|
||||
nav a.active {
|
||||
color: #039be5;
|
||||
|
@ -33,11 +33,11 @@ h4 {
|
||||
color: #eee;
|
||||
max-height: 120px;
|
||||
min-width: 120px;
|
||||
background-color: #607D8B;
|
||||
background-color: #607d8b;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.module:hover {
|
||||
background-color: #EEE;
|
||||
background-color: #eee;
|
||||
cursor: pointer;
|
||||
color: #607d8b;
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
// #docregion
|
||||
var path = require('path');
|
||||
|
||||
var _root = path.resolve(__dirname, '..');
|
||||
|
||||
function root(args) {
|
||||
args = Array.prototype.slice.call(arguments, 0);
|
||||
return path.join.apply(path, [_root].concat(args));
|
||||
}
|
||||
|
||||
exports.root = root;
|
||||
// #enddocregion
|
@ -1,17 +0,0 @@
|
||||
// #docregion
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
require('core-js/es6');
|
||||
require('core-js/es7/reflect');
|
||||
|
||||
require('zone.js/dist/zone');
|
||||
require('zone.js/dist/zone-testing');
|
||||
|
||||
var appContext = require.context('../src', true, /\.spec\.ts/);
|
||||
|
||||
appContext.keys().forEach(appContext);
|
||||
|
||||
var testing = require('@angular/core/testing');
|
||||
var browser = require('@angular/platform-browser-dynamic/testing');
|
||||
|
||||
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
|
@ -1,39 +0,0 @@
|
||||
// #docregion
|
||||
var webpackConfig = require('./webpack.test');
|
||||
|
||||
module.exports = function (config) {
|
||||
var _config = {
|
||||
basePath: '',
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
files: [
|
||||
{pattern: './config/karma-test-shim.js', watched: false}
|
||||
],
|
||||
|
||||
preprocessors: {
|
||||
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
|
||||
webpack: webpackConfig,
|
||||
|
||||
webpackMiddleware: {
|
||||
stats: 'errors-only'
|
||||
},
|
||||
|
||||
webpackServer: {
|
||||
noInfo: true
|
||||
},
|
||||
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: false,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: true
|
||||
};
|
||||
|
||||
config.set(_config);
|
||||
};
|
||||
// #enddocregion
|
@ -1,81 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = {
|
||||
// #docregion entries, one-entry, two-entries
|
||||
entry: {
|
||||
// #enddocregion one-entry, two-entries
|
||||
'polyfills': './src/polyfills.ts',
|
||||
// #docregion two-entries
|
||||
'vendor': './src/vendor.ts',
|
||||
// #docregion one-entry
|
||||
'app': './src/main.ts'
|
||||
},
|
||||
// #enddocregion entries, one-entry, two-entries
|
||||
|
||||
// #docregion resolve
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
// #enddocregion resolve
|
||||
|
||||
// #docregion loaders
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: 'awesome-typescript-loader',
|
||||
options: { configFileName: helpers.root('src', 'tsconfig.json') }
|
||||
} , 'angular2-template-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
loader: 'html-loader'
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
|
||||
loader: 'file-loader?name=assets/[name].[hash].[ext]'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: helpers.root('src', 'app'),
|
||||
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' })
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: helpers.root('src', 'app'),
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
// #enddocregion loaders
|
||||
|
||||
// #docregion plugins
|
||||
plugins: [
|
||||
// Workaround for angular/angular#11580
|
||||
new webpack.ContextReplacementPlugin(
|
||||
// The (\\|\/) piece accounts for path separators in *nix and Windows
|
||||
/angular(\\|\/)core(\\|\/)@angular/,
|
||||
helpers.root('./src'), // location of your src
|
||||
{} // a map of your routes
|
||||
),
|
||||
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: ['app', 'vendor', 'polyfills']
|
||||
}),
|
||||
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'src/index.html'
|
||||
})
|
||||
]
|
||||
// #enddocregion plugins
|
||||
};
|
||||
// #enddocregion
|
||||
|
@ -1,26 +0,0 @@
|
||||
// #docregion
|
||||
var webpackMerge = require('webpack-merge');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var commonConfig = require('./webpack.common.js');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = webpackMerge(commonConfig, {
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
|
||||
output: {
|
||||
path: helpers.root('dist'),
|
||||
publicPath: '/',
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[id].chunk.js'
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new ExtractTextPlugin('[name].css')
|
||||
],
|
||||
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
stats: 'minimal'
|
||||
}
|
||||
});
|
||||
// #enddocregion
|
@ -1,41 +0,0 @@
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var webpackMerge = require('webpack-merge');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var commonConfig = require('./webpack.common.js');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
|
||||
|
||||
module.exports = webpackMerge(commonConfig, {
|
||||
devtool: 'source-map',
|
||||
|
||||
output: {
|
||||
path: helpers.root('dist'),
|
||||
publicPath: '/',
|
||||
filename: '[name].[hash].js',
|
||||
chunkFilename: '[id].[hash].chunk.js'
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
|
||||
mangle: {
|
||||
keep_fnames: true
|
||||
}
|
||||
}),
|
||||
new ExtractTextPlugin('[name].[hash].css'),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
'ENV': JSON.stringify(ENV)
|
||||
}
|
||||
}),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
htmlLoader: {
|
||||
minimize: false // workaround for ng2
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
// #enddocregion
|
@ -1,55 +0,0 @@
|
||||
// #docregion
|
||||
var webpack = require('webpack');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
module.exports = {
|
||||
devtool: 'inline-source-map',
|
||||
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loaders: [
|
||||
{
|
||||
loader: 'awesome-typescript-loader',
|
||||
options: { configFileName: helpers.root('src', 'tsconfig.json') }
|
||||
} , 'angular2-template-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
loader: 'html-loader'
|
||||
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
|
||||
loader: 'null-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: helpers.root('src', 'app'),
|
||||
loader: 'null-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
include: helpers.root('src', 'app'),
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.ContextReplacementPlugin(
|
||||
// The (\\|\/) piece accounts for path separators in *nix and Windows
|
||||
/angular(\\|\/)core(\\|\/)@angular/,
|
||||
helpers.root('./src'), // location of your src
|
||||
{} // a map of your routes
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
// #enddocregion
|
@ -1,21 +0,0 @@
|
||||
'use strict'; // necessary for es6 output in node
|
||||
|
||||
import { browser, element, by } from 'protractor';
|
||||
|
||||
describe('QuickStart E2E Tests', function () {
|
||||
|
||||
let expectedMsg = 'Hello from Angular App with Webpack';
|
||||
|
||||
beforeEach(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
it(`should display: ${expectedMsg}`, function () {
|
||||
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
|
||||
});
|
||||
|
||||
it('should display an image', function () {
|
||||
expect(element(by.css('img')).isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
});
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"build": "build:webpack",
|
||||
"run": "serve:cli",
|
||||
"projectType": "systemjs"
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
// #docregion
|
||||
module.exports = require('./config/karma.conf.js');
|
@ -1,49 +0,0 @@
|
||||
{
|
||||
"name": "angular2-webpack",
|
||||
"version": "1.0.0",
|
||||
"description": "A webpack starter for Angular",
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --inline --progress --port 8080",
|
||||
"test": "karma start",
|
||||
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@angular/common": "~4.2.0",
|
||||
"@angular/compiler": "~4.2.0",
|
||||
"@angular/core": "~4.2.0",
|
||||
"@angular/forms": "~4.2.0",
|
||||
"@angular/http": "~4.2.0",
|
||||
"@angular/platform-browser": "~4.2.0",
|
||||
"@angular/platform-browser-dynamic": "~4.2.0",
|
||||
"@angular/router": "~4.2.0",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "5.0.1",
|
||||
"zone.js": "^0.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^6.0.45",
|
||||
"@types/jasmine": "2.5.36",
|
||||
"angular2-template-loader": "^0.6.0",
|
||||
"awesome-typescript-loader": "^3.0.4",
|
||||
"css-loader": "^0.26.1",
|
||||
"extract-text-webpack-plugin": "2.0.0-beta.5",
|
||||
"file-loader": "^0.9.0",
|
||||
"html-loader": "^0.4.3",
|
||||
"html-webpack-plugin": "^2.16.1",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"karma": "^1.2.0",
|
||||
"karma-chrome-launcher": "^2.0.0",
|
||||
"karma-jasmine": "^1.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^2.0.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"rimraf": "^2.5.2",
|
||||
"style-loader": "^0.13.1",
|
||||
"typescript": "~2.3.1",
|
||||
"webpack": "2.2.1",
|
||||
"webpack-dev-server": "2.4.1",
|
||||
"webpack-merge": "^3.0.0"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/* #docregion */
|
||||
main {
|
||||
padding: 1em;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
margin-top: 50px;
|
||||
display: block;
|
||||
}
|
||||
/* #enddocregion */
|
@ -1,7 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<main>
|
||||
<h1>Hello from Angular App with Webpack</h1>
|
||||
|
||||
<img src="../assets/images/angular.png">
|
||||
</main>
|
||||
<!-- #enddocregion -->
|
@ -1,16 +0,0 @@
|
||||
// #docregion
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('App', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({ declarations: [AppComponent]});
|
||||
});
|
||||
|
||||
it ('should work', () => {
|
||||
let fixture = TestBed.createComponent(AppComponent);
|
||||
expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
|
||||
});
|
||||
});
|
||||
// #enddocregion
|
@ -1,16 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion component
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
// #enddocregion component
|
||||
import '../assets/css/styles.css';
|
||||
|
||||
// #docregion component
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent { }
|
||||
// #enddocregion
|
@ -1,16 +0,0 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
@ -1,6 +0,0 @@
|
||||
/* #docregion */
|
||||
body {
|
||||
background: #0147A7;
|
||||
color: #fff;
|
||||
}
|
||||
/* #enddocregion */
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
@ -1,14 +0,0 @@
|
||||
<!-- #docregion -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Angular With Webpack</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<my-app>Loading...</my-app>
|
||||
</body>
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
@ -1,14 +0,0 @@
|
||||
// #docregion
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { enableProdMode } from '@angular/core';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
|
||||
// #docregion enable-prod
|
||||
if (process.env.ENV === 'production') {
|
||||
enableProdMode();
|
||||
}
|
||||
// #enddocregion enable-prod
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// #enddocregion
|
@ -1,12 +0,0 @@
|
||||
// #docregion
|
||||
import 'core-js/es6';
|
||||
import 'core-js/es7/reflect';
|
||||
require('zone.js/dist/zone');
|
||||
|
||||
if (process.env.ENV === 'production') {
|
||||
// Production
|
||||
} else {
|
||||
// Development and test
|
||||
Error['stackTraceLimit'] = Infinity;
|
||||
require('zone.js/dist/long-stack-trace-zone');
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["es2015", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// TODO(i): this no longer works. we need to review this example and if absolutely necessary rewrite it to use the
|
||||
// rxjs-compat package
|
||||
|
||||
// #docregion
|
||||
// Angular
|
||||
import '@angular/platform-browser';
|
||||
import '@angular/platform-browser-dynamic';
|
||||
import '@angular/core';
|
||||
import '@angular/common';
|
||||
import '@angular/http';
|
||||
import '@angular/router';
|
||||
|
||||
// RxJS
|
||||
import 'rxjs';
|
||||
|
||||
// Other vendors for example jQuery, Lodash or Bootstrap
|
||||
// You can import js, ts, css, sass, ...
|
||||
// #enddocregion
|
@ -1,3 +0,0 @@
|
||||
// #docregion
|
||||
module.exports = require('./config/webpack.dev.js');
|
||||
// #enddocregion
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"files":[
|
||||
"!**/*.d.ts",
|
||||
"!**/*.js",
|
||||
"!**/*.[0-9].*",
|
||||
"config/**/*",
|
||||
"webpack.config.js",
|
||||
"karma.webpack.conf.js"
|
||||
],
|
||||
"removeSystemJsConfig": true,
|
||||
"type": "webpack"
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
<div class="breadcrumb">
|
||||
<a href="#">API<a> / <a href="#">@core<a>
|
||||
</div>
|
||||
<header class="api-header">
|
||||
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
|
||||
</header>
|
||||
<div class="page-actions">
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
|
||||
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
|
||||
</div>
|
||||
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
|
||||
<div class="api-body">
|
||||
<section>
|
||||
<h2>Overview</h2>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
|
||||
class <a href="api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">NgModuleFactory</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun"><</span><span class="typ">ModuleWithComponentFactories</span><span class="pun"><</span><span class="pln">T</span><span class="pun">>></span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
|
||||
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun"><</span><span class="pln">any</span><span class="pun">>)</span></a><span class="pln">
|
||||
</span><span class="pun">}</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Description</h2>
|
||||
<p>The longer class description goes here which can include multiple paragraphs.</p>
|
||||
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
<h3>Subclasses</h3>
|
||||
<ul>
|
||||
<li><a href="#">Subclass1</a></li>
|
||||
<li><a href="#">Subclass2</a></li>
|
||||
<li><a href="#">Subclass3</a></li>
|
||||
</ul>
|
||||
<h3>See Also</h3>
|
||||
<ul>
|
||||
<li><a href="#">Link1</a></li>
|
||||
<li><a href="#">Link2</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Constructor</h2>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Properties</h2>
|
||||
<table class="is-full-width list-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property1</strong></code>
|
||||
</td>
|
||||
<td><label class="property-type-label type">Type</label></td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property2</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code><strong>Property3</strong></code>
|
||||
</td>
|
||||
<td>Type</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section class="api-method">
|
||||
<h2>Methods</h2>
|
||||
<table class="is-full-width item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method1Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<br>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="is-full-width api-method item-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Method2Name( )</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Description goes here</p>
|
||||
<hr>
|
||||
<h5>Declaration</h5>
|
||||
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
|
||||
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
|
||||
</aio-code>
|
||||
</code-example>
|
||||
<h6>Parameters</h6>
|
||||
<h6>Returns</h6>
|
||||
<p>Returns information and results goes here.</p>
|
||||
<h6>Errors</h6>
|
||||
<p>Error information goes here</p>
|
||||
<hr>
|
||||
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
|
||||
<h6>Overloads</h6>
|
||||
<table class="is-full-width">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
</td>
|
||||
<td>Description goes here</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr>
|
||||
<h5>Example: Descriptive Title of Method Example</h5>
|
||||
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
|
||||
<p>Intro description text about what the example is and how it can be used.</p>
|
||||
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
|
||||
<aio-code class="simple-code"><pre class="prettyprint lang-">
|
||||
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
|
||||
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
|
||||
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
|
||||
</pre></aio-code></code-example>
|
||||
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
|
||||
</section>
|
||||
</div>
|
@ -933,29 +933,18 @@ As always, strive for consistency.
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-06}
|
||||
{@a 05-02}
|
||||
|
||||
### Directive selectors
|
||||
### Component selectors
|
||||
|
||||
#### Style 02-06
|
||||
#### Style 05-02
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** Use lower camel case for naming the selectors of directives.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
|
||||
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
|
||||
|
||||
|
||||
</div>
|
||||
@ -966,16 +955,40 @@ As always, strive for consistency.
|
||||
|
||||
|
||||
|
||||
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
|
||||
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-07}
|
||||
|
||||
### Custom prefix for components
|
||||
### Component custom prefix
|
||||
|
||||
#### Style 02-07
|
||||
|
||||
@ -1078,11 +1091,51 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-06}
|
||||
|
||||
### Directive selectors
|
||||
|
||||
#### Style 02-06
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** Use lower camel case for naming the selectors of directives.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 02-08}
|
||||
|
||||
### Custom prefix for directives
|
||||
### Directive custom prefix
|
||||
|
||||
#### Style 02-08
|
||||
|
||||
@ -3056,9 +3109,9 @@ module are referenced across the entire application.
|
||||
|
||||
|
||||
|
||||
**Avoid** providing services in shared modules. Services are usually
|
||||
**Consider** _not_ providing services in shared modules. Services are usually
|
||||
singletons that are provided once for the entire application or
|
||||
in a particular feature module.
|
||||
in a particular feature module. There are exceptions, however. For example, in the sample code that follows, notice that the `SharedModule` provides `FilterTextService`. This is acceptable here because the service is stateless;that is, the consumers of the service aren't impacted by new instances.
|
||||
|
||||
|
||||
</div>
|
||||
@ -3710,59 +3763,6 @@ A typical *lazy loaded folder* contains a *routing component*, its child compone
|
||||
|
||||
## Components
|
||||
|
||||
{@a 05-02}
|
||||
|
||||
### Component selector names
|
||||
|
||||
#### Style 05-02
|
||||
|
||||
|
||||
<div class="s-rule do">
|
||||
|
||||
|
||||
|
||||
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="s-why-last">
|
||||
|
||||
|
||||
|
||||
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<a href="#toc">Back to top</a>
|
||||
|
||||
{@a 05-03}
|
||||
|
||||
### Components as elements
|
||||
|
@ -398,7 +398,7 @@ But a component is more than just its class.
|
||||
A component interacts with the DOM and with other components.
|
||||
The _class-only_ tests can tell you about class behavior.
|
||||
They cannot tell you if the component is going to render properly,
|
||||
respond to user input and gestures, or integrate with its parent and and child components.
|
||||
respond to user input and gestures, or integrate with its parent and child components.
|
||||
|
||||
None of the _class-only_ tests above can answer key questions about how the
|
||||
components actually behave on screen.
|
||||
|
@ -132,7 +132,7 @@ QuickStart identifies two *typings*, or `d.ts`, files:
|
||||
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.
|
||||
|
||||
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment;
|
||||
you can view an example in the [webpack](guide/webpack) page.
|
||||
|
||||
|
||||
QuickStart doesn't require these typings but many of the samples do.
|
||||
|
||||
|
@ -1,801 +0,0 @@
|
||||
# Webpack: An Introduction
|
||||
|
||||
<style>
|
||||
h4 {font-size: 17px !important; text-transform: none !important;}
|
||||
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
[**Webpack**](https://webpack.github.io/) is a popular module bundler,
|
||||
a tool for bundling application source code in convenient _chunks_
|
||||
and for loading that code from a server into a browser.
|
||||
|
||||
It's an excellent alternative to the *SystemJS* approach used elsewhere in the documentation.
|
||||
This guide offers a taste of Webpack and explains how to use it with Angular applications.
|
||||
|
||||
|
||||
{@a top}
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
# Contents
|
||||
|
||||
* [What is Webpack?](guide/webpack#what-is-webpack)
|
||||
|
||||
* [Entries and outputs](guide/webpack#entries-outputs)
|
||||
* [Multiple bundles](guide/webpack#multiple-bundles)
|
||||
* [Loaders](guide/webpack#loaders)
|
||||
* [Plugins](guide/webpack#plugins)
|
||||
|
||||
* [Configuring Webpack](guide/webpack#configure-webpack)
|
||||
|
||||
* [Polyfills](guide/webpack#polyfills)
|
||||
* [Common configuration](guide/webpack#common-configuration)
|
||||
* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)
|
||||
|
||||
* [entry](guide/webpack#common-entries)
|
||||
* [resolve extension-less imports](guide/webpack#common-resolves)
|
||||
* [`module.rules`](guide/webpack#common-rules)
|
||||
* [Plugins](guide/webpack#plugins)
|
||||
* [`CommonsChunkPlugin`](guide/webpack#commons-chunk-plugin)
|
||||
* [`HtmlWebpackPlugin`](guide/webpack#html-webpack-plugin)
|
||||
|
||||
* [Environment specific configuration](guide/webpack#environment-configuration)
|
||||
* [Development configuration](guide/webpack#development-configuration)
|
||||
* [Production configuration](guide/webpack#production-configuration)
|
||||
* [Test configuration](guide/webpack#test-configuration)
|
||||
|
||||
* [Trying it out](guide/webpack#try)
|
||||
* [Highlights](guide/webpack#highlights)
|
||||
* [Conclusion](guide/webpack#conclusion)
|
||||
|
||||
-->
|
||||
|
||||
You can also <a href="generated/zips/webpack/webpack.zip" target="_blank">download the final result.</a>
|
||||
|
||||
{@a what-is-webpack}
|
||||
|
||||
## What is Webpack?
|
||||
|
||||
Webpack is a powerful module bundler.
|
||||
A _bundle_ is a JavaScript file that incorporates _assets_ that *belong* together and
|
||||
should be served to the client in a response to a single file request.
|
||||
A bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.
|
||||
|
||||
Webpack roams over your application source code,
|
||||
looking for `import` statements, building a dependency graph, and emitting one or more _bundles_.
|
||||
With plugins and rules, Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.
|
||||
|
||||
You determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.
|
||||
|
||||
|
||||
{@a entries-outputs}
|
||||
|
||||
|
||||
|
||||
### Entries and outputs
|
||||
|
||||
You supply Webpack with one or more *entry* files and let it find and incorporate the dependencies that radiate from those entries.
|
||||
The one entry point file in this example is the application's root file, `src/main.ts`:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="one-entry" title="webpack.config.js (single entry)" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Webpack inspects that file and traverses its `import` dependencies recursively.
|
||||
|
||||
|
||||
<code-example path="webpack/src/app/app.component.ts" region="component" title="src/main.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
It sees that you're importing `@angular/core` so it adds that to its dependency list for potential inclusion in the bundle.
|
||||
It opens the `@angular/core` file and follows _its_ network of `import` statements until it has built the complete dependency graph from `main.ts` down.
|
||||
|
||||
Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:
|
||||
|
||||
<code-example name="webpack.config.js (single output)" language="javascript">
|
||||
output: {
|
||||
filename: 'app.js'
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
This `app.js` output bundle is a single JavaScript file that contains the application source and its dependencies.
|
||||
You'll load it later with a `<script>` tag in the `index.html`.
|
||||
|
||||
|
||||
{@a multiple-bundles}
|
||||
|
||||
|
||||
#### Multiple bundles
|
||||
You probably don't want one giant bundle of everything.
|
||||
It's preferable to separate the volatile application app code from comparatively stable vendor code modules.
|
||||
|
||||
Change the configuration so that it has two entry points, `main.ts` and `vendor.ts`:
|
||||
|
||||
|
||||
<code-example language="javascript">
|
||||
entry: {
|
||||
app: 'src/app.ts',
|
||||
vendor: 'src/vendor.ts'
|
||||
},
|
||||
|
||||
output: {
|
||||
filename: '[name].js'
|
||||
}
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
Webpack constructs two separate dependency graphs
|
||||
and emits *two* bundle files, one called `app.js` containing only the application code and
|
||||
another called `vendor.js` with all the vendor dependencies.
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The `[name]` in the output name is a *placeholder* that a Webpack plugin replaces with the entry names,
|
||||
`app` and `vendor`. Plugins are [covered later](guide/webpack#commons-chunk-plugin) in the guide.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
To tell Webpack what belongs in the vendor bundle,
|
||||
add a `vendor.ts` file that only imports the application's third-party modules:
|
||||
|
||||
<code-example path="webpack/src/vendor.ts" title="src/vendor.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a loaders}
|
||||
|
||||
|
||||
|
||||
### Loaders
|
||||
|
||||
Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, HTML, fonts, whatever.
|
||||
Webpack _itself_ only understands JavaScript files.
|
||||
Teach it to transform non-JavaScript file into their JavaScript equivalents with *loaders*.
|
||||
Configure loaders for TypeScript and CSS as follows.
|
||||
|
||||
|
||||
<code-example language="javascript">
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
loader: 'awesome-typescript-loader'
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: 'style-loader!css-loader'
|
||||
}
|
||||
]
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
When Webpack encounters `import` statements like the following,
|
||||
it applies the `test` RegEx patterns.
|
||||
|
||||
|
||||
<code-example language="typescript">
|
||||
import { AppComponent } from './app.component.ts';
|
||||
|
||||
import 'uiframework/dist/uiframework.css';
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
When a pattern matches the filename, Webpack processes the file with the associated loader.
|
||||
|
||||
The first `import` file matches the `.ts` pattern so Webpack processes it with the `awesome-typescript-loader`.
|
||||
The imported file doesn't match the second pattern so its loader is ignored.
|
||||
|
||||
The second `import` matches the second `.css` pattern for which you have *two* loaders chained by the (!) character.
|
||||
Webpack applies chained loaders *right to left*. So it applies
|
||||
the `css` loader first to flatten CSS `@import` and `url(...)` statements.
|
||||
Then it applies the `style` loader to append the css inside `<style>` elements on the page.
|
||||
|
||||
|
||||
{@a plugins}
|
||||
|
||||
|
||||
|
||||
### Plugins
|
||||
|
||||
Webpack has a build pipeline with well-defined phases.
|
||||
Tap into that pipeline with plugins such as the `uglify` minification plugin:
|
||||
|
||||
<code-example language="javascript">
|
||||
plugins: [
|
||||
new webpack.optimize.UglifyJsPlugin()
|
||||
]
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a configure-webpack}
|
||||
|
||||
|
||||
|
||||
## Configuring Webpack
|
||||
|
||||
After that brief orientation, you are ready to build your own Webpack configuration for Angular apps.
|
||||
|
||||
Begin by setting up the development environment.
|
||||
|
||||
Create a new project folder.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
mkdir angular-webpack
|
||||
cd angular-webpack
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Add these files:
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="package.json" path="webpack/package.webpack.json">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/tsconfig.json" path="webpack/src/tsconfig.1.json">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="webpack.config.js" path="webpack/webpack.config.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="karma.conf.js" path="webpack/karma.webpack.conf.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="config/helpers.js" path="webpack/config/helpers.js">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Many of these files should be familiar from other Angular documentation guides,
|
||||
especially the [Typescript configuration](guide/typescript-configuration) and
|
||||
[npm packages](guide/npm-packages) guides.
|
||||
|
||||
Webpack, the plugins, and the loaders are also installed as packages.
|
||||
They are listed in the updated `packages.json`.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Open a terminal window and install the npm packages.
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm install
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a polyfills}
|
||||
|
||||
|
||||
|
||||
### Polyfills
|
||||
|
||||
You'll need polyfills to run an Angular application in most browsers as explained
|
||||
in the [Browser Support](guide/browser-support) guide.
|
||||
|
||||
Polyfills should be bundled separately from the application and vendor bundles.
|
||||
Add a `polyfills.ts` like this one to the `src/` folder.
|
||||
|
||||
|
||||
<code-example path="webpack/src/polyfills.ts" title="src/polyfills.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="callout is-critical">
|
||||
|
||||
|
||||
|
||||
<header>
|
||||
Loading polyfills
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
Load `zone.js` early within `polyfills.ts`, immediately after the other ES6 and metadata shims.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Because this bundle file will load first, `polyfills.ts` is also a good place to configure the browser environment
|
||||
for production or development.
|
||||
|
||||
|
||||
{@a common-configuration}
|
||||
|
||||
|
||||
|
||||
### Common configuration
|
||||
|
||||
Developers typically have separate configurations for development, production, and test environments.
|
||||
All three have a lot of configuration in common.
|
||||
|
||||
Gather the common configuration in a file called `webpack.common.js`.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a inside-webpack-commonjs}
|
||||
|
||||
|
||||
### Inside _webpack.common.js_
|
||||
Webpack is a NodeJS-based tool that reads configuration from a JavaScript commonjs module file.
|
||||
|
||||
The configuration imports dependencies with `require` statements
|
||||
and exports several objects as properties of a `module.exports` object.
|
||||
|
||||
* [`entry`](guide/webpack#common-entries)—the entry-point files that define the bundles.
|
||||
* [`resolve`](guide/webpack#common-resolves)—how to resolve file names when they lack extensions.
|
||||
* [`module.rules`](guide/webpack#common-rules)— `module` is an object with `rules` for deciding how files are loaded.
|
||||
* [`plugins`](guide/webpack#common-plugins)—creates instances of the plugins.
|
||||
|
||||
|
||||
{@a common-entries}
|
||||
|
||||
|
||||
#### _entry_
|
||||
|
||||
The first export is the `entry` object:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="entries" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
This `entry` object defines the three bundles:
|
||||
|
||||
* `polyfills`—the polyfills needed to run Angular applications in most modern browsers.
|
||||
* `vendor`—the third-party dependencies such as Angular, lodash, and bootstrap.css.
|
||||
* `app`—the application code.
|
||||
|
||||
|
||||
{@a common-resolves}
|
||||
|
||||
|
||||
#### _resolve_ extension-less imports
|
||||
|
||||
The app will `import` dozens if not hundreds of JavaScript and TypeScript files.
|
||||
You could write `import` statements with explicit extensions like this example:
|
||||
|
||||
<code-example language="typescript">
|
||||
import { AppComponent } from './app.component.ts';
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
But most `import` statements don't mention the extension at all.
|
||||
Tell Webpack to resolve extension-less file requests by looking for matching files with
|
||||
`.ts` extension or `.js` extension (for regular JavaScript files and pre-compiled TypeScript files).
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="resolve" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
If Webpack should resolve extension-less files for styles and HTML,
|
||||
add `.css` and `.html` to the list.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a common-rules}
|
||||
|
||||
|
||||
|
||||
|
||||
#### _module.rules_
|
||||
Rules tell Webpack which loaders to use for each file, or module:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="loaders" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
* `awesome-typescript-loader`—a loader to transpile the Typescript code to ES5, guided by the `tsconfig.json` file.
|
||||
* `angular2-template-loader`—loads angular components' template and styles.
|
||||
* `html-loader`—for component templates.
|
||||
* images/fonts—Images and fonts are bundled as well.
|
||||
* CSS—the first pattern matches application-wide styles; the second handles
|
||||
component-scoped styles (the ones specified in a component's `styleUrls` metadata property).
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The first pattern is for the application-wide styles. It excludes `.css` files within the `src/app` directory
|
||||
where the component-scoped styles sit. The `ExtractTextPlugin` (described below) applies the `style` and `css`
|
||||
loaders to these files.
|
||||
|
||||
The second pattern filters for component-scoped styles and loads them as strings via the `raw-loader`,
|
||||
which is what Angular expects to do with styles specified in a `styleUrls` metadata property.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
Multiple loaders can be chained using the array notation.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a common-plugins}
|
||||
|
||||
|
||||
|
||||
|
||||
#### _plugins_
|
||||
Finally, create instances of three plugins:
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.common.js" region="plugins" title="config/webpack.common.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a commons-chunk-plugin}
|
||||
|
||||
|
||||
#### *CommonsChunkPlugin*
|
||||
|
||||
The `app.js` bundle should contain only application code. All vendor code belongs in the `vendor.js` bundle.
|
||||
|
||||
Of course the application code imports vendor code.
|
||||
On its own, Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
|
||||
The `CommonsChunkPlugin` does that job.
|
||||
|
||||
<div class="l-sub-section">
|
||||
|
||||
|
||||
|
||||
The `CommonsChunkPlugin` identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`.
|
||||
Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
|
||||
It would remove `polyfills` from `vendor` if they shared dependencies, which they don't.
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{@a html-webpack-plugin}
|
||||
|
||||
|
||||
#### _HtmlWebpackPlugin_
|
||||
|
||||
Webpack generates a number of js and CSS files.
|
||||
You _could_ insert them into the `index.html` _manually_. That would be tedious and error-prone.
|
||||
Webpack can inject those scripts and links for you with the `HtmlWebpackPlugin`.
|
||||
|
||||
|
||||
{@a environment-configuration}
|
||||
|
||||
|
||||
|
||||
### Environment-specific configuration
|
||||
|
||||
The `webpack.common.js` configuration file does most of the heavy lifting.
|
||||
Create separate, environment-specific configuration files that build on `webpack.common`
|
||||
by merging into it the peculiarities particular to the target environments.
|
||||
|
||||
These files tend to be short and simple.
|
||||
|
||||
|
||||
{@a development-configuration}
|
||||
|
||||
|
||||
|
||||
### Development configuration
|
||||
|
||||
Here is the `webpack.dev.js` development configuration file.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.dev.js" title="config/webpack.dev.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
The development build relies on the Webpack development server, configured near the bottom of the file.
|
||||
|
||||
Although you tell Webpack to put output bundles in the `dist` folder,
|
||||
the dev server keeps all bundles in memory; it doesn't write them to disk.
|
||||
You won't find any files in the `dist` folder, at least not any generated from *this development build*.
|
||||
|
||||
|
||||
The `HtmlWebpackPlugin`, added in `webpack.common.js`, uses the `publicPath` and the `filename` settings to generate
|
||||
appropriate `<script>` and `<link>` tags into the `index.html`.
|
||||
|
||||
The CSS styles are buried inside the Javascript bundles by default. The `ExtractTextPlugin` extracts them into
|
||||
external `.css` files that the `HtmlWebpackPlugin` inscribes as `<link>` tags into the `index.html`.
|
||||
|
||||
Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and
|
||||
other configuration options in this file.
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm start
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a production-configuration}
|
||||
|
||||
|
||||
|
||||
### Production configuration
|
||||
|
||||
Configuration of a *production* build resembles *development* configuration with a few key changes.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.prod.js" title="config/webpack.prod.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You'll deploy the application and its dependencies to a real production server.
|
||||
You won't deploy the artifacts needed only in development.
|
||||
|
||||
Put the production output bundle files in the `dist` folder.
|
||||
|
||||
Webpack generates file names with cache-busting hash.
|
||||
Thanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes.
|
||||
|
||||
There are additional plugins:
|
||||
|
||||
* *`NoEmitOnErrorsPlugin`—stops the build if there is an error.
|
||||
* *`UglifyJsPlugin`—minifies the bundles.
|
||||
* *`ExtractTextPlugin`—extracts embedded css as external files, adding cache-busting hash to the filename.
|
||||
* *`DefinePlugin`—use to define environment variables that you can reference within the application.
|
||||
* *`LoaderOptionsPlugins`—to override options of certain loaders.
|
||||
|
||||
Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:
|
||||
|
||||
|
||||
<code-example path="webpack/src/main.ts" region="enable-prod" title="src/main.ts" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm run build
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
{@a test-configuration}
|
||||
|
||||
|
||||
|
||||
### Test configuration
|
||||
|
||||
You don't need much configuration to run unit tests.
|
||||
You don't need the loaders and plugins that you declared for your development and production builds.
|
||||
You probably don't need to load and process the application-wide styles files for unit tests and doing so would slow you down;
|
||||
you'll use the `null` loader for those CSS files.
|
||||
|
||||
You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need.
|
||||
But it might be simpler to start over with a completely fresh configuration.
|
||||
|
||||
|
||||
<code-example path="webpack/config/webpack.test.js" title="config/webpack.test.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Reconfigure [Karma](https://karma-runner.github.io/1.0/index.html) to use Webpack to run the tests:
|
||||
|
||||
|
||||
<code-example path="webpack/config/karma.conf.js" title="config/karma.conf.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
You don't precompile the TypeScript; Webpack transpiles the Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.
|
||||
There are no temporary files on disk.
|
||||
|
||||
The `karma-test-shim` tells Karma what files to pre-load and
|
||||
primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
|
||||
|
||||
|
||||
<code-example path="webpack/config/karma-test-shim.js" title="config/karma-test-shim.js" linenums="false">
|
||||
|
||||
</code-example>
|
||||
|
||||
|
||||
|
||||
Notice that you do _not_ load the application code explicitly.
|
||||
You tell Webpack to find and load the test files (the files ending in `.spec.ts`).
|
||||
Each spec file imports all—and only—the application source code that it tests.
|
||||
Webpack loads just _those_ specific application files and ignores the other files that you aren't testing.
|
||||
|
||||
|
||||
Grab the app code at the end of this guide and try:
|
||||
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
npm test
|
||||
|
||||
</code-example>
|
||||
|
||||
{@a try}
|
||||
|
||||
## Trying it out
|
||||
|
||||
Here is the source code for a small application that bundles with the
|
||||
Webpack techniques covered in this guide.
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/index.html" path="webpack/src/index.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/main.ts" path="webpack/src/main.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/assets/css/styles.css" path="webpack/src/assets/css/styles.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/app/app.component.ts" path="webpack/src/app/app.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.html" path="webpack/src/app/app.component.html">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.css" path="webpack/src/app/app.component.css">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.component.spec.ts" path="webpack/src/app/app.component.spec.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/app/app.module.ts" path="webpack/src/app/app.module.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
|
||||
The <code>app.component.html</code> displays this downloadable Angular logo
|
||||
<a href="assets/images/logos/angular/angular.png">
|
||||
<img src="assets/images/logos/angular/angular.png" height="40px" title="download Angular logo"></a>.
|
||||
Create a folder called `images` under the project's `assets` folder, then right-click (Cmd+click on Mac)
|
||||
on the image and download it to that folder.
|
||||
|
||||
|
||||
{@a bundle-ts}
|
||||
|
||||
|
||||
Here again are the TypeScript entry-point files that define the `polyfills` and `vendor` bundles.
|
||||
|
||||
<code-tabs>
|
||||
|
||||
<code-pane title="src/polyfills.ts" path="webpack/src/polyfills.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane title="src/vendor.ts" path="webpack/src/vendor.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
</code-tabs>
|
||||
|
||||
{@a highlights}
|
||||
|
||||
<h3 class="no-toc">Highlights</h3>
|
||||
|
||||
* There are no `<script>` or `<link>` tags in the `index.html`.
|
||||
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
|
||||
|
||||
* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
|
||||
|
||||
* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.
|
||||
Webpack stashes those component-scoped files in the `app.js` bundle too.
|
||||
You don't see those calls in the source code;
|
||||
they're added behind the scenes by the `angular2-template-loader` plug-in.
|
||||
|
||||
* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
|
||||
The application imports these modules too; they'd be duplicated in the `app.js` bundle
|
||||
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
|
||||
{@a conclusion}
|
||||
|
||||
## Conclusion
|
||||
|
||||
You've learned just enough Webpack to configurate development, test and production builds
|
||||
for a small Angular application.
|
||||
|
||||
_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.
|
||||
|
||||
[Back to top](guide/webpack#top)
|
@ -12,5 +12,19 @@
|
||||
"message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/ng-conf.png",
|
||||
"linkUrl": "https://www.ng-conf.org/livestream/"
|
||||
},
|
||||
{
|
||||
"startDate": "2018-06-01",
|
||||
"endDate": "2018-08-15",
|
||||
"message": "Join us for Angular Mix<br/>October 10th-12th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/angular-mix.png",
|
||||
"linkUrl": "https://angularmix.com/"
|
||||
},
|
||||
{
|
||||
"startDate": "2018-08-15",
|
||||
"endDate": "2018-11-06",
|
||||
"message": "Join us for Angular Connect<br/>November 6th-7th, 2018",
|
||||
"imageUrl": "generated/images/marketing/home/angular-connect.png",
|
||||
"linkUrl": "https://angularconnect.com/"
|
||||
}
|
||||
]
|
||||
|
@ -175,7 +175,13 @@
|
||||
"rev": true,
|
||||
"title": "Angular IDE by Webclipse",
|
||||
"url": "https://www.genuitec.com/products/angular-ide"
|
||||
}
|
||||
},
|
||||
"amexio-canvas": {
|
||||
"desc": "Amexio Canvas is Drag and Drop Environment to create Fully Responsive Web and Smart Device HTML5/Angular Apps. Code will be auto generated and hot deployed by the Canvas for live testing. Out of the box 50+ Material Design Theme support. Commit your code to GitHub public or private repository.",
|
||||
"rev": true,
|
||||
"title": "Amexio Canvas Web Based Drag and Drop IDE by MetaMagic",
|
||||
"url": "https://amexio.tech/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tooling": {
|
||||
|
@ -61,12 +61,6 @@
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"url": "guide/webpack",
|
||||
"title": "Webpack: An Introduction",
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
"url": "guide/quickstart",
|
||||
"title": "Getting Started",
|
||||
|
@ -112,7 +112,7 @@
|
||||
"cross-spawn": "^5.1.0",
|
||||
"css-selector-parser": "^1.3.0",
|
||||
"dgeni": "^0.4.7",
|
||||
"dgeni-packages": "^0.26.1",
|
||||
"dgeni-packages": "^0.26.2",
|
||||
"entities": "^1.1.1",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-plugin-jasmine": "^2.2.0",
|
||||
|
@ -82,31 +82,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (window.document.documentMode) {
|
||||
// polyfill IE11 in a blocking way
|
||||
var s = document.createElement('script');
|
||||
s.src = 'generated/ie-polyfills.min.js';
|
||||
document.head.appendChild(s);
|
||||
} else if (!Object.assign) {
|
||||
// polyfill other non-evergreen browsers in a blocking way
|
||||
var polyfillUrl = "https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.find&flags=gated&unknown=polyfill";
|
||||
|
||||
// send a blocking XHR to fetch the polyfill
|
||||
// then append it to the document so that its eval-ed synchronously
|
||||
// this is required because the method used for IE is not reliable with other non-evergreen browsers
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener("load", function() {
|
||||
var s = document.createElement('script');
|
||||
s.type = 'text/javascript';
|
||||
var code = this.responseText;
|
||||
s.appendChild(document.createTextNode(code));
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
xhr.open("GET", polyfillUrl, false);
|
||||
xhr.send();
|
||||
}
|
||||
</script>
|
||||
<script nomodule src="generated/ie-polyfills.min.js"></script>
|
||||
|
||||
<script>
|
||||
//load CE polyfill
|
||||
|
@ -1,79 +0,0 @@
|
||||
.api-section {
|
||||
position: relative;
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
table.api-table {
|
||||
min-width: 680px;
|
||||
|
||||
thead th {
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
background-color: $blue;
|
||||
border-radius: 4px 4px 0 0;
|
||||
text-transform: none;
|
||||
padding: 8px 24px;
|
||||
}
|
||||
|
||||
tbody {
|
||||
pre {
|
||||
white-space: normal;
|
||||
margin: 4px;
|
||||
padding: 4px 16px;
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.api-body {
|
||||
|
||||
max-width: 1200px;
|
||||
|
||||
table {
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
aio/src/styles/1-layouts/_api-pages.scss
Normal file
41
aio/src/styles/1-layouts/_api-pages.scss
Normal file
@ -0,0 +1,41 @@
|
||||
.api-body {
|
||||
|
||||
max-width: 1200px;
|
||||
|
||||
table {
|
||||
|
||||
th {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-bottom: 1px solid $lightgray;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.item-table {
|
||||
td {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
&.list-table {
|
||||
td {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
LAYOUT STYLES
|
||||
============================== */
|
||||
|
||||
@import 'api-page';
|
||||
@import 'api-pages';
|
||||
@import 'content-layout';
|
||||
@import 'doc-viewer';
|
||||
@import 'footer';
|
||||
|
@ -280,6 +280,7 @@ p {
|
||||
.code-anchor {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
|
@ -1,4 +1,4 @@
|
||||
.page-actions {
|
||||
.github-links {
|
||||
float: right;
|
||||
.material-icons {
|
||||
border-radius: 4px;
|
||||
@ -30,10 +30,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
.method-table {
|
||||
.method-table, .option-table {
|
||||
th {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
h3 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.github-links {
|
||||
a {
|
||||
color: $mediumgray;
|
||||
.material-icons:hover {
|
||||
background: none;
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 6px 0;
|
||||
font-weight: bold;
|
||||
clear: left;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@ -87,10 +107,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.api-section aio-code {
|
||||
background-color: rgba(241, 241, 241, 0.2);
|
||||
}
|
||||
|
||||
.from-constructor, .read-only-property {
|
||||
font-style: italic;
|
||||
color: $blue;
|
||||
|
@ -25,7 +25,7 @@ The zipper will use this information for creating new zips.
|
||||
|
||||
## Three kinds of examples
|
||||
|
||||
The majority of examples in AIO use `System.js` but there are also `CLI` and `Webpack` projects. This
|
||||
The majority of examples in AIO use `CLI`, with some additionally using `Webpack` and upgrade usiing `SystemJS`. This
|
||||
tool is able to differentiate between them.
|
||||
|
||||
The boilerplate uses a `package.json` that contains packages and scripts to run any kind of example.
|
||||
@ -44,7 +44,6 @@ Here you find a:
|
||||
|
||||
* **base.json** - All the common scripts and packages
|
||||
* **cli.json** - Extra scripts and packages for the CLI
|
||||
* **webpack.json** - Extra scripts and packages for Webpack
|
||||
* **universal.json** - Extra scripts and packages for universal
|
||||
* **i18n.json** - Extra scripts and packages for i18n
|
||||
* **systemjs.json** - All the System.js related packages but it also contains the remainder scripts
|
||||
@ -68,11 +67,11 @@ In both `stackblitz.json` and `zipper.json` you can use two extra properties for
|
||||
{
|
||||
...
|
||||
"removeSystemJsConfig": true,
|
||||
"type": "webpack"
|
||||
"type": "testing"
|
||||
}
|
||||
```
|
||||
|
||||
This would generate a zip for a webpack application and it will also remove everything related with
|
||||
This would generate a zip for a testing application and it will also remove everything related with
|
||||
SystemJS.
|
||||
|
||||
## Executing the zip generation
|
||||
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"scripts": [
|
||||
{ "name": "start:webpack", "rename": "start" },
|
||||
{ "name": "test:webpack", "rename": "test" },
|
||||
{ "name": "build:webpack", "rename": "build" }
|
||||
],
|
||||
"dependencies": [],
|
||||
"devDependencies": [
|
||||
"angular2-template-loader",
|
||||
"awesome-typescript-loader",
|
||||
"css-loader",
|
||||
"extract-text-webpack-plugin",
|
||||
"file-loader",
|
||||
"html-loader",
|
||||
"html-webpack-plugin",
|
||||
"karma-sourcemap-loader",
|
||||
"karma-webpack",
|
||||
"null-loader",
|
||||
"raw-loader",
|
||||
"rimraf",
|
||||
"style-loader",
|
||||
"webpack",
|
||||
"webpack-dev-server",
|
||||
"webpack-merge"
|
||||
]
|
||||
}
|
@ -113,7 +113,6 @@ class ExampleZipper {
|
||||
'!**/package.json',
|
||||
'!**/example-config.json',
|
||||
'!**/wallaby.js',
|
||||
'!**/package.webpack.json',
|
||||
// AoT related files
|
||||
'!**/aot/**/*.*',
|
||||
'!**/*-aot.*'
|
||||
|
@ -18,7 +18,6 @@ const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||
const IGNORED_EXAMPLES = [ // temporary ignores
|
||||
'quickstart',
|
||||
'setup',
|
||||
'webpack',
|
||||
'upgrade-p'
|
||||
];
|
||||
|
||||
|
@ -26,13 +26,7 @@
|
||||
"serve:cli": "http-server dist/",
|
||||
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
|
||||
"serve:aot": "lite-server -c bs-config.aot.json",
|
||||
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
|
||||
"test:webpack": "karma start karma.webpack.conf.js",
|
||||
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
|
||||
"build:babel": "babel src -d src --extensions \".es6\" --source-maps",
|
||||
"build:uni-client": "webpack --config webpack.config.client.js",
|
||||
"build:uni": "webpack --config webpack.config.universal.js",
|
||||
"serve:uni": "node dist/server.js",
|
||||
|
||||
"clean": "rimraf src/dist && rimraf src/app/*.js* && rimraf src/universal/*.js* && rimraf src/main.js*",
|
||||
"copy-dist-files": "node ./copy-dist-files.js",
|
||||
|
@ -58,12 +58,6 @@
|
||||
"@types/node": "^6.0.45",
|
||||
"canonical-path": "0.0.2",
|
||||
"concurrently": "^3.0.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.26.1",
|
||||
"extract-text-webpack-plugin": "2.0.0-beta.5",
|
||||
"file-loader": "^0.9.0",
|
||||
"html-loader": "^0.4.3",
|
||||
"html-webpack-plugin": "^2.16.1",
|
||||
"http-server": "^0.9.0",
|
||||
"jasmine-core": "~2.99.1",
|
||||
"jasmine-marbles": "^0.3.1",
|
||||
@ -74,7 +68,6 @@
|
||||
"karma-jasmine": "~1.1.1",
|
||||
"karma-jasmine-html-reporter": "^0.2.2",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"lite-server": "^2.2.2",
|
||||
"lodash": "^4.16.2",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
@ -85,7 +78,6 @@
|
||||
"rollup-plugin-node-resolve": "2.0.0",
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"source-map-explorer": "^1.3.2",
|
||||
"ts-loader": "^4.2.0",
|
||||
"ts-node": "^5.0.1",
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "2.7.2",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,12 +42,19 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
return EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe', 'module']);
|
||||
})
|
||||
|
||||
/**
|
||||
* These are the doc types that are contained within other docs
|
||||
*/
|
||||
.factory(function API_CONTAINED_DOC_TYPES() {
|
||||
return ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'];
|
||||
})
|
||||
|
||||
/**
|
||||
* These are the doc types that are API docs, including ones that will be merged into container docs,
|
||||
* such as members and overloads.
|
||||
*/
|
||||
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER) {
|
||||
return API_DOC_TYPES_TO_RENDER.concat(['member', 'function-overload']);
|
||||
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER, API_CONTAINED_DOC_TYPES) {
|
||||
return API_DOC_TYPES_TO_RENDER.concat(API_CONTAINED_DOC_TYPES);
|
||||
})
|
||||
|
||||
// Where do we get the source files?
|
||||
@ -112,8 +119,8 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder(__dirname, './tag-defs')));
|
||||
})
|
||||
|
||||
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, EXPORT_DOC_TYPES, API_DOC_TYPES) {
|
||||
computeStability.docTypes = EXPORT_DOC_TYPES;
|
||||
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, API_DOC_TYPES_TO_RENDER, API_DOC_TYPES) {
|
||||
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
|
||||
// Only split the description on the API docs
|
||||
splitDescription.docTypes = API_DOC_TYPES;
|
||||
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
|
||||
@ -155,6 +162,16 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
});
|
||||
})
|
||||
|
||||
.config(function(filterContainedDocs, API_CONTAINED_DOC_TYPES) {
|
||||
filterContainedDocs.docTypes = API_CONTAINED_DOC_TYPES;
|
||||
})
|
||||
|
||||
.config(function(checkContentRules, API_DOC_TYPES, API_CONTAINED_DOC_TYPES) {
|
||||
addMinLengthRules(checkContentRules);
|
||||
addHeadingRules(checkContentRules, API_DOC_TYPES);
|
||||
addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES);
|
||||
})
|
||||
|
||||
.config(function(computePathsProcessor, EXPORT_DOC_TYPES, generateApiListDoc) {
|
||||
|
||||
const API_SEGMENT = 'api';
|
||||
@ -188,3 +205,45 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||
autoLinkCode.docTypes = API_DOC_TYPES;
|
||||
autoLinkCode.codeElements = ['code', 'code-example', 'code-pane'];
|
||||
});
|
||||
|
||||
|
||||
function addMinLengthRules(checkContentRules) {
|
||||
const createMinLengthRule = require('./content-rules/minLength');
|
||||
const paramRuleSet = checkContentRules.docTypeRules['parameter'] = checkContentRules.docTypeRules['parameter'] || {};
|
||||
const paramRules = paramRuleSet['name'] = paramRuleSet['name'] || [];
|
||||
paramRules.push(createMinLengthRule());
|
||||
}
|
||||
|
||||
function addHeadingRules(checkContentRules, API_DOC_TYPES) {
|
||||
const createNoMarkdownHeadingsRule = require('./content-rules/noMarkdownHeadings');
|
||||
const noMarkdownHeadings = createNoMarkdownHeadingsRule();
|
||||
const allowOnlyLevel3Headings = createNoMarkdownHeadingsRule(1, 2, '4,');
|
||||
|
||||
API_DOC_TYPES.forEach(docType => {
|
||||
let rules;
|
||||
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
|
||||
|
||||
rules = ruleSet['description'] = ruleSet['description'] || [];
|
||||
rules.push(noMarkdownHeadings);
|
||||
|
||||
rules = ruleSet['shortDescription'] = ruleSet['shortDescription'] || [];
|
||||
rules.push(noMarkdownHeadings);
|
||||
|
||||
rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
|
||||
rules.push(allowOnlyLevel3Headings);
|
||||
});
|
||||
}
|
||||
|
||||
function addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES) {
|
||||
API_CONTAINED_DOC_TYPES.forEach(docType => {
|
||||
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
|
||||
|
||||
const rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
|
||||
rules.push((doc, prop, value) => value && !isMethod(doc) &&
|
||||
`Invalid property: "${prop}" is not allowed on "${doc.docType}" docs.`);
|
||||
});
|
||||
}
|
||||
|
||||
function isMethod(doc) {
|
||||
return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor;
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
module.exports = function computeApiBreadCrumbs(EXPORT_DOC_TYPES) {
|
||||
module.exports = function computeApiBreadCrumbs(API_DOC_TYPES_TO_RENDER) {
|
||||
return {
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process(docs) {
|
||||
// Compute the breadcrumb for each doc by processing its containers
|
||||
docs.forEach(doc => {
|
||||
if (EXPORT_DOC_TYPES.indexOf(doc.docType) !== -1) {
|
||||
doc.breadCrumbs = [
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path },
|
||||
{ text: doc.name, path: doc.path }
|
||||
];
|
||||
if (API_DOC_TYPES_TO_RENDER.indexOf(doc.docType) !== -1) {
|
||||
doc.breadCrumbs = [];
|
||||
doc.breadCrumbs.push({ text: 'API', path: '/api' });
|
||||
if (doc.moduleDoc) doc.breadCrumbs.push({ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path });
|
||||
doc.breadCrumbs.push({ text: doc.name, path: doc.path });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -13,14 +13,15 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
|
||||
expect(processor.$runBefore).toEqual(['rendering-docs']);
|
||||
});
|
||||
|
||||
it('should attach a breadCrumbs property to each of the EXPORT_DOC_TYPES docs', () => {
|
||||
const EXPORT_DOC_TYPES = ['class', 'interface'];
|
||||
const processor = processorFactory(EXPORT_DOC_TYPES);
|
||||
it('should attach a breadCrumbs property to each of the API_DOC_TYPES_TO_RENDER docs', () => {
|
||||
const API_DOC_TYPES_TO_RENDER = ['class', 'interface', 'module'];
|
||||
const processor = processorFactory(API_DOC_TYPES_TO_RENDER);
|
||||
|
||||
const docs = [
|
||||
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
|
||||
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
|
||||
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
|
||||
{ docType: 'module', name: 'testing', id: 'http/testing', path: 'http/testing' },
|
||||
];
|
||||
processor.$process(docs);
|
||||
|
||||
@ -35,5 +36,9 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
|
||||
{ text: 'InterfaceB', path: 'module-2/interface-b' },
|
||||
]);
|
||||
expect(docs[2].breadCrumbs).toBeUndefined();
|
||||
expect(docs[3].breadCrumbs).toEqual([
|
||||
{ text: 'API', path: '/api' },
|
||||
{ text: 'testing', path: 'http/testing' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,7 @@
|
||||
module.exports = function filterContainedDocs() {
|
||||
return {
|
||||
docTypes: ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'],
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'checkContentRules'],
|
||||
$runBefore: ['computing-paths'],
|
||||
$process: function(docs) {
|
||||
var docTypes = this.docTypes;
|
||||
|
@ -1,6 +1,6 @@
|
||||
module.exports = function filterPrivateDocs() {
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'checkContentRules'],
|
||||
$runBefore: ['computing-paths'],
|
||||
$process: function(docs) {
|
||||
return docs.filter(function(doc) { return doc.privateExport !== true; });
|
||||
|
@ -18,7 +18,7 @@ describe('filterPrivateDocs processor', () => {
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added', 'checkContentRules']);
|
||||
});
|
||||
|
||||
it('should remove docs that are marked as private exports', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
module.exports = function generateApiListDoc() {
|
||||
|
||||
return {
|
||||
$runAfter: ['extra-docs-added'],
|
||||
$runAfter: ['extra-docs-added', 'computeStability'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
outputFolder: null,
|
||||
$validate: {outputFolder: {presence: true}},
|
||||
|
@ -13,7 +13,7 @@ describe('generateApiListDoc processor', () => {
|
||||
|
||||
it('should run after the correct processor', () => {
|
||||
const processor = processorFactory();
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added']);
|
||||
expect(processor.$runAfter).toEqual(['extra-docs-added', 'computeStability']);
|
||||
});
|
||||
|
||||
it('should run before the correct processor', () => {
|
||||
|
@ -48,64 +48,62 @@ const {mergeProperties} = require('../../helpers/utils');
|
||||
module.exports = function mergeDecoratorDocs(log) {
|
||||
return {
|
||||
$runAfter: ['processing-docs'],
|
||||
$runBefore: ['docs-processed'],
|
||||
$runBefore: ['docs-processed', 'checkContentRules'],
|
||||
propertiesToMerge: [],
|
||||
makeDecoratorCalls: [
|
||||
{type: '', description: 'toplevel', functionName: 'makeDecorator'},
|
||||
{type: 'Prop', description: 'property', functionName: 'makePropDecorator'},
|
||||
{type: 'Param', description: 'parameter', functionName: 'makeParamDecorator'},
|
||||
],
|
||||
$process: function(docs) {
|
||||
$process(docs) {
|
||||
|
||||
var makeDecoratorCalls = this.makeDecoratorCalls;
|
||||
var propertiesToMerge = this.propertiesToMerge;
|
||||
var docsToMerge = Object.create(null);
|
||||
const decoratorDocs = Object.create(null);
|
||||
|
||||
docs.forEach(function(doc) {
|
||||
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
|
||||
docs.forEach(doc => {
|
||||
const initializer = getInitializer(doc);
|
||||
if (initializer) {
|
||||
makeDecoratorCalls.forEach(function(call) {
|
||||
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
|
||||
this.makeDecoratorCalls.forEach(function(call) {
|
||||
if (initializer.expression && initializer.expression.text === call.functionName) {
|
||||
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name);
|
||||
doc.docType = 'decorator';
|
||||
doc.decoratorLocation = call.description;
|
||||
// Get the type of the decorator metadata from the first "type" argument of the call.
|
||||
// For example the `X` of `createDecorator<X>(...)`.
|
||||
doc.decoratorType = initializer.arguments[0].text;
|
||||
// clear the symbol type named since it is not needed
|
||||
doc.symbolTypeName = undefined;
|
||||
const decoratorType = initializer.arguments[0].text;
|
||||
|
||||
// keep track of the names of the metadata interface that will need to be merged into this decorator doc
|
||||
docsToMerge[doc.name + 'Decorator'] = doc;
|
||||
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name, decoratorType);
|
||||
|
||||
doc.docType = 'decorator';
|
||||
doc.decoratorLocation = call.description;
|
||||
doc.decoratorType = decoratorType;
|
||||
|
||||
decoratorDocs[doc.name + 'Decorator'] = doc;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// merge the metadata docs into the decorator docs
|
||||
docs = docs.filter(function(doc) {
|
||||
if (docsToMerge[doc.name]) {
|
||||
// merge the info from the associated metadata interfaces into the decorator docs
|
||||
docs = docs.filter(doc => {
|
||||
if (decoratorDocs[doc.name]) {
|
||||
|
||||
// We have found an `XxxDecorator` document that will hold the call signature of the decorator
|
||||
var decoratorDoc = docsToMerge[doc.name];
|
||||
var callMember = doc.members.filter(function(member) { return member.isCallMember; })[0];
|
||||
var decoratorDoc = decoratorDocs[doc.name];
|
||||
var callMember = doc.members.find(member => member.isCallMember);
|
||||
|
||||
log.debug(
|
||||
'mergeDecoratorDocs: merging', doc.name, 'into', decoratorDoc.name,
|
||||
callMember.description.substring(0, 50));
|
||||
|
||||
// Merge the documentation found in this call signature into the original decorator
|
||||
mergeProperties(decoratorDoc, callMember, propertiesToMerge);
|
||||
mergeProperties(decoratorDoc, callMember, this.propertiesToMerge);
|
||||
|
||||
// remove doc from its module doc's exports
|
||||
doc.moduleDoc.exports =
|
||||
doc.moduleDoc.exports.filter(function(exportDoc) { return exportDoc !== doc; });
|
||||
|
||||
|
||||
// remove from the overall list of docs to be rendered
|
||||
return false;
|
||||
doc.moduleDoc.exports = doc.moduleDoc.exports.filter(exportDoc => exportDoc !== doc);
|
||||
}
|
||||
return true;
|
||||
|
||||
return !decoratorDocs[doc.name];
|
||||
});
|
||||
|
||||
return docs;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
// A ts2dart compiler annotation that can be ignored in API docs.
|
||||
// A ts2dart compiler annotation that we don't care about for API docs.
|
||||
// But, if we don't have a tag-def for it the doc-gen will error.
|
||||
module.exports = function() {
|
||||
return {name: 'Annotation', ignore: true};
|
||||
return {name: 'Annotation'};
|
||||
};
|
||||
|
@ -65,7 +65,9 @@ module.exports = function autoLinkCode(getDocFromAlias) {
|
||||
};
|
||||
}
|
||||
function foundValidDoc(docs) {
|
||||
return docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
return docs.length === 1 &&
|
||||
!docs[0].internal &&
|
||||
autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
|
||||
}
|
||||
|
||||
function createLinkNode(doc, text) {
|
||||
|
@ -79,6 +79,13 @@ describe('autoLinkCode post-processor', () => {
|
||||
'</code>');
|
||||
});
|
||||
|
||||
it('should ignore code items that match an internal API doc', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass', internal: true });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||
processor.$process([doc]);
|
||||
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||
});
|
||||
|
||||
it('should insert anchors for individual text nodes within a code block', () => {
|
||||
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||
const doc = { docType: 'test-doc', renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>' };
|
||||
|
@ -32,7 +32,7 @@ module.exports = function checkContentRules(log, createDocMessage) {
|
||||
docTypeRules: {},
|
||||
failOnContentErrors: false,
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['processing-docs'],
|
||||
$runBefore: [],
|
||||
$process(docs) {
|
||||
const logMessage = this.failOnContentErrors ? log.error.bind(log) : log.warn.bind(log);
|
||||
const errors = [];
|
||||
|
@ -18,7 +18,7 @@ describe('checkContentRules processor', function() {
|
||||
|
||||
it('shpuld run at the right time', () => {
|
||||
expect(processor.$runAfter).toEqual(['tags-extracted']);
|
||||
expect(processor.$runBefore).toEqual(['processing-docs']);
|
||||
expect(processor.$runBefore).toEqual([]);
|
||||
});
|
||||
|
||||
it('should do nothing if not configured', () => {
|
||||
|
@ -9,7 +9,7 @@ describe('hasValues filter', () => {
|
||||
|
||||
it('should return true if the specified property is truthy on any item in the list', function() {
|
||||
expect(filter.process([], 'a')).toEqual(false);
|
||||
expect(filter.process(0), 'a').toEqual(false);
|
||||
expect(filter.process(0, 'a')).toEqual(false);
|
||||
expect(filter.process({}, 'a')).toEqual(false);
|
||||
expect(filter.process([{a: 1}], 'a')).toEqual(true);
|
||||
expect(filter.process([{b: 2}], 'a')).toEqual(false);
|
||||
|
@ -8,16 +8,20 @@ module.exports =
|
||||
.factory(require('./services/getAliases'))
|
||||
.factory(require('./services/getDocFromAlias'))
|
||||
.factory(require('./services/getLinkInfo'))
|
||||
.factory(require('./services/disambiguators/disambiguateByContainer'))
|
||||
.factory(require('./services/disambiguators/disambiguateByDeprecated'))
|
||||
.factory(require('./services/disambiguators/disambiguateByModule'))
|
||||
.factory(require('./services/disambiguators/disambiguateByNonMember'))
|
||||
|
||||
.config(function(inlineTagProcessor, linkInlineTagDef) {
|
||||
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
|
||||
})
|
||||
|
||||
.config(function(getDocFromAlias, disambiguateByDeprecated, disambiguateByModule) {
|
||||
.config(function(getDocFromAlias, disambiguateByContainer, disambiguateByDeprecated, disambiguateByModule, disambiguateByNonMember) {
|
||||
getDocFromAlias.disambiguators = [
|
||||
disambiguateByContainer,
|
||||
disambiguateByDeprecated,
|
||||
disambiguateByModule
|
||||
disambiguateByModule,
|
||||
disambiguateByNonMember,
|
||||
];
|
||||
});
|
||||
|
@ -14,7 +14,6 @@ var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
|
||||
module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) {
|
||||
return {
|
||||
name: 'link',
|
||||
aliases: ['linkDocs'],
|
||||
failOnBadLink: false,
|
||||
description:
|
||||
'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors',
|
||||
|
@ -19,7 +19,6 @@ describe('link inline-tag-def', function() {
|
||||
it('should be available as a service', () => {
|
||||
expect(tag).toBeDefined();
|
||||
expect(tag.name).toEqual('link');
|
||||
expect(tag.aliases).toEqual(['linkDocs']);
|
||||
});
|
||||
|
||||
it('should call getLinkInfo', () => {
|
||||
|
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This link disambiguator looks for matching docs that have a common container with the
|
||||
* originatingDoc and will return just those.
|
||||
*/
|
||||
module.exports = function disambiguateByContainer() {
|
||||
return _disambiguate;
|
||||
};
|
||||
|
||||
function _disambiguate(alias, originatingDoc, docs) {
|
||||
if (originatingDoc) {
|
||||
const filteredDocs = docs.filter(doc => doc.containerDoc === originatingDoc);
|
||||
if (filteredDocs.length === 0) {
|
||||
// No docs match so let's look at the containers container
|
||||
return _disambiguate(alias, originatingDoc.containerDoc, docs);
|
||||
}
|
||||
return filteredDocs;
|
||||
}
|
||||
return docs;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
const disambiguateByContainer = require('./disambiguateByContainer')();
|
||||
const containerA = { name: 'a' };
|
||||
const containerB = { name: 'b' };
|
||||
const docs = [
|
||||
{ id: 'doc1', containerDoc: containerA },
|
||||
{ id: 'doc2', containerDoc: containerA },
|
||||
{ id: 'doc3', containerDoc: containerB },
|
||||
];
|
||||
|
||||
describe('disambiguateByContainer', () => {
|
||||
it('should return all docs if the originating doc has no containerDoc', () => {
|
||||
expect(disambiguateByContainer('alias', { }, docs)).toEqual(docs);
|
||||
});
|
||||
|
||||
it('should return all docs if no docs match the originating doc containerDoc', () => {
|
||||
expect(disambiguateByContainer('alias', { containerDoc: { name: 'c' } }, docs)).toEqual(docs);
|
||||
});
|
||||
|
||||
it('should return only docs that are contained by the originating doc or its containers', () => {
|
||||
expect(disambiguateByContainer('alias', containerB, docs)).toEqual([
|
||||
{ id: 'doc3', containerDoc: containerB },
|
||||
]);
|
||||
|
||||
expect(disambiguateByContainer('alias', { containerDoc: containerA }, docs)).toEqual([
|
||||
{ id: 'doc1', containerDoc: containerA },
|
||||
{ id: 'doc2', containerDoc: containerA },
|
||||
]);
|
||||
|
||||
expect(disambiguateByContainer('alias', { containerDoc: containerB }, docs)).toEqual([
|
||||
{ id: 'doc3', containerDoc: containerB },
|
||||
]);
|
||||
|
||||
});
|
||||
});
|
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* This link disambiguator will remove all the members from the list of ambiguous links
|
||||
* if there is at least one link to a doc that is not a member.
|
||||
*
|
||||
* The heuristic is that exports are more important than members when linking, and that
|
||||
* in general members will be linked to via a more explicit code links such as
|
||||
* `MyClass.member` rather than simply `member`.
|
||||
*/
|
||||
module.exports = function disambiguateByNonMember() {
|
||||
return (alias, originatingDoc, docs) => {
|
||||
const filteredDocs = docs.filter(doc => doc.docType !== 'member');
|
||||
return filteredDocs.length > 0 ? filteredDocs : docs;
|
||||
};
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
const disambiguateByNonMember = require('./disambiguateByNonMember')();
|
||||
const doc1 = { id: 'doc1', docType: 'function', containerDoc: {} };
|
||||
const doc2 = { id: 'doc2', docType: 'member', containerDoc: {} };
|
||||
const doc3 = { id: 'doc3', docType: 'member', containerDoc: {} };
|
||||
const doc4 = { id: 'doc4', docType: 'class', containerDoc: {} };
|
||||
const doc5 = { id: 'doc5', docType: 'member', containerDoc: {} };
|
||||
|
||||
describe('disambiguateByNonMember', () => {
|
||||
it('should filter out docs that are not members', () => {
|
||||
const docs = [doc1, doc2, doc3, doc4, doc5];
|
||||
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc1, doc4]);
|
||||
});
|
||||
|
||||
it('should return all docs if there are no members', () => {
|
||||
const docs = [doc1, doc4];
|
||||
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc1, doc4]);
|
||||
});
|
||||
|
||||
it('should return all docs if there are only members', () => {
|
||||
const docs = [doc2, doc3, doc5];
|
||||
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc2, doc3, doc5]);
|
||||
});
|
||||
});
|
@ -5,5 +5,5 @@ var Package = require('dgeni').Package;
|
||||
* @description Overrides the renderMarkdown service with an implementation based on remark
|
||||
*/
|
||||
module.exports = new Package('remark', ['nunjucks'])
|
||||
|
||||
.factory(require('./services/markedNunjucksFilter'))
|
||||
.factory(require('./services/renderMarkdown'));
|
||||
|
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Convert the value, as markdown, into HTML
|
||||
* @param headingMappings A map of headings to convert (e.g. from h3 to h4).
|
||||
*/
|
||||
module.exports = function markedNunjucksFilter(renderMarkdown) {
|
||||
return {
|
||||
name: 'marked',
|
||||
process: function(str, headingMappings) {
|
||||
return str && renderMarkdown(str, headingMappings);
|
||||
}
|
||||
};
|
||||
};
|
@ -0,0 +1,31 @@
|
||||
const visit = require('unist-util-visit');
|
||||
|
||||
function headingToLevel(heading) {
|
||||
const match = /^h(\d+)/.exec(heading);
|
||||
return match ? match[1] : '0';
|
||||
}
|
||||
|
||||
function parseMappings(mappings) {
|
||||
const mapping = {};
|
||||
Object.keys(mappings).forEach(key => mapping[headingToLevel(key)] = headingToLevel(mappings[key]));
|
||||
return mapping;
|
||||
}
|
||||
|
||||
module.exports = function mapHeadings(mappings) {
|
||||
const headings = parseMappings(mappings || {});
|
||||
return () => ast => {
|
||||
const nodesToFix = [];
|
||||
Object.keys(headings).forEach(heading => {
|
||||
visit(ast, 'heading', node => {
|
||||
if (node.depth === Number(heading)) {
|
||||
nodesToFix.push(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Update the depth of the matched nodes
|
||||
nodesToFix.forEach(node => node.depth = headings[node.depth]);
|
||||
|
||||
return ast;
|
||||
};
|
||||
};
|
@ -1,25 +1,29 @@
|
||||
const remark = require('remark');
|
||||
const html = require('remark-html');
|
||||
const code = require('./handlers/code');
|
||||
const mapHeadings = require('./plugins/mapHeadings');
|
||||
|
||||
/**
|
||||
* @dgService renderMarkdown
|
||||
* @description
|
||||
* Render the markdown in the given string as HTML.
|
||||
* @param headingMap A map of headings to convert.
|
||||
* E.g. `{h3: 'h4'} will map heading 3 level into heading 4.
|
||||
*/
|
||||
module.exports = function renderMarkdown() {
|
||||
const handlers = { code };
|
||||
const renderer = remark()
|
||||
.use(inlineTagDefs)
|
||||
.use(noIndentedCodeBlocks)
|
||||
.use(plainHTMLBlocks)
|
||||
// USEFUL DEBUGGING CODE
|
||||
// .use(() => tree => {
|
||||
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
|
||||
// })
|
||||
.use(html, { handlers });
|
||||
return function renderMarkdownImpl(content, headingMap) {
|
||||
|
||||
const renderer = remark()
|
||||
.use(inlineTagDefs)
|
||||
.use(noIndentedCodeBlocks)
|
||||
.use(plainHTMLBlocks)
|
||||
// USEFUL DEBUGGING CODE
|
||||
// .use(() => tree => {
|
||||
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
|
||||
// })
|
||||
.use(mapHeadings(headingMap))
|
||||
.use(html, { handlers: { code } });
|
||||
|
||||
return function renderMarkdownImpl(content) {
|
||||
return renderer.processSync(content).toString();
|
||||
};
|
||||
|
||||
|
@ -95,4 +95,36 @@ describe('remark: renderMarkdown service', () => {
|
||||
'</code-example>\n'
|
||||
);
|
||||
});
|
||||
|
||||
it('should map heading levels as specified', () => {
|
||||
const content =
|
||||
'# heading 1\n' +
|
||||
'\n' +
|
||||
'some paragraph\n' +
|
||||
'\n' +
|
||||
'## heading 2a\n' +
|
||||
'\n' +
|
||||
'some paragraph\n' +
|
||||
'\n' +
|
||||
'### heading 3\n' +
|
||||
'\n' +
|
||||
'some paragraph\n' +
|
||||
'\n' +
|
||||
'## heading 2b\n' +
|
||||
'\n' +
|
||||
'some paragraph\n' +
|
||||
'\n';
|
||||
const headingMappings = { h2: 'h3', h3: 'h5' };
|
||||
const output = renderMarkdown(content, headingMappings);
|
||||
expect(output).toEqual(
|
||||
'<h1>heading 1</h1>\n' +
|
||||
'<p>some paragraph</p>\n' +
|
||||
'<h3>heading 2a</h3>\n' +
|
||||
'<p>some paragraph</p>\n' +
|
||||
'<h5>heading 3</h5>\n' +
|
||||
'<p>some paragraph</p>\n' +
|
||||
'<h3>heading 2b</h3>\n' +
|
||||
'<p>some paragraph</p>\n'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -2,10 +2,7 @@
|
||||
{% set comma = joiner(',') %}
|
||||
{% set slash = joiner('/') %}
|
||||
<article>
|
||||
<div class="page-actions">
|
||||
<a href="{$ github.githubEditHref(doc, versionInfo) $}" aria-label="Suggest Edits" title="Suggest Edits"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a>
|
||||
<a href="{$ github.githubViewHref(doc, versionInfo) $}" aria-label="View Source" title="View Source"><i class="material-icons" aria-hidden="true" role="img">code</i></a>
|
||||
</div>
|
||||
{$ github.githubLinks(doc, versionInfo) $}
|
||||
<div class="breadcrumb">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
|
@ -9,15 +9,15 @@
|
||||
{% block details %}
|
||||
{% block additional %}{% endblock %}
|
||||
{% include "includes/description.html" %}
|
||||
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static Properties') $}
|
||||
{$ memberHelpers.renderMethodDetails(doc.staticMethods, 'static-methods', 'static-method', 'Static Methods') $}
|
||||
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
|
||||
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
|
||||
{% if doc.constructorDoc %}
|
||||
<h2>Constructor</h2>
|
||||
{$ memberHelpers.renderMethodDetail(doc.constructorDoc, 'constructor') $}{% endif %}
|
||||
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}{% endif %}
|
||||
|
||||
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
|
||||
|
||||
{$ memberHelpers.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
||||
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
||||
|
||||
{% block annotations %}{% include "includes/annotations.html" %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -1,9 +1,47 @@
|
||||
{% import "lib/githubLinks.html" as github -%}
|
||||
{% import "lib/memberHelpers.html" as memberHelper -%}
|
||||
{% import "lib/paramList.html" as params -%}
|
||||
{% extends 'export-base.template.html' %}
|
||||
|
||||
{% block overview %}{% include "includes/decorator-overview.html" %}{% endblock %}
|
||||
{% block details %}
|
||||
{% include "includes/description.html" %}
|
||||
{$ memberHelper.renderProperties(doc.members, 'metadata-members', 'metadata-member', 'Options') $}
|
||||
{% include "includes/description.html" %}
|
||||
|
||||
<section class="decorator-options">
|
||||
<h2>Options</h2>
|
||||
{% for option in doc.members %}
|
||||
<a id="{$ option.anchor $}"></a>
|
||||
<table class="is-full-width option-table">
|
||||
<thead><tr><th>
|
||||
<h3>{$ option.name $}</h3>
|
||||
{$ github.githubLinks(option, versionInfo) $}
|
||||
</th></tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{% if option.shortDescription %}{$ option.shortDescription | marked $}{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code-example language="ts" hideCopy="true" class="no-box api-heading">
|
||||
{$ option.name $}: {$ option.type | escape $}
|
||||
</code-example>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{%- if option.description %}
|
||||
{$ option.description | marked({ h3: 'h4' }) $}
|
||||
{% endif %}
|
||||
|
||||
{%- if option.usageNotes %}
|
||||
{$ option.usageNotes | marked({ h3: 'h4' }) $}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
@ -1,10 +1,33 @@
|
||||
{% import "lib/memberHelpers.html" as memberHelper -%}
|
||||
{% import "lib/descendants.html" as descendants -%}
|
||||
|
||||
{% macro renderOptionsTable(doc) %}
|
||||
<table class="is-full-width list-table option-overview">
|
||||
<thead>
|
||||
<tr><th>Option</th><th>Description</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%- for option in doc.members %}
|
||||
<tr class="option">
|
||||
<td>
|
||||
<a class="code-anchor" href="{$ doc.path $}#{$ option.anchor | urlencode $}">
|
||||
<code>{$ option.name $}</code>
|
||||
</a>
|
||||
</td>
|
||||
<td>{$ option.shortDescription | marked $}</td>
|
||||
</tr>
|
||||
{% endfor -%}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% for ancestor in doc.extendsClauses %}{% if ancestor.doc %}
|
||||
<h3 class="no-toc">Inherited from <a class="code-anchor" href="{$ ancestor.doc.path $}">{$ ancestor.doc.name $}</a> decorator</h3>
|
||||
{$ renderOptionsTable(ancestor.doc) $}
|
||||
{% endif %}{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% if doc.members.length %}
|
||||
<section class="decorator-overview">
|
||||
<code-example language="ts" hideCopy="true">
|
||||
@{$ doc.name $}{$ doc.typeParams | escape $}({ {$ memberHelper.renderMembers(doc) $}
|
||||
})
|
||||
</code-example>
|
||||
{$ renderOptionsTable(doc) $}
|
||||
{$ descendants.renderDescendants(doc, 'decorator', 'Subclasses') $}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% if doc.deprecated %}
|
||||
<section class="deprecated">
|
||||
<h2>Deprecation Notes</h2>
|
||||
<h2>Deprecation notes</h2>
|
||||
{$ doc.deprecated | marked $}
|
||||
</section>
|
||||
{% endif %}
|
@ -1,6 +1,6 @@
|
||||
{% if doc.members.length %}
|
||||
<section class="meta-data">
|
||||
<h2>Metadata Properties</h2>
|
||||
<h2>Metadata properties</h2>
|
||||
{% for metadata in doc.members %}{% if not metadata.internal %}
|
||||
<div class="metadata-member">
|
||||
<a name="{$ metadata.name $}" class="anchor-offset"></a>
|
||||
|
@ -11,7 +11,7 @@
|
||||
{%- endfor %} }}</code-example>
|
||||
|
||||
{% if doc.valueParam.type %}
|
||||
<h2>Input Value</h2>
|
||||
<h2>Input value</h2>
|
||||
{$ params.renderParameters([doc.valueParam], 'pipe-parameters', 'pipe-parameter', true) $}
|
||||
{% endif %}
|
||||
{% if doc.pipeParams.length %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% if doc.security %}
|
||||
<section "security">
|
||||
<h2>Security Risk</h2>
|
||||
<h2>Security risk</h2>
|
||||
{$ doc.security | marked $}
|
||||
</section>
|
||||
{% endif %}
|
@ -1,6 +1,6 @@
|
||||
{%- if doc.see.length %}
|
||||
<section class="see-also">
|
||||
<h2>See Also</h2>
|
||||
<h2>See also</h2>
|
||||
<ul>
|
||||
{% for see in doc.see %}
|
||||
<li>{$ see | marked $}</li>{% endfor %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% if doc.usageNotes %}
|
||||
<section class="usage-notes">
|
||||
<h2>Usage Notes</h2>
|
||||
<h2>Usage notes</h2>
|
||||
{$ doc.usageNotes | marked $}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
@ -7,5 +7,5 @@
|
||||
{% block details %}
|
||||
{% include "includes/description.html" %}
|
||||
{$ memberHelper.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
|
||||
{$ memberHelper.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
||||
{$ memberHelper.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
|
||||
{% endblock %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% macro githubViewHref(doc, versionInfo) -%}
|
||||
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.realProjectRelativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
|
||||
{%- endmacro %}
|
||||
{%- endmacro -%}
|
||||
|
||||
|
||||
{% macro githubEditHref(doc, versionInfo) -%}
|
||||
@ -9,4 +9,11 @@ https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInf
|
||||
{%- elseif doc.docType === 'module' %}{$ doc.id.split('/')[0] $}
|
||||
{%- else %}...{%- endif -%}
|
||||
)%3A%20describe%20your%20change...#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
|
||||
{%- endmacro %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{% macro githubLinks(doc, versionInfo) -%}
|
||||
<div class="github-links">
|
||||
<a href="{$ githubEditHref(doc, versionInfo) $}" aria-label="Suggest Edits" title="Suggest Edits"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a>
|
||||
<a href="{$ githubViewHref(doc, versionInfo) $}" aria-label="View Source" title="View Source"><i class="material-icons" aria-hidden="true" role="img">code</i></a>
|
||||
</div>
|
||||
{%- endmacro -%}
|
@ -1,3 +1,4 @@
|
||||
{% import "lib/githubLinks.html" as github -%}
|
||||
{% import "lib/paramList.html" as params -%}
|
||||
|
||||
{%- macro renderHeritage(exportDoc) -%}
|
||||
@ -69,15 +70,18 @@
|
||||
{%- endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro renderMethodDetail(method, cssClass) -%}
|
||||
{%- macro renderMethodDetail(versionInfo, method, cssClass) -%}
|
||||
<a id="{$ method.anchor $}"></a>
|
||||
<table class="is-full-width method-table {$ cssClass $}">
|
||||
{% if method.name !== 'constructor' %}<thead><tr><th><h3>
|
||||
{% if method.isCallMember %}<i>call signature</i>
|
||||
{% elseif method.isNewMember %}<i>construct signature</i>
|
||||
{% else %}{$ method.name $}()
|
||||
{% endif %}
|
||||
</h3></th></tr></thead>{% endif %}
|
||||
{% if method.name !== 'constructor' %}<thead><tr><th>
|
||||
<h3>
|
||||
{% if method.isCallMember %}<i>call signature</i>
|
||||
{% elseif method.isNewMember %}<i>construct signature</i>
|
||||
{% else %}{$ method.name $}()
|
||||
{% endif %}
|
||||
</h3>
|
||||
{$ github.githubLinks(method, versionInfo) $}
|
||||
</th></tr></thead>{% endif %}
|
||||
<tbody>
|
||||
{% if method.shortDescription %}<tr>
|
||||
<td class="short-description">
|
||||
@ -113,22 +117,33 @@
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if method.description %}<tr>
|
||||
|
||||
{% if method.description -%}
|
||||
<tr>
|
||||
<td class="description">
|
||||
{$ method.description | marked $}
|
||||
{$ method.description | marked({ h3: 'h4' }) $}
|
||||
</td>
|
||||
</tr>{% endif %}
|
||||
</tbody>
|
||||
</tr>
|
||||
{%- endif %}
|
||||
|
||||
{% if method.usageNotes -%}
|
||||
<tr>
|
||||
<td class="usage-notes">
|
||||
{$ method.usageNotes | marked({ h3: 'h4' }) $}
|
||||
</td>
|
||||
</tr>
|
||||
{%- endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endmacro -%}
|
||||
|
||||
{%- macro renderMethodDetails(methods, containerClass, itemClass, headingText) -%}
|
||||
{%- macro renderMethodDetails(versionInfo, methods, containerClass, itemClass, headingText) -%}
|
||||
{% set nonInternalMethods = methods | filterByPropertyValue('internal', undefined) %}
|
||||
{% if nonInternalMethods.length %}
|
||||
<section class="{$ containerClass $}">
|
||||
<h2>{$ headingText $}</h2>
|
||||
{% for member in nonInternalMethods %}
|
||||
{$ renderMethodDetail(member, itemClass) $}
|
||||
{$ renderMethodDetail(versionInfo, member, itemClass) $}
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endif %}
|
||||
@ -141,7 +156,7 @@
|
||||
{% if nonInternalProperties.length -%}
|
||||
<section class="{$ containerClass $}">
|
||||
<h2>{$ headingText $}</h2>
|
||||
<table class="is-full-width list-table properties-table">
|
||||
<table class="is-full-width list-table property-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{$ headings[0] or 'Property' $}</th>
|
||||
|
@ -3086,9 +3086,9 @@ devtools-timeline-model@1.1.6:
|
||||
chrome-devtools-frontend "1.0.401423"
|
||||
resolve "1.1.7"
|
||||
|
||||
dgeni-packages@^0.26.1:
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.26.1.tgz#34b5ed880be2f91862095b15085c50cc84507aa8"
|
||||
dgeni-packages@^0.26.2:
|
||||
version "0.26.2"
|
||||
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.26.2.tgz#dac22d7e861d4d72ed42af5272714f42b6b5bf3d"
|
||||
dependencies:
|
||||
canonical-path "0.0.2"
|
||||
catharsis "^0.8.1"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user