mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-22 17:47:53 +00:00
In generator-aspnetcore-spa, add option to produce Angular 2.4.5 project (with 'experimental' caveat)
This commit is contained in:
62
templates/Angular2Spa/package-2.4.5.json
Normal file
62
templates/Angular2Spa/package-2.4.5.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"name": "Angular2Spa",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"test": "karma start ClientApp/test/karma.conf.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": "^2.4.5",
|
||||||
|
"@angular/compiler": "^2.4.5",
|
||||||
|
"@angular/core": "^2.4.5",
|
||||||
|
"@angular/forms": "^2.4.5",
|
||||||
|
"@angular/http": "^2.4.5",
|
||||||
|
"@angular/platform-browser": "^2.4.5",
|
||||||
|
"@angular/platform-browser-dynamic": "^2.4.5",
|
||||||
|
"@angular/platform-server": "^2.4.5",
|
||||||
|
"@angular/router": "^3.0.2",
|
||||||
|
"@types/node": "^6.0.42",
|
||||||
|
"angular2-platform-node": "~2.0.11",
|
||||||
|
"angular2-template-loader": "^0.6.0",
|
||||||
|
"angular2-universal": "^2.1.0-rc.1",
|
||||||
|
"angular2-universal-patch": "^0.2.1",
|
||||||
|
"angular2-universal-polyfills": "^2.1.0-rc.1",
|
||||||
|
"aspnet-prerendering": "^2.0.0",
|
||||||
|
"aspnet-webpack": "^1.0.17",
|
||||||
|
"awesome-typescript-loader": "3.0.0-beta.13 || ^3.0.0",
|
||||||
|
"bootstrap": "^3.3.7",
|
||||||
|
"css": "^2.2.1",
|
||||||
|
"css-loader": "^0.25.0",
|
||||||
|
"es6-shim": "^0.35.1",
|
||||||
|
"event-source-polyfill": "^0.0.7",
|
||||||
|
"expose-loader": "^0.7.1",
|
||||||
|
"extract-text-webpack-plugin": "^2.0.0-rc",
|
||||||
|
"file-loader": "^0.9.0",
|
||||||
|
"html-loader": "^0.4.4",
|
||||||
|
"isomorphic-fetch": "^2.2.1",
|
||||||
|
"jquery": "^2.2.1",
|
||||||
|
"json-loader": "^0.5.4",
|
||||||
|
"preboot": "^4.5.2",
|
||||||
|
"raw-loader": "^0.5.1",
|
||||||
|
"rxjs": "^5.0.1",
|
||||||
|
"style-loader": "^0.13.1",
|
||||||
|
"to-string-loader": "^1.1.5",
|
||||||
|
"typescript": "^2.0.3",
|
||||||
|
"url-loader": "^0.5.7",
|
||||||
|
"webpack": "^2.2.0",
|
||||||
|
"webpack-hot-middleware": "^2.12.2",
|
||||||
|
"webpack-merge": "^0.14.1",
|
||||||
|
"zone.js": "^0.7.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/chai": "^3.4.34",
|
||||||
|
"@types/jasmine": "^2.5.37",
|
||||||
|
"chai": "^3.5.0",
|
||||||
|
"jasmine-core": "^2.5.2",
|
||||||
|
"karma": "^1.3.0",
|
||||||
|
"karma-chai": "^0.1.0",
|
||||||
|
"karma-chrome-launcher": "^2.0.0",
|
||||||
|
"karma-cli": "^1.0.1",
|
||||||
|
"karma-jasmine": "^1.0.2",
|
||||||
|
"karma-webpack": "^1.8.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,12 +35,21 @@ const testSpecificNpmPackages = [
|
|||||||
type YeomanPrompt = (opt: yeoman.IPromptOptions | yeoman.IPromptOptions[], callback: (answers: any) => void) => void;
|
type YeomanPrompt = (opt: yeoman.IPromptOptions | yeoman.IPromptOptions[], callback: (answers: any) => void) => void;
|
||||||
const optionOrPrompt: YeomanPrompt = require('yeoman-option-or-prompt');
|
const optionOrPrompt: YeomanPrompt = require('yeoman-option-or-prompt');
|
||||||
|
|
||||||
const templates = [
|
interface TemplateConfig {
|
||||||
{ value: 'angular-2', name: 'Angular 2', tests: true },
|
value: string; // Internal unique ID for Yeoman prompt
|
||||||
{ value: 'aurelia', name: 'Aurelia', tests: false },
|
rootDir: string; // Which of the template root directories should be used
|
||||||
{ value: 'knockout', name: 'Knockout', tests: false },
|
name: string; // Display name
|
||||||
{ value: 'react', name: 'React', tests: false },
|
tests: boolean;
|
||||||
{ value: 'react-redux', name: 'React with Redux', tests: false }
|
mapFilenames?: { [pattern: string]: string | boolean };
|
||||||
|
}
|
||||||
|
|
||||||
|
const templates: TemplateConfig[] = [
|
||||||
|
{ value: 'angular-2', rootDir: 'angular-2', name: 'Angular 2.0.2', tests: true, mapFilenames: { '^package\\-[\\d\\.]+.json$': false } },
|
||||||
|
{ value: 'angular-245', rootDir: 'angular-2', name: 'Angular 2.4.5 (experimental)', tests: true, mapFilenames: { '^package.json$': false, '^package\\-2\\.4\\.5.json$': 'package.json' } },
|
||||||
|
{ value: 'aurelia', rootDir: 'aurelia', name: 'Aurelia', tests: false },
|
||||||
|
{ value: 'knockout', rootDir: 'knockout', name: 'Knockout', tests: false },
|
||||||
|
{ value: 'react', rootDir: 'react', name: 'React', tests: false },
|
||||||
|
{ value: 'react-redux', rootDir: 'react-redux', name: 'React with Redux', tests: false }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Once everyone is on .csproj-compatible tooling, we might be able to remove the global.json files and eliminate
|
// Once everyone is on .csproj-compatible tooling, we might be able to remove the global.json files and eliminate
|
||||||
@@ -88,7 +97,7 @@ class MyGenerator extends yeoman.Base {
|
|||||||
message: 'What type of project do you want to create?',
|
message: 'What type of project do you want to create?',
|
||||||
choices: sdkChoices
|
choices: sdkChoices
|
||||||
}], firstAnswers => {
|
}], firstAnswers => {
|
||||||
const frameworkChoice = templates.filter(t => t.value === firstAnswers.framework)[0];
|
const templateConfig = templates.filter(t => t.value === firstAnswers.framework)[0];
|
||||||
const furtherQuestions = [{
|
const furtherQuestions = [{
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -96,7 +105,7 @@ class MyGenerator extends yeoman.Base {
|
|||||||
default: this.appname
|
default: this.appname
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (frameworkChoice.tests) {
|
if (templateConfig.tests) {
|
||||||
furtherQuestions.unshift({
|
furtherQuestions.unshift({
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
name: 'tests',
|
name: 'tests',
|
||||||
@@ -109,6 +118,7 @@ class MyGenerator extends yeoman.Base {
|
|||||||
answers.framework = firstAnswers.framework;
|
answers.framework = firstAnswers.framework;
|
||||||
this._answers = answers;
|
this._answers = answers;
|
||||||
this._answers.framework = firstAnswers.framework;
|
this._answers.framework = firstAnswers.framework;
|
||||||
|
this._answers.templateConfig = templateConfig;
|
||||||
this._answers.sdkVersion = firstAnswers.sdkVersion;
|
this._answers.sdkVersion = firstAnswers.sdkVersion;
|
||||||
this._answers.namePascalCase = toPascalCase(answers.name);
|
this._answers.namePascalCase = toPascalCase(answers.name);
|
||||||
this._answers.projectGuid = this.options['projectguid'] || uuid.v4();
|
this._answers.projectGuid = this.options['projectguid'] || uuid.v4();
|
||||||
@@ -122,7 +132,8 @@ class MyGenerator extends yeoman.Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
writing() {
|
writing() {
|
||||||
const templateRoot = this.templatePath(this._answers.framework);
|
const templateConfig = this._answers.templateConfig as TemplateConfig;
|
||||||
|
const templateRoot = this.templatePath(templateConfig.rootDir);
|
||||||
const chosenSdk = sdkChoices.filter(sdk => sdk.value === this._answers.sdkVersion)[0];
|
const chosenSdk = sdkChoices.filter(sdk => sdk.value === this._answers.sdkVersion)[0];
|
||||||
glob.sync('**/*', { cwd: templateRoot, dot: true, nodir: true }).forEach(fn => {
|
glob.sync('**/*', { cwd: templateRoot, dot: true, nodir: true }).forEach(fn => {
|
||||||
// Token replacement in filenames
|
// Token replacement in filenames
|
||||||
@@ -133,12 +144,22 @@ class MyGenerator extends yeoman.Base {
|
|||||||
outputFn = path.join(path.dirname(fn), '.gitignore');
|
outputFn = path.join(path.dirname(fn), '.gitignore');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform any filename replacements configured for the template
|
||||||
|
const mappedFilename = applyFirstMatchingReplacement(outputFn, templateConfig.mapFilenames);
|
||||||
|
let fileIsExcludedByTemplateConfig = false;
|
||||||
|
if (typeof mappedFilename === 'string') {
|
||||||
|
outputFn = mappedFilename;
|
||||||
|
} else {
|
||||||
|
fileIsExcludedByTemplateConfig = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Decide whether to emit this file
|
// Decide whether to emit this file
|
||||||
const isTestSpecificFile = testSpecificPaths.some(regex => regex.test(outputFn));
|
const isTestSpecificFile = testSpecificPaths.some(regex => regex.test(outputFn));
|
||||||
const isSdkSpecificFile = sdkChoices.some(sdk => sdk.includeFiles.some(regex => regex.test(outputFn)));
|
const isSdkSpecificFile = sdkChoices.some(sdk => sdk.includeFiles.some(regex => regex.test(outputFn)));
|
||||||
const matchesChosenSdk = chosenSdk.includeFiles.some(regex => regex.test(outputFn));
|
const matchesChosenSdk = chosenSdk.includeFiles.some(regex => regex.test(outputFn));
|
||||||
const emitFile = (matchesChosenSdk || !isSdkSpecificFile)
|
const emitFile = (matchesChosenSdk || !isSdkSpecificFile)
|
||||||
&& (this._answers.tests || !isTestSpecificFile);
|
&& (this._answers.tests || !isTestSpecificFile)
|
||||||
|
&& !fileIsExcludedByTemplateConfig;
|
||||||
|
|
||||||
if (emitFile) {
|
if (emitFile) {
|
||||||
let inputFullPath = path.join(templateRoot, fn);
|
let inputFullPath = path.join(templateRoot, fn);
|
||||||
@@ -247,5 +268,28 @@ function rewritePackageJson(contents, includeTests) {
|
|||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyFirstMatchingReplacement(inputValue: string, replacements: { [pattern: string]: string | boolean }): string | boolean {
|
||||||
|
if (replacements) {
|
||||||
|
const replacementPatterns = Object.getOwnPropertyNames(replacements);
|
||||||
|
for (let patternIndex = 0; patternIndex < replacementPatterns.length; patternIndex++) {
|
||||||
|
const pattern = replacementPatterns[patternIndex];
|
||||||
|
const regexp = new RegExp(pattern);
|
||||||
|
if (regexp.test(inputValue)) {
|
||||||
|
const replacement = replacements[pattern];
|
||||||
|
|
||||||
|
// To avoid bug-prone evaluation order dependencies, we only respond to the first name match per file
|
||||||
|
if (typeof (replacement) === 'boolean') {
|
||||||
|
return replacement;
|
||||||
|
} else {
|
||||||
|
return inputValue.replace(regexp, replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match
|
||||||
|
return inputValue;
|
||||||
|
}
|
||||||
|
|
||||||
declare var module: any;
|
declare var module: any;
|
||||||
(module).exports = MyGenerator;
|
(module).exports = MyGenerator;
|
||||||
|
|||||||
Reference in New Issue
Block a user