webpack.config.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. "use strict";
  2. const fs = require("fs");
  3. const path = require("path");
  4. const webpack = require("webpack");
  5. const resolve = require("resolve");
  6. const HtmlWebpackPlugin = require("html-webpack-plugin");
  7. const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
  8. const InlineChunkHtmlPlugin = require("react-dev-utils/InlineChunkHtmlPlugin");
  9. const TerserPlugin = require("terser-webpack-plugin");
  10. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  11. const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
  12. const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
  13. const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin");
  14. const WorkboxWebpackPlugin = require("workbox-webpack-plugin");
  15. const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
  16. const getCSSModuleLocalIdent = require("react-dev-utils/getCSSModuleLocalIdent");
  17. const ESLintPlugin = require("eslint-webpack-plugin");
  18. const paths = require("./paths");
  19. const modules = require("./modules");
  20. const getClientEnvironment = require("./env");
  21. const ModuleNotFoundPlugin = require("react-dev-utils/ModuleNotFoundPlugin");
  22. const WebpackBar = require("webpackbar");
  23. const ForkTsCheckerWebpackPlugin =
  24. process.env.TSC_COMPILE_ON_ERROR === "true"
  25. ? require("react-dev-utils/ForkTsCheckerWarningWebpackPlugin")
  26. : require("react-dev-utils/ForkTsCheckerWebpackPlugin");
  27. const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
  28. const createEnvironmentHash = require("./webpack/persistentCache/createEnvironmentHash");
  29. // Source maps are resource heavy and can cause out of memory issue for large source files.
  30. let shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
  31. const reactRefreshRuntimeEntry = require.resolve("react-refresh/runtime");
  32. const reactRefreshWebpackPluginRuntimeEntry = require.resolve(
  33. "@pmmmwh/react-refresh-webpack-plugin"
  34. );
  35. const babelRuntimeEntry = require.resolve("babel-preset-react-app");
  36. const babelRuntimeEntryHelpers = require.resolve(
  37. "@babel/runtime/helpers/esm/assertThisInitialized",
  38. { paths: [babelRuntimeEntry] }
  39. );
  40. const babelRuntimeRegenerator = require.resolve("@babel/runtime/regenerator", {
  41. paths: [babelRuntimeEntry],
  42. });
  43. // Some apps do not need the benefits of saving a web request, so not inlining the chunk
  44. // makes for a smoother build process.
  45. const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== "false";
  46. const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === "true";
  47. const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === "true";
  48. const imageInlineSizeLimit = parseInt(
  49. process.env.IMAGE_INLINE_SIZE_LIMIT || "10000"
  50. );
  51. // Check if TypeScript is setup
  52. const useTypeScript = fs.existsSync(paths.appTsConfig);
  53. // Check if Tailwind config exists
  54. const useTailwind = fs.existsSync(
  55. path.join(paths.appPath, "tailwind.config.js")
  56. );
  57. // Get the path to the uncompiled service worker (if it exists).
  58. const swSrc = paths.swSrc;
  59. // style files regexes
  60. const cssRegex = /\.css$/;
  61. const cssModuleRegex = /\.module\.css$/;
  62. const sassRegex = /\.(scss|sass)$/;
  63. const lessRegex = /\.(less|less)$/;
  64. const sassModuleRegex = /\.module\.(scss|sass)$/;
  65. const lessModuleRegex = /\.module\.(less|less)$/;
  66. const hasJsxRuntime = (() => {
  67. if (process.env.DISABLE_NEW_JSX_TRANSFORM === "true") {
  68. return false;
  69. }
  70. try {
  71. require.resolve("react/jsx-runtime");
  72. return true;
  73. } catch (e) {
  74. return false;
  75. }
  76. })();
  77. // console.log(path.join(__dirname, "../src"))
  78. // console.log(ks)
  79. // This is the production and development configuration.
  80. // It is focused on developer experience, fast rebuilds, and a minimal bundle.
  81. module.exports = function (webpackEnv, params) {
  82. shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
  83. let { configEntry, htmls, CONFIG, isNginx } = params;
  84. const isEnvDevelopment = webpackEnv === "development";
  85. const isEnvProduction = webpackEnv === "production";
  86. // Variable used for enabling profiling in Production
  87. // passed into alias object. Uses a flag if passed into the build command
  88. const isEnvProductionProfile =
  89. isEnvProduction && process.argv.includes("--profile");
  90. // We will provide `paths.publicUrlOrPath` to our app
  91. // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
  92. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
  93. // Get environment variables to inject into our app.
  94. const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1), CONFIG);
  95. const shouldUseReactRefresh = env.raw.FAST_REFRESH;
  96. // common function to get style loaders
  97. const getStyleLoaders = (cssOptions, preProcessor) => {
  98. const loaders = [
  99. isEnvDevelopment && require.resolve("style-loader"),
  100. isEnvProduction && {
  101. loader: MiniCssExtractPlugin.loader,
  102. // css is located in `static/css`, use '../../' to locate index.html folder
  103. // in production `paths.publicUrlOrPath` can be a relative path
  104. options: paths.publicUrlOrPath.startsWith(".")
  105. ? { publicPath: "../../" }
  106. : {},
  107. },
  108. {
  109. loader: require.resolve("css-loader"),
  110. options: cssOptions,
  111. },
  112. {
  113. // Options for PostCSS as we reference these options twice
  114. // Adds vendor prefixing based on your specified browser support in
  115. // package.json
  116. loader: require.resolve("postcss-loader"),
  117. options: {
  118. postcssOptions: {
  119. // Necessary for external CSS imports to work
  120. // https://github.com/facebook/create-react-app/issues/2677
  121. ident: "postcss",
  122. config: false,
  123. plugins: !useTailwind
  124. ? [
  125. "postcss-flexbugs-fixes",
  126. [
  127. "postcss-preset-env",
  128. {
  129. autoprefixer: {
  130. flexbox: "no-2009",
  131. },
  132. stage: 3,
  133. },
  134. ],
  135. // Adds PostCSS Normalize as the reset css with default options,
  136. // so that it honors browserslist config in package.json
  137. // which in turn let's users customize the target behavior as per their needs.
  138. "postcss-normalize",
  139. ]
  140. : [
  141. "tailwindcss",
  142. "postcss-flexbugs-fixes",
  143. [
  144. "postcss-preset-env",
  145. {
  146. autoprefixer: {
  147. flexbox: "no-2009",
  148. },
  149. stage: 3,
  150. },
  151. ],
  152. ],
  153. },
  154. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  155. },
  156. },
  157. ].filter(Boolean);
  158. if (preProcessor) {
  159. loaders.push(
  160. {
  161. loader: require.resolve("resolve-url-loader"),
  162. options: {
  163. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  164. root: paths.appSrc,
  165. },
  166. },
  167. {
  168. loader: require.resolve(preProcessor),
  169. options: {
  170. sourceMap: true,
  171. },
  172. }
  173. );
  174. }
  175. return loaders;
  176. };
  177. return {
  178. target: ["browserslist"],
  179. mode: isEnvProduction ? "production" : isEnvDevelopment && "development",
  180. // Stop compilation early in production
  181. bail: isEnvProduction,
  182. devtool: isEnvProduction
  183. ? shouldUseSourceMap
  184. ? "source-map"
  185. // ?false
  186. : false
  187. : isEnvDevelopment && "cheap-module-source-map",
  188. // These are the "entry points" to our application.
  189. // This means they will be the "root" imports that are included in JS bundle.
  190. // entry: paths.appIndexJs,
  191. entry: configEntry,
  192. output: {
  193. // The build folder.
  194. path: paths.appBuild,
  195. // Add /* filename */ comments to generated require()s in the output.
  196. pathinfo: isEnvDevelopment,
  197. // There will be one main bundle, and one file per asynchronous chunk.
  198. // In development, it does not produce real files.
  199. filename: isEnvProduction
  200. ? "app/[name]/static/js/[name].[contenthash:8].js"
  201. : isEnvDevelopment && "app/[name]/static/js/[name].bundle.js",
  202. // There are also additional JS chunk files if you use code splitting.
  203. chunkFilename: isEnvProduction
  204. ? "app/[name]/static/js/[name].[contenthash:8].chunk.js"
  205. : isEnvDevelopment && "app/[name]/static/js/[name].chunk.js",
  206. assetModuleFilename: "static/media/[name].[hash][ext]",
  207. // webpack uses `publicPath` to determine where the app is being served from.
  208. // It requires a trailing slash, or the file assets will get an incorrect path.
  209. // We inferred the "public path" (such as / or /my-project) from homepage.
  210. publicPath: paths.publicUrlOrPath,
  211. // Point sourcemap entries to original disk location (format as URL on Windows)
  212. devtoolModuleFilenameTemplate: isEnvProduction
  213. ? (info) =>
  214. path
  215. .relative(paths.appSrc, info.absoluteResourcePath)
  216. .replace(/\\/g, "/")
  217. : isEnvDevelopment &&
  218. ((info) =>
  219. path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")),
  220. },
  221. cache: {
  222. type: "filesystem",
  223. version: createEnvironmentHash(env.raw),
  224. cacheDirectory: paths.appWebpackCache,
  225. store: "pack",
  226. buildDependencies: {
  227. defaultWebpack: ["webpack/lib/"],
  228. config: [__filename],
  229. tsconfig: [paths.appTsConfig, paths.appJsConfig].filter((f) =>
  230. fs.existsSync(f)
  231. ),
  232. },
  233. },
  234. infrastructureLogging: {
  235. level: "none",
  236. },
  237. optimization: {
  238. minimize: isEnvProduction,
  239. minimizer: [
  240. // This is only used in production mode
  241. new TerserPlugin({
  242. terserOptions: {
  243. parse: {
  244. // We want terser to parse ecma 8 code. However, we don't want it
  245. // to apply any minification steps that turns valid ecma 5 code
  246. // into invalid ecma 5 code. This is why the 'compress' and 'output'
  247. // sections only apply transformations that are ecma 5 safe
  248. // https://github.com/facebook/create-react-app/pull/4234
  249. ecma: 8,
  250. },
  251. compress: {
  252. ecma: 5,
  253. warnings: false,
  254. // Disabled because of an issue with Uglify breaking seemingly valid code:
  255. // https://github.com/facebook/create-react-app/issues/2376
  256. // Pending further investigation:
  257. // https://github.com/mishoo/UglifyJS2/issues/2011
  258. comparisons: false,
  259. // Disabled because of an issue with Terser breaking valid code:
  260. // https://github.com/facebook/create-react-app/issues/5250
  261. // Pending further investigation:
  262. // https://github.com/terser-js/terser/issues/120
  263. inline: 2,
  264. },
  265. mangle: {
  266. safari10: true,
  267. },
  268. // Added for profiling in devtools
  269. keep_classnames: isEnvProductionProfile,
  270. keep_fnames: isEnvProductionProfile,
  271. output: {
  272. ecma: 5,
  273. comments: false,
  274. // Turned on because emoji and regex is not minified properly using default
  275. // https://github.com/facebook/create-react-app/issues/2488
  276. ascii_only: true,
  277. },
  278. },
  279. }),
  280. // This is only used in production mode
  281. new CssMinimizerPlugin(),
  282. ],
  283. splitChunks: {
  284. chunks: "async", //这表明将选择哪些 chunk 进行优化。当提供一个字符串,有效值为 all,async 和 initial
  285. minSize: 20000, //生成 chunk 的最小体积(以 bytes 为单位)
  286. minRemainingSize: 0,
  287. minChunks: 1, //拆分前必须共享模块的最小 chunks 数
  288. maxAsyncRequests: 30, //按需加载时的最大并行请求数
  289. maxInitialRequests: 30, //入口点的最大并行请求数
  290. enforceSizeThreshold: 50000, //强制执行拆分的体积阈值和其他限制
  291. cacheGroups: {
  292. defaultVendors: {
  293. test: /[\\/]node_modules[\\/]/,
  294. priority: -10,
  295. reuseExistingChunk: true,
  296. },
  297. default: {
  298. minChunks: 2,
  299. priority: -20,
  300. reuseExistingChunk: true,
  301. },
  302. commons: {
  303. name: "commons",
  304. chunks: "initial",
  305. minChunks: 2,
  306. },
  307. },
  308. },
  309. },
  310. resolve: {
  311. // This allows you to set a fallback for where webpack should look for modules.
  312. // We placed these paths second because we want `node_modules` to "win"
  313. // if there are any conflicts. This matches Node resolution mechanism.
  314. // https://github.com/facebook/create-react-app/issues/253
  315. modules: ["node_modules", paths.appNodeModules].concat(
  316. modules.additionalModulePaths || []
  317. ),
  318. // These are the reasonable defaults supported by the Node ecosystem.
  319. // We also include JSX as a common component filename extension to support
  320. // some tools, although we do not recommend using it, see:
  321. // https://github.com/facebook/create-react-app/issues/290
  322. // `web` extension prefixes have been added for better support
  323. // for React Native Web.
  324. extensions: paths.moduleFileExtensions
  325. .map((ext) => `.${ext}`)
  326. .filter((ext) => useTypeScript || !ext.includes("ts")),
  327. alias: {
  328. // Support React Native Web
  329. // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
  330. "react-native": "react-native-web",
  331. // Allows for better profiling with ReactDevTools
  332. ...(isEnvProductionProfile && {
  333. "react-dom$": "react-dom/profiling",
  334. "scheduler/tracing": "scheduler/tracing-profiling",
  335. }),
  336. ...(modules.webpackAliases || {}),
  337. "@": path.resolve(__dirname,'../src'),
  338. "@@":path.resolve(__dirname,'./'),
  339. },
  340. plugins: [
  341. // Prevents users from importing files from outside of src/ (or node_modules/).
  342. // This often causes confusion because we only process files within src/ with babel.
  343. // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
  344. // please link the files into your node_modules/ and let module-resolution kick in.
  345. // Make sure your source files are compiled, as they will not be processed in any way.
  346. new ModuleScopePlugin(paths.appSrc, [
  347. paths.appPackageJson,
  348. reactRefreshRuntimeEntry,
  349. reactRefreshWebpackPluginRuntimeEntry,
  350. babelRuntimeEntry,
  351. babelRuntimeEntryHelpers,
  352. babelRuntimeRegenerator,
  353. ]),
  354. ],
  355. },
  356. module: {
  357. strictExportPresence: true,
  358. rules: [
  359. // Handle node_modules packages that contain sourcemaps
  360. shouldUseSourceMap && {
  361. enforce: "pre",
  362. exclude: /@babel(?:\/|\\{1,2})runtime/,
  363. test: /\.(js|mjs|jsx|ts|tsx|css)$/,
  364. loader: require.resolve("source-map-loader"),
  365. },
  366. {
  367. // "oneOf" will traverse all following loaders until one will
  368. // match the requirements. When no loader matches it will fall
  369. // back to the "file" loader at the end of the loader list.
  370. oneOf: [
  371. // TODO: Merge this config once `image/avif` is in the mime-db
  372. // https://github.com/jshttp/mime-db
  373. {
  374. test: [/\.avif$/],
  375. type: "asset",
  376. mimetype: "image/avif",
  377. parser: {
  378. dataUrlCondition: {
  379. maxSize: imageInlineSizeLimit,
  380. },
  381. },
  382. },
  383. // "url" loader works like "file" loader except that it embeds assets
  384. // smaller than specified limit in bytes as data URLs to avoid requests.
  385. // A missing `test` is equivalent to a match.
  386. {
  387. test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  388. type: "asset",
  389. parser: {
  390. dataUrlCondition: {
  391. maxSize: imageInlineSizeLimit,
  392. },
  393. },
  394. },
  395. {
  396. test: /\.svg$/,
  397. use: [
  398. {
  399. loader: require.resolve("@svgr/webpack"),
  400. options: {
  401. prettier: false,
  402. svgo: false,
  403. svgoConfig: {
  404. plugins: [{ removeViewBox: false }],
  405. },
  406. titleProp: true,
  407. ref: true,
  408. },
  409. },
  410. {
  411. loader: require.resolve("file-loader"),
  412. options: {
  413. name: "static/media/[name].[hash].[ext]",
  414. },
  415. },
  416. ],
  417. issuer: {
  418. and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
  419. },
  420. },
  421. // Process application JS with Babel.
  422. // The preset includes JSX, Flow, TypeScript, and some ESnext features.
  423. {
  424. test: /\.(js|mjs|jsx|ts|tsx)$/,
  425. include: paths.appSrc,
  426. loader: require.resolve("babel-loader"),
  427. options: {
  428. customize: require.resolve(
  429. "babel-preset-react-app/webpack-overrides"
  430. ),
  431. presets: [
  432. [
  433. require.resolve("babel-preset-react-app"),
  434. {
  435. runtime: hasJsxRuntime ? "automatic" : "classic",
  436. },
  437. ],
  438. ],
  439. plugins: [
  440. isEnvDevelopment &&
  441. shouldUseReactRefresh &&
  442. require.resolve("react-refresh/babel"),
  443. // ['import',{libraryName: "antd", style: 'css'}]
  444. ].filter(Boolean),
  445. // This is a feature of `babel-loader` for webpack (not Babel itself).
  446. // It enables caching results in ./node_modules/.cache/babel-loader/
  447. // directory for faster rebuilds.
  448. cacheDirectory: true,
  449. // See #6846 for context on why cacheCompression is disabled
  450. cacheCompression: false,
  451. compact: isEnvProduction,
  452. },
  453. },
  454. // Process any JS outside of the app with Babel.
  455. // Unlike the application JS, we only compile the standard ES features.
  456. {
  457. test: /\.(js|mjs)$/,
  458. exclude: /@babel(?:\/|\\{1,2})runtime/,
  459. loader: require.resolve("babel-loader"),
  460. options: {
  461. babelrc: false,
  462. configFile: false,
  463. compact: false,
  464. presets: [
  465. [
  466. require.resolve("babel-preset-react-app/dependencies"),
  467. { helpers: true },
  468. ],
  469. ],
  470. cacheDirectory: true,
  471. // See #6846 for context on why cacheCompression is disabled
  472. cacheCompression: false,
  473. // Babel sourcemaps are needed for debugging into node_modules
  474. // code. Without the options below, debuggers like VSCode
  475. // show incorrect code and set breakpoints on the wrong lines.
  476. sourceMaps: shouldUseSourceMap,
  477. inputSourceMap: shouldUseSourceMap,
  478. },
  479. },
  480. // "postcss" loader applies autoprefixer to our CSS.
  481. // "css" loader resolves paths in CSS and adds assets as dependencies.
  482. // "style" loader turns CSS into JS modules that inject <style> tags.
  483. // In production, we use MiniCSSExtractPlugin to extract that CSS
  484. // to a file, but in development "style" loader enables hot editing
  485. // of CSS.
  486. // By default we support CSS Modules with the extension .module.css
  487. {
  488. test: cssRegex,
  489. exclude: cssModuleRegex,
  490. use: getStyleLoaders({
  491. importLoaders: 1,
  492. sourceMap: isEnvProduction
  493. ? shouldUseSourceMap
  494. : isEnvDevelopment,
  495. modules: {
  496. mode: "icss",
  497. },
  498. }),
  499. // Don't consider CSS imports dead code even if the
  500. // containing package claims to have no side effects.
  501. // Remove this when webpack adds a warning or an error for this.
  502. // See https://github.com/webpack/webpack/issues/6571
  503. sideEffects: true,
  504. },
  505. // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
  506. // using the extension .module.css
  507. {
  508. test: cssModuleRegex,
  509. use: getStyleLoaders({
  510. importLoaders: 1,
  511. sourceMap: isEnvProduction
  512. ? shouldUseSourceMap
  513. : isEnvDevelopment,
  514. modules: {
  515. mode: "local",
  516. getLocalIdent: getCSSModuleLocalIdent,
  517. },
  518. }),
  519. },
  520. // Opt-in support for SASS (using .scss or .sass extensions).
  521. // By default we support SASS Modules with the
  522. // extensions .module.scss or .module.sass
  523. // {
  524. // test: sassRegex,
  525. // exclude: sassModuleRegex,
  526. // use: getStyleLoaders(
  527. // {
  528. // importLoaders: 3,
  529. // sourceMap: isEnvProduction
  530. // ? shouldUseSourceMap
  531. // : isEnvDevelopment,
  532. // modules: {
  533. // mode: 'icss',
  534. // },
  535. // },
  536. // 'sass-loader'
  537. // ),
  538. // // Don't consider CSS imports dead code even if the
  539. // // containing package claims to have no side effects.
  540. // // Remove this when webpack adds a warning or an error for this.
  541. // // See https://github.com/webpack/webpack/issues/6571
  542. // sideEffects: true,
  543. // },
  544. // // Adds support for CSS Modules, but using SASS
  545. // // using the extension .module.scss or .module.sass
  546. // {
  547. // test: sassModuleRegex,
  548. // use: getStyleLoaders(
  549. // {
  550. // importLoaders: 3,
  551. // sourceMap: isEnvProduction
  552. // ? shouldUseSourceMap
  553. // : isEnvDevelopment,
  554. // modules: {
  555. // mode: 'local',
  556. // getLocalIdent: getCSSModuleLocalIdent,
  557. // },
  558. // },
  559. // 'sass-loader'
  560. // ),
  561. // },
  562. // Opt-in support for SASS (using .scss or .sass extensions).
  563. // By default we support SASS Modules with the
  564. // extensions .module.scss or .module.sass
  565. {
  566. test: lessRegex,
  567. exclude: lessModuleRegex,
  568. use: [
  569. ...getStyleLoaders({
  570. importLoaders: 3,
  571. sourceMap: isEnvProduction
  572. ? shouldUseSourceMap
  573. : isEnvDevelopment,
  574. modules: {
  575. mode: (resourcePath)=>{
  576. if(resourcePath.includes('global.less')){
  577. return 'icss'
  578. }else{
  579. return 'local'
  580. }
  581. },
  582. getLocalIdent: getCSSModuleLocalIdent,
  583. },
  584. }),
  585. {
  586. loader: "less-loader", // compiles Less to CSS
  587. options: {
  588. lessOptions: {
  589. // 如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
  590. modifyVars: {
  591. "primary-color": "#1DA57A",
  592. "link-color": "#1DA57A",
  593. "border-radius-base": "2px",
  594. },
  595. javascriptEnabled: true,
  596. },
  597. },
  598. },
  599. ],
  600. // Don't consider CSS imports dead code even if the
  601. // containing package claims to have no side effects.
  602. // Remove this when webpack adds a warning or an error for this.
  603. // See https://github.com/webpack/webpack/issues/6571
  604. sideEffects: true,
  605. },
  606. // Adds support for CSS Modules, but using SASS
  607. // using the extension .module.scss or .module.sass
  608. {
  609. test: lessModuleRegex,
  610. use: [
  611. ...getStyleLoaders({
  612. importLoaders: 3,
  613. sourceMap: isEnvProduction
  614. ? shouldUseSourceMap
  615. : isEnvDevelopment,
  616. modules: {
  617. mode: "local",
  618. getLocalIdent: getCSSModuleLocalIdent,
  619. },
  620. }),
  621. {
  622. loader: "less-loader", // compiles Less to CSS
  623. options: {
  624. lessOptions: {
  625. // 如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
  626. modifyVars: {
  627. "primary-color": "#1DA57A",
  628. "link-color": "#1DA57A",
  629. "border-radius-base": "2px",
  630. },
  631. javascriptEnabled: true,
  632. },
  633. },
  634. },
  635. ],
  636. },
  637. // "file" loader makes sure those assets get served by WebpackDevServer.
  638. // When you `import` an asset, you get its (virtual) filename.
  639. // In production, they would get copied to the `build` folder.
  640. // This loader doesn't use a "test" so it will catch all modules
  641. // that fall through the other loaders.
  642. {
  643. // Exclude `js` files to keep "css" loader working as it injects
  644. // its runtime that would otherwise be processed through "file" loader.
  645. // Also exclude `html` and `json` extensions so they get processed
  646. // by webpacks internal loaders.
  647. exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
  648. type: "asset/resource",
  649. },
  650. // ** STOP ** Are you adding a new loader?
  651. // Make sure to add the new loader(s) before the "file" loader.
  652. ],
  653. },
  654. ].filter(Boolean),
  655. },
  656. plugins: [
  657. // Generates an `index.html` file with the <script> injected.
  658. // new HtmlWebpackPlugin(
  659. // Object.assign(
  660. // {},
  661. // {
  662. // inject: true,
  663. // template: paths.appHtml,
  664. // },
  665. // isEnvProduction
  666. // ? {
  667. // minify: {
  668. // removeComments: true,
  669. // collapseWhitespace: true,
  670. // removeRedundantAttributes: true,
  671. // useShortDoctype: true,
  672. // removeEmptyAttributes: true,
  673. // removeStyleLinkTypeAttributes: true,
  674. // keepClosingSlash: true,
  675. // minifyJS: true,
  676. // minifyCSS: true,
  677. // minifyURLs: true,
  678. // },
  679. // }
  680. // : undefined
  681. // )
  682. // ),
  683. ...htmls,
  684. // Inlines the webpack runtime script. This script is too small to warrant
  685. // a network request.
  686. // https://github.com/facebook/create-react-app/issues/5358
  687. isEnvProduction &&
  688. shouldInlineRuntimeChunk &&
  689. new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
  690. // Makes some environment variables available in index.html.
  691. // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
  692. // <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
  693. // It will be an empty string unless you specify "homepage"
  694. // in `package.json`, in which case it will be the pathname of that URL.
  695. new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
  696. // This gives some necessary context to module not found errors, such as
  697. // the requesting resource.
  698. new ModuleNotFoundPlugin(paths.appPath),
  699. // Makes some environment variables available to the JS code, for example:
  700. // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
  701. // It is absolutely essential that NODE_ENV is set to production
  702. // during a production build.
  703. // Otherwise React will be compiled in the very slow development mode.
  704. new webpack.DefinePlugin(env.stringified),
  705. // Experimental hot reloading for React .
  706. // https://github.com/facebook/react/tree/main/packages/react-refresh
  707. isEnvDevelopment &&
  708. shouldUseReactRefresh &&
  709. new ReactRefreshWebpackPlugin({
  710. overlay: false,
  711. }),
  712. // Watcher doesn't work well if you mistype casing in a path so we use
  713. // a plugin that prints an error when you attempt to do this.
  714. // See https://github.com/facebook/create-react-app/issues/240
  715. isEnvDevelopment && new CaseSensitivePathsPlugin(),
  716. isEnvProduction &&
  717. new MiniCssExtractPlugin({
  718. // Options similar to the same options in webpackOptions.output
  719. // both options are optional
  720. filename: "app/[name]/static/css/[name].[contenthash:8].css",
  721. chunkFilename: "app/[name]/static/css/[name].[contenthash:8].chunk.css",
  722. ignoreOrder: true,
  723. }),
  724. // Generate an asset manifest file with the following content:
  725. // - "files" key: Mapping of all asset filenames to their corresponding
  726. // output file so that tools can pick it up without having to parse
  727. // `index.html`
  728. // - "entrypoints" key: Array of files which are included in `index.html`,
  729. // can be used to reconstruct the HTML if necessary
  730. new WebpackManifestPlugin({
  731. fileName: "asset-manifest.json",
  732. publicPath: paths.publicUrlOrPath,
  733. generate: (seed, files, entrypoints) => {
  734. console.log(entrypoints);
  735. const manifestFiles = files.reduce((manifest, file) => {
  736. manifest[file.name] = file.path;
  737. return manifest;
  738. }, seed);
  739. const entrypointFiles = entrypoints["login"]?.filter(
  740. (fileName) => !fileName.endsWith(".map")
  741. );
  742. return {
  743. files: manifestFiles,
  744. entrypoints: entrypointFiles,
  745. };
  746. },
  747. }),
  748. // Moment.js is an extremely popular library that bundles large locale files
  749. // by default due to how webpack interprets its code. This is a practical
  750. // solution that requires the user to opt into importing specific locales.
  751. // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
  752. // You can remove this if you don't use Moment.js:
  753. new webpack.IgnorePlugin({
  754. resourceRegExp: /^\.\/locale$/,
  755. contextRegExp: /moment$/,
  756. }),
  757. // Generate a service worker script that will precache, and keep up to date,
  758. // the HTML & assets that are part of the webpack build.
  759. isEnvProduction &&
  760. fs.existsSync(swSrc) &&
  761. new WorkboxWebpackPlugin.InjectManifest({
  762. swSrc,
  763. dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
  764. exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
  765. // Bump up the default maximum size (2mb) that's precached,
  766. // to make lazy-loading failure scenarios less likely.
  767. // See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
  768. maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
  769. }),
  770. // TypeScript type checking
  771. useTypeScript &&
  772. new ForkTsCheckerWebpackPlugin({
  773. async: isEnvDevelopment,
  774. typescript: {
  775. typescriptPath: resolve.sync("typescript", {
  776. basedir: paths.appNodeModules,
  777. }),
  778. configOverwrite: {
  779. compilerOptions: {
  780. sourceMap: isEnvProduction
  781. ? shouldUseSourceMap
  782. : isEnvDevelopment,
  783. skipLibCheck: true,
  784. inlineSourceMap: false,
  785. declarationMap: false,
  786. noEmit: true,
  787. incremental: true,
  788. tsBuildInfoFile: paths.appTsBuildInfoFile,
  789. },
  790. },
  791. context: paths.appPath,
  792. diagnosticOptions: {
  793. syntactic: true,
  794. },
  795. mode: "write-references",
  796. // profile: true,
  797. },
  798. issue: {
  799. // This one is specifically to match during CI tests,
  800. // as micromatch doesn't match
  801. // '../cra-template-typescript/template/src/App.tsx'
  802. // otherwise.
  803. include: [
  804. { file: "../**/src/**/*.{ts,tsx}" },
  805. { file: "**/src/**/*.{ts,tsx}" },
  806. ],
  807. exclude: [
  808. { file: "**/src/**/__tests__/**" },
  809. { file: "**/src/**/?(*.){spec|test}.*" },
  810. { file: "**/src/setupProxy.*" },
  811. { file: "**/src/setupTests.*" },
  812. ],
  813. },
  814. logger: {
  815. infrastructure: "silent",
  816. },
  817. }),
  818. !disableESLintPlugin &&
  819. new ESLintPlugin({
  820. // Plugin options
  821. extensions: ["js", "mjs", "jsx", "ts", "tsx"],
  822. formatter: require.resolve("react-dev-utils/eslintFormatter"),
  823. eslintPath: require.resolve("eslint"),
  824. failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
  825. context: paths.appSrc,
  826. cache: true,
  827. cacheLocation: path.resolve(
  828. paths.appNodeModules,
  829. ".cache/.eslintcache"
  830. ),
  831. // ESLint class options
  832. cwd: paths.appPath,
  833. resolvePluginsRelativeTo: __dirname,
  834. baseConfig: {
  835. extends: [require.resolve("eslint-config-react-app/base")],
  836. rules: {
  837. ...(!hasJsxRuntime && {
  838. "react/react-in-jsx-scope": "error",
  839. }),
  840. },
  841. },
  842. }),
  843. new WebpackBar(),
  844. ].filter(Boolean),
  845. // Turn off performance processing because we utilize
  846. // our own hints via the FileSizeReporter
  847. performance: false,
  848. };
  849. };