diff --git a/docs/docs/docs/api/config.md b/docs/docs/docs/api/config.md index 05b2ce19610a..0409eeffcd30 100644 --- a/docs/docs/docs/api/config.md +++ b/docs/docs/docs/api/config.md @@ -1477,6 +1477,8 @@ import SmileUrl, { ReactComponent as SvgSmile } from './smile.svg'; - 默认值:`{ chrome: 80 }` 配置需要兼容的浏览器最低版本。Umi 会根据这个自定引入 polyfill、配置 autoprefixer 和做语法转换等。 +注意:如果`package.json` 中存在 `browsersList`, 或存在 `browsersList` 配置文件, `target` 设置默认失效. + 示例, diff --git a/packages/bundler-webpack/src/config/cssRules.ts b/packages/bundler-webpack/src/config/cssRules.ts index 193e5aabcb93..db741844bb60 100644 --- a/packages/bundler-webpack/src/config/cssRules.ts +++ b/packages/bundler-webpack/src/config/cssRules.ts @@ -1,5 +1,6 @@ import Config from '@umijs/bundler-webpack/compiled/webpack-5-chain'; import { winPath } from '@umijs/utils'; +import browserslist from 'browserslist'; import type { LoaderContext } from 'mini-css-extract-plugin/types/utils'; import { Env, IConfig } from '../types'; @@ -127,6 +128,17 @@ export async function addCSSRules(opts: IOpts) { modules: cssLoaderModulesConfig, ...userConfig.cssLoader, }); + const browsersListConfig = browserslist.loadConfig({ path: opts.cwd }); + const envOpts: any = { + autoprefixer: { + flexbox: 'no-2009', + ...userConfig.autoprefixer, + }, + stage: 3, + }; + if (!browsersListConfig) { + envOpts.browsers = opts.browsers; + } rule .use('postcss-loader') @@ -138,14 +150,7 @@ export async function addCSSRules(opts: IOpts) { ident: 'postcss', plugins: [ require('@umijs/bundler-webpack/compiled/postcss-flexbugs-fixes'), - require('postcss-preset-env')({ - browsers: opts.browsers, - autoprefixer: { - flexbox: 'no-2009', - ...userConfig.autoprefixer, - }, - stage: 3, - }), + require('postcss-preset-env')(envOpts), ].concat(userConfig.extraPostCSSPlugins || []), ...userConfig.postcssLoader, }, diff --git a/packages/bundler-webpack/src/config/javaScriptRules.ts b/packages/bundler-webpack/src/config/javaScriptRules.ts index 9a9f3d45a2cd..2a834edf6141 100644 --- a/packages/bundler-webpack/src/config/javaScriptRules.ts +++ b/packages/bundler-webpack/src/config/javaScriptRules.ts @@ -4,13 +4,14 @@ import { VIRTUAL_ENTRY_DIR, } from '@umijs/mfsu'; import { chalk, lodash, resolve } from '@umijs/utils'; +import { warn } from '@umijs/utils/dist/logger'; +import browsersList from 'browserslist'; import { dirname, isAbsolute } from 'path'; import { ProvidePlugin } from '../../compiled/webpack'; import Config from '../../compiled/webpack-5-chain'; import { MFSU_NAME } from '../constants'; import { Env, IConfig, Transpiler } from '../types'; import { es5ImcompatibleVersionsToPkg, isMatch } from '../utils/depMatch'; - interface IOpts { config: Config; userConfig: IConfig; @@ -124,47 +125,54 @@ export async function addJavaScriptRules(opts: IOpts) { // const prefix = existsSync(join(cwd, 'src')) ? join(cwd, 'src') : cwd; const srcTranspiler = userConfig.srcTranspiler || Transpiler.babel; + const browsersListConfig = browsersList.loadConfig({ path: cwd }); + const options: any = { + // Tell babel to guess the type, instead assuming all files are modules + // https://github.com/webpack/webpack/issues/4039#issuecomment-419284940 + sourceType: 'unambiguous', + babelrc: false, + configFile: false, + cacheDirectory: false, + browserslistConfigFile: !!browsersListConfig, + // process.env.BABEL_CACHE !== 'none' + // ? join(cwd, `.umi/.cache/babel-loader`) + // : false, + // targets: userConfig.targets, + // 解决 vue MFSU 解析 需要 + customize: userConfig.babelLoaderCustomize, + presets: [ + opts.babelPreset || [ + require.resolve('@umijs/babel-preset-umi'), + { + presetEnv: {}, + presetReact: {}, + presetTypeScript: {}, + pluginTransformRuntime: {}, + pluginLockCoreJS: {}, + pluginDynamicImportNode: false, + pluginAutoCSSModules: userConfig.autoCSSModules, + }, + ], + ...opts.extraBabelPresets, + ...(userConfig.extraBabelPresets || []).filter(Boolean), + ], + plugins: [ + useFastRefresh && require.resolve('react-refresh/babel'), + ...opts.extraBabelPlugins, + ...(userConfig.extraBabelPlugins || []), + ].filter(Boolean), + }; + if (!browsersListConfig) { + options.targets = userConfig.targets; + } else if (userConfig.targets) { + warn('检测到项目中存在browsersList配置, targets 配置已失效'); + } srcRules.forEach((rule) => { if (srcTranspiler === Transpiler.babel) { rule .use('babel-loader') .loader(require.resolve('../../compiled/babel-loader')) - .options({ - // Tell babel to guess the type, instead assuming all files are modules - // https://github.com/webpack/webpack/issues/4039#issuecomment-419284940 - sourceType: 'unambiguous', - babelrc: false, - configFile: false, - cacheDirectory: false, - browserslistConfigFile: false, - // process.env.BABEL_CACHE !== 'none' - // ? join(cwd, `.umi/.cache/babel-loader`) - // : false, - targets: userConfig.targets, - // 解决 vue MFSU 解析 需要 - customize: userConfig.babelLoaderCustomize, - presets: [ - opts.babelPreset || [ - require.resolve('@umijs/babel-preset-umi'), - { - presetEnv: {}, - presetReact: {}, - presetTypeScript: {}, - pluginTransformRuntime: {}, - pluginLockCoreJS: {}, - pluginDynamicImportNode: false, - pluginAutoCSSModules: userConfig.autoCSSModules, - }, - ], - ...opts.extraBabelPresets, - ...(userConfig.extraBabelPresets || []).filter(Boolean), - ], - plugins: [ - useFastRefresh && require.resolve('react-refresh/babel'), - ...opts.extraBabelPlugins, - ...(userConfig.extraBabelPlugins || []), - ].filter(Boolean), - }); + .options(options); } else if (srcTranspiler === Transpiler.swc) { rule .use('swc-loader') diff --git a/packages/preset-umi/src/features/polyfill/polyfill.ts b/packages/preset-umi/src/features/polyfill/polyfill.ts index f9bb1b3145ab..2ac2c1750207 100644 --- a/packages/preset-umi/src/features/polyfill/polyfill.ts +++ b/packages/preset-umi/src/features/polyfill/polyfill.ts @@ -1,5 +1,6 @@ import { DEFAULT_BROWSER_TARGETS } from '@umijs/bundler-webpack/dist/constants'; import { getCorejsVersion, importLazy, winPath } from '@umijs/utils'; +import browsersList from 'browserslist'; import { dirname, join } from 'path'; import { IApi } from '../../types'; @@ -27,6 +28,16 @@ export default (api: IApi) => { .map((item: string) => `import '${item}';`) .join('\n') : `import 'core-js';`; + const browsersListConfig = browsersList.loadConfig({ path: api.paths.cwd }); + const envOpts: any = { + useBuiltIns: 'entry', + corejs: getCorejsVersion(join(__dirname, '../../../package.json')), + modules: false, + ignoreBrowserslistConfig: !browsersListConfig, + }; + if (!browsersListConfig) { + envOpts.targets = api.config.targets; + } const { transform } = babelCore; const { code } = transform( ` @@ -39,15 +50,7 @@ export {}; presets: [ [ require.resolve('@umijs/bundler-utils/compiled/babel/preset-env'), - { - useBuiltIns: 'entry', - corejs: getCorejsVersion( - join(__dirname, '../../../package.json'), - ), - modules: false, - targets: api.config.targets, - ignoreBrowserslistConfig: true, - }, + envOpts, ], ], plugins: [ @@ -55,7 +58,7 @@ export {}; ], babelrc: false, configFile: false, - browserslistConfigFile: false, + browserslistConfigFile: !!browsersListConfig, }, )!;