"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; function _react() { const data = _interopRequireDefault(require("react")); _react = function _react() { return data; }; return data; } function _webpack() { const data = require("webpack"); _webpack = function _webpack() { return data; }; return data; } function _webpackChain() { const data = _interopRequireDefault(require("webpack-chain")); _webpackChain = function _webpackChain() { return data; }; return data; } function _path() { const data = require("path"); _path = function _path() { return data; }; return data; } function _fs() { const data = require("fs"); _fs = function _fs() { return data; }; return data; } function _os() { const data = require("os"); _os = function _os() { return data; }; return data; } function _assert() { const data = _interopRequireDefault(require("assert")); _assert = function _assert() { return data; }; return data; } var _es5ImcompatibleVersions = require("./es5ImcompatibleVersions"); var _resolveDefine = _interopRequireDefault(require("./resolveDefine")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // import send, { STARTING } from '../send'; function makeArray(item) { if (Array.isArray(item)) return item; return [item]; } function _default(opts) { const _ref = opts || {}, cwd = _ref.cwd; const isDev = opts.isDev || process.env.NODE_ENV === 'development'; const webpackConfig = new (_webpackChain().default)(); // mode webpackConfig.mode('development'); // entry if (opts.entry) { // eslint-disable-next-line guard-for-in for (const key in opts.entry) { const entry = webpackConfig.entry(key); makeArray(opts.entry[key]).forEach(file => { entry.add(file); }); } } // output const absOutputPath = (0, _path().resolve)(cwd, opts.outputPath || 'dist'); webpackConfig.output.path(absOutputPath).filename(`[name].js`).chunkFilename(`[name].async.js`).publicPath(opts.publicPath || undefined).devtoolModuleFilenameTemplate(info => { return (0, _path().relative)(opts.cwd, info.absoluteResourcePath).replace(/\\/g, '/'); }); // resolve webpackConfig.resolve // 不能设为 false,因为 tnpm 是通过 link 处理依赖,设为 false tnpm 下会有大量的冗余模块 .set('symlinks', true).modules.add('node_modules').add((0, _path().join)(__dirname, '../../node_modules')) // Fix yarn global resolve problem .add((0, _path().join)(__dirname, '../../../')).end().extensions.merge(['.web.js', '.wasm', '.mjs', '.js', '.web.jsx', '.jsx', '.web.ts', '.ts', '.web.tsx', '.tsx', '.json']); if (opts.alias) { // eslint-disable-next-line guard-for-in for (const key in opts.alias) { webpackConfig.resolve.alias.set(key, opts.alias[key]); } } // resolveLoader webpackConfig.resolveLoader.modules.add('node_modules').add((0, _path().join)(__dirname, '../../node_modules')).end(); if (!opts.disableDynamicImport && !process.env.__FROM_UMI_TEST) { webpackConfig.optimization.splitChunks({ chunks: 'async', name: 'vendors' }).runtimeChunk(false); } // module -> exclude const DEFAULT_INLINE_LIMIT = 10000; const rule = webpackConfig.module.rule('exclude').exclude.add(/\.json$/).add(/\.(js|jsx|ts|tsx|mjs|wasm)$/).add(/\.(graphql|gql)$/).add(/\.(css|less|scss|sass|styl(us)?)$/); if (opts.urlLoaderExcludes) { opts.urlLoaderExcludes.forEach(exclude => { rule.add(exclude); }); } rule.end().use('url-loader').loader(require.resolve('umi-url-pnp-loader')).options({ limit: opts.inlineLimit || DEFAULT_INLINE_LIMIT, name: 'static/[name].[hash:8].[ext]' }); const babelOptsCommon = { // Tell babel to guess the type, instead assuming all files are modules // https://github.com/webpack/webpack/issues/4039#issuecomment-419284940 sourceType: 'unambiguous', cacheDirectory: process.env.BABEL_CACHE !== 'none', // enable by default babelrc: !!process.env.BABELRC, // disable by default customize: require.resolve('babel-preset-umi/lib/webpack-overrides') }; const babel = opts.babel || {}; const babelOpts = _objectSpread({ presets: [...(babel.presets || []), ...(opts.extraBabelPresets || [])], plugins: [...(babel.plugins || []), ...(opts.extraBabelPlugins || []), [require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: `${require.resolve('../svgr')}?-prettier,-svgo![path]` } } }]] }, babelOptsCommon); if (opts.disableDynamicImport) { babelOpts.plugins = [...(babelOpts.plugins || []), require.resolve('babel-plugin-dynamic-import-node')]; } // module -> eslint if (process.env.ESLINT && process.env.ESLINT !== 'none') { require('./eslint').default(webpackConfig, opts); } // Avoid "require is not defined" errors webpackConfig.module.rule('mjs-require').test(/\.mjs$/).type('javascript/auto').include.add(opts.cwd); // module -> mjs webpackConfig.module.rule('mjs').test(/\.mjs$/).include.add(opts.cwd).end().use('babel-loader').loader(require.resolve('babel-loader')).options(babelOpts); // module -> js webpackConfig.module.rule('js').test(/\.js$/).include.add(opts.cwd).end().exclude.add(/node_modules/).end().use('babel-loader').loader(require.resolve('babel-loader')).options(babelOpts); // module -> jsx // jsx 不 exclude node_modules webpackConfig.module.rule('jsx').test(/\.jsx$/).include.add(opts.cwd).end().use('babel-loader').loader(require.resolve('babel-loader')).options(babelOpts); // module -> extraBabelIncludes // suport es5ImcompatibleVersions const extraBabelIncludes = (opts.extraBabelIncludes || []).concat(a => { if (!a.includes('node_modules')) return false; const pkgPath = (0, _es5ImcompatibleVersions.getPkgPath)(a); return (0, _es5ImcompatibleVersions.shouldTransform)(pkgPath); }); extraBabelIncludes.forEach((include, index) => { const rule = `extraBabelInclude_${index}`; webpackConfig.module.rule(rule).test(/\.jsx?$/).include.add(include).end().use('babel-loader').loader(require.resolve('babel-loader')).options(babelOpts); }); // module -> tsx? const tsConfigFile = opts.tsConfigFile || ((0, _fs().existsSync)((0, _path().join)(opts.cwd, 'tsconfig.json')) ? (0, _path().join)(opts.cwd, 'tsconfig.json') : (0, _path().join)(__dirname, 'tsconfig.default.json')); webpackConfig.module.rule('ts').test(/\.tsx?$/).use('babel-loader').loader(require.resolve('babel-loader')).options(babelOpts).end().use('ts-loader').loader(require.resolve('ts-loader')).options(_objectSpread({ configFile: tsConfigFile, transpileOnly: true, // ref: https://github.com/TypeStrong/ts-loader/blob/fbed24b/src/utils.ts#L23 errorFormatter(error, colors) { const messageColor = error.severity === 'warning' ? colors.bold.yellow : colors.bold.red; return colors.grey('[tsl] ') + messageColor(error.severity.toUpperCase()) + (error.file === '' ? '' : messageColor(' in ') + colors.bold.cyan(`${(0, _path().relative)(cwd, (0, _path().join)(error.context, error.file))}(${error.line},${error.character})`)) + _os().EOL + messageColor(` TS${error.code}: ${error.content}`); } }, opts.typescript || {})); // module -> gql, graphql webpackConfig.module.rule('graphql').test(/\.(graphql|gql)$/).exclude.add(/node_modules/).end().use('graphql-tag-loader').loader('graphql-tag/loader'); // module -> css require('./css').default(webpackConfig, opts); // plugins -> define webpackConfig.plugin('define').use(require('webpack/lib/DefinePlugin'), [(0, _resolveDefine.default)(opts)]); // plugins -> progress bar const NO_PROGRESS = process.env.PROGRESS === 'none'; if (!process.env.__FROM_UMI_TEST) { if (!process.env.CI && !NO_PROGRESS) { if (process.platform === 'win32') { webpackConfig.plugin('progress').use(require('progress-bar-webpack-plugin')); } else { webpackConfig.plugin('progress').use(require('webpackbar'), [{ color: 'green', reporters: ['fancy'] }]); } } } // 没用到,先注释了。 // plugins -> progress report // webpackConfig.plugin('progressReport').use(ProgressPlugin, [ // percentage => { // send({ // type: STARTING, // progress: { // percentage, // }, // }); // }, // ]); // plugins -> ignore moment locale if (opts.ignoreMomentLocale) { webpackConfig.plugin('ignore-moment-locale').use(require('webpack/lib/IgnorePlugin'), [/^\.\/locale$/, /moment$/]); } // plugins -> analyze if (process.env.ANALYZE && !opts.ssr || process.env.ANALYZE_SSR && opts.ssr) { webpackConfig.plugin('bundle-analyzer').use(require('umi-webpack-bundle-analyzer').BundleAnalyzerPlugin, [{ analyzerMode: process.env.ANALYZE_MODE || 'server', analyzerPort: process.env.ANALYZE_PORT || 8888, openAnalyzer: process.env.ANALYZE_OPEN !== 'none', // generate stats file while ANALYZE_DUMP exist generateStatsFile: !!process.env.ANALYZE_DUMP, statsFilename: process.env.ANALYZE_DUMP || 'stats.json', logLevel: process.env.ANALYZE_LOG_LEVEL || 'info', defaultSizes: 'parsed' // stat // gzip }]); } // plugins -> analyze report if (process.env.ANALYZE_REPORT) { webpackConfig.plugin('bundle-analyzer-reporter').use(require('umi-webpack-bundle-analyzer').BundleAnalyzerPlugin, [{ analyzerMode: 'disabled', // 关闭 analyzer server generateReportFile: true, // 开启报告生成功能 reportDepth: 2, // 裁剪深度 2 reportDir: process.cwd(), statsFilename: process.env.ANALYZE_DUMP || 'bundlestats.json' // 默认生成到 bundlestats.json }]); } if (process.env.DUPLICATE_CHECKER) { webpackConfig.plugin('duplicate-package-checker').use(require('duplicate-package-checker-webpack-plugin')); } if (process.env.FORK_TS_CHECKER) { webpackConfig.plugin('fork-ts-checker').use(require('fork-ts-checker-webpack-plugin'), [{ formatter: 'codeframe' }]); } // plugins -> copy if ((0, _fs().existsSync)((0, _path().join)(opts.cwd, 'public'))) { webpackConfig.plugin('copy-public').use(require('copy-webpack-plugin'), [[{ from: (0, _path().join)(opts.cwd, 'public'), to: absOutputPath, toType: 'dir' }]]); } if (opts.copy) { makeArray(opts.copy).forEach((copy, index) => { if (typeof copy === 'string') { copy = { from: (0, _path().join)(opts.cwd, copy), to: absOutputPath }; } webpackConfig.plugin(`copy-${index}`).use(require('copy-webpack-plugin'), [[copy]]); }); } if (!process.env.__FROM_UMI_TEST) { // filter `Conflicting order between` warning webpackConfig.plugin('filter-css-conflicting-warnings').use(require('./FilterCSSConflictingWarning').default); // plugins -> friendly-errors const _process$env$CLEAR_CO = process.env.CLEAR_CONSOLE, CLEAR_CONSOLE = _process$env$CLEAR_CO === void 0 ? 'none' : _process$env$CLEAR_CO; webpackConfig.plugin('friendly-errors').use(require('friendly-errors-webpack-plugin'), [{ clearConsole: CLEAR_CONSOLE !== 'none' }]); } // externals if (opts.externals) { webpackConfig.externals(opts.externals); } // node webpackConfig.node.merge({ setImmediate: false, process: 'mock', dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' }); if (isDev) { require('./dev').default(webpackConfig, opts); } else { require('./prod').default(webpackConfig, opts); } if (opts.chainConfig) { (0, _assert().default)(typeof opts.chainConfig === 'function', `opts.chainConfig should be function, but got ${opts.chainConfig}`); opts.chainConfig(webpackConfig); } let config = webpackConfig.toConfig(); if (process.env.SPEED_MEASURE && !opts.ssr) { const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); const smpOption = process.env.SPEED_MEASURE === 'CONSOLE' ? { outputFormat: 'human', outputTarget: console.log } : { outputFormat: 'json', outputTarget: (0, _path().join)(process.cwd(), 'speed-measure.json') }; const smp = new SpeedMeasurePlugin(smpOption); config = smp.wrap(config); } return config; }