Implement workaround for #1066

This commit is contained in:
Steve Sanderson
2017-06-26 12:51:03 +01:00
parent 53f5a77490
commit 117c1a6cbd
4 changed files with 84 additions and 4 deletions

View File

@@ -1,11 +1,12 @@
{ {
"name": "aspnet-webpack-react", "name": "aspnet-webpack-react",
"version": "2.0.0", "version": "2.0.1",
"description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.", "description": "Helpers for using Webpack with React in ASP.NET Core projects. Works in conjunction with the Microsoft.AspNetCore.SpaServices NuGet package.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-webpack-react\"'", "prepublish": "rimraf *.d.ts && tsc && echo 'Finished building NPM package \"aspnet-webpack-react\"'",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1",
"postinstall": "node scripts/postinstall.js"
}, },
"author": "Microsoft", "author": "Microsoft",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -16,8 +17,12 @@
"type": "git", "type": "git",
"url": "https://github.com/aspnet/JavaScriptServices.git" "url": "https://github.com/aspnet/JavaScriptServices.git"
}, },
"dependencies": {
"@types/webpack": "2.2.15",
"hjson": "2.4.3"
},
"devDependencies": { "devDependencies": {
"@types/webpack": "^2.2.0", "@types/react": "15.0.29",
"rimraf": "^2.5.4", "rimraf": "^2.5.4",
"typescript": "^2.0.0", "typescript": "^2.0.0",
"webpack": "^2.2.0" "webpack": "^2.2.0"

View File

@@ -0,0 +1,55 @@
var fs = require('fs');
var path = require('path');
var Hjson = require('hjson');
// This logic is a workaround for #1066.
// See the comment in index.ts for details.
function findInDirOrAncestor(targetFilename, rootDir) {
var candidateFilename = path.join(rootDir, targetFilename);
if (fs.existsSync(candidateFilename)) {
return candidateFilename;
}
var parentDir = path.join(rootDir, '..');
return parentDir !== rootDir ? findInDirOrAncestor(targetFilename, parentDir) : null;
}
function findTsConfigFile() {
var rootDir = path.join(__dirname, '..', '..'); // Start 2 levels up because this package has a tsconfig file of its own
var tsConfigFile = 'tsconfig.json';
var tsConfigFileName = findInDirOrAncestor(tsConfigFile, rootDir);
if (!tsConfigFileName) {
console.error('Could not locate ' + tsConfigFile + ' in ' + rootDir + ' or any ancestor directory.');
}
return tsConfigFileName;
}
function ensureTsConfigContainsTypesEntry(packageName) {
var tsConfigFileName = findTsConfigFile();
if (tsConfigFileName) {
var parsedTsConfig = Hjson.rt.parse(fs.readFileSync(tsConfigFileName, 'utf8'));
parsedTsConfig.compilerOptions = parsedTsConfig.compilerOptions || {};
parsedTsConfig.compilerOptions.types = parsedTsConfig.compilerOptions.types || [];
if (parsedTsConfig.compilerOptions.types.indexOf(packageName) < 0) {
parsedTsConfig.compilerOptions.types.push(packageName);
var hjsonOptions = {
bracesSameLine: true,
multiline: 'off',
quotes: 'all',
separator: true,
space: 2
};
fs.writeFileSync(tsConfigFileName, Hjson.rt.stringify(parsedTsConfig, hjsonOptions), 'utf8');
}
}
}
try {
ensureTsConfigContainsTypesEntry('aspnet-webpack-react');
} catch(ex) {
console.error(ex);
process.exit(0); // Don't break installation
}

View File

@@ -4,3 +4,23 @@ export { addReactHotModuleReplacementConfig } from './HotModuleReplacement';
// compatibility with aspnet-webpack 1.x. In aspnet-webpack 2.0, we can drop the old name (and also deprecate // compatibility with aspnet-webpack 1.x. In aspnet-webpack 2.0, we can drop the old name (and also deprecate
// some other no-longer-supported functionality, such as LoadViaWebpack). // some other no-longer-supported functionality, such as LoadViaWebpack).
export { addReactHotModuleReplacementConfig as addReactHotModuleReplacementBabelTransform } from './HotModuleReplacement'; export { addReactHotModuleReplacementConfig as addReactHotModuleReplacementBabelTransform } from './HotModuleReplacement';
// Workaround for #1066
//
// The issue is that @types/react-router@4.0.12 is incompatible with @types/react@15.0.29
// This is a problem because the ReactReduxSpa template that ships in 2.0.0-preview2 is pinned
// to @types/react@15.0.29 but does *not* declare a direct dependency on @types/react-router,
// which means we end up grabbing the latest @types/react-router.
//
// The temporary solution is for aspnet-webpack-react to add the following extra type information
// that patches the compatibility issue. The longer-term solution will be for the templates to
// pin versions of *every* package in the transitive closure, not just their direct dependencies.
//
// Note that for this workaround to work, the developer also needs 'aspnet-webpack-react' to be
// present in the 'types' array in tsconfig.json. We automate the task of adding that in the
// scripts/postinstall.js file in this package. Later, that action can be removed.
import * as React from 'react';
declare module 'react' {
interface Component<P, S={}> {}
}

View File

@@ -5,7 +5,7 @@
"target": "es5", "target": "es5",
"declaration": true, "declaration": true,
"outDir": ".", "outDir": ".",
"lib": ["es2015"] "lib": ["dom", "es2015"]
}, },
"files": [ "files": [
"src/index.ts" "src/index.ts"