diff --git a/packages/af-webpack/package.json b/packages/af-webpack/package.json index 46f39bc71d2c..dc9ff45ddc9f 100644 --- a/packages/af-webpack/package.json +++ b/packages/af-webpack/package.json @@ -23,6 +23,7 @@ "deprecate": "^1.0.0", "detect-port": "^1.2.1", "didyoumean": "^1.2.1", + "es5-imcompatible-versions": "^0.1.2", "eslint": "^4.7.1", "eslint-config-umi": "^0.1.4", "eslint-loader": "^2.0.0", @@ -40,6 +41,7 @@ "less": "^2.7.2", "less-loader": "^4.0.5", "lodash.isequal": "^4.5.0", + "pkg-up": "^2.0.0", "postcss": "^6.0.11", "postcss-flexbugs-fixes": "^3.2.0", "postcss-loader": "^2.0.6", @@ -48,6 +50,7 @@ "react-error-overlay": "^3.0.0", "requireindex": "^1.1.0", "resolve": "^1.5.0", + "semver": "^5.5.0", "sockjs-client": "1.1.4", "strip-ansi": "3.0.1", "strip-json-comments": "^2.0.1", diff --git a/packages/af-webpack/src/es5ImcompatibleVersions.js b/packages/af-webpack/src/es5ImcompatibleVersions.js new file mode 100644 index 000000000000..f6ff178e677c --- /dev/null +++ b/packages/af-webpack/src/es5ImcompatibleVersions.js @@ -0,0 +1,31 @@ +import { dirname } from 'path'; +import pkgUp from 'pkg-up'; +import { satisfies } from 'semver'; + +const pkgPathCache = {}; +const pkgCache = {}; +const { + config: { 'es5-imcompatible-versions': config }, +} = require('es5-imcompatible-versions/package.json'); + +export function getPkgPath(filePath) { + const dir = dirname(filePath); + if (dir in pkgPathCache) return pkgPathCache[dir]; + pkgPathCache[dir] = pkgUp.sync(filePath); + return pkgPathCache[dir]; +} + +export function shouldTransform(pkgPath) { + if (pkgPath in pkgCache) return pkgCache[pkgPath]; + const { name, version } = require(pkgPath); // eslint-disable-line + pkgCache[pkgPath] = isMatch(name, version); + return pkgCache[pkgPath]; +} + +function isMatch(name, version) { + if (config[name]) { + return Object.keys(config[name]).some(sv => satisfies(version, sv)); + } else { + return false; + } +} diff --git a/packages/af-webpack/src/getConfig.js b/packages/af-webpack/src/getConfig.js index 9c306466b1fc..1cddc65d3dc7 100644 --- a/packages/af-webpack/src/getConfig.js +++ b/packages/af-webpack/src/getConfig.js @@ -25,6 +25,7 @@ import normalizeTheme from './normalizeTheme'; import { applyWebpackConfig } from './applyWebpackConfig'; import readRc from './readRc'; import { stripLastSlash } from './utils'; +import { getPkgPath, shouldTransform } from './es5ImcompatibleVersions'; const { TsConfigPathsPlugin } = require('awesome-typescript-loader'); // eslint-disable-line const debug = require('debug')('af-webpack:getConfig'); @@ -333,6 +334,15 @@ export default function getConfig(opts = {}) { } } + const extraBabelIncludes = opts.extraBabelIncludes || []; + if (opts.es5ImcompatibleVersions) { + extraBabelIncludes.push(a => { + if (a.indexOf('node_modules') === -1) return false; + const pkgPath = getPkgPath(a); + return shouldTransform(pkgPath); + }); + } + const config = { bail: !isDev, devtool: opts.devtool || undefined, @@ -449,7 +459,7 @@ export default function getConfig(opts = {}) { }, ], }, - ...(opts.extraBabelIncludes || []).map(include => { + ...extraBabelIncludes.map(include => { return { test: /\.(js|jsx)$/, include: diff --git a/packages/af-webpack/src/getUserConfig/configs/es5ImcompatibleVersions.js b/packages/af-webpack/src/getUserConfig/configs/es5ImcompatibleVersions.js new file mode 100644 index 000000000000..26077e2c4d13 --- /dev/null +++ b/packages/af-webpack/src/getUserConfig/configs/es5ImcompatibleVersions.js @@ -0,0 +1,13 @@ +import assert from 'assert'; + +export default function() { + return { + name: 'es5ImcompatibleVersions', + validate(val) { + assert( + typeof val === 'boolean', + `The es5ImcompatibleVersions config must be Boolean, but got ${val}`, + ); + }, + }; +}