{"id":10006431,"date":"2022-09-08T08:13:40","date_gmt":"2022-09-08T00:13:40","guid":{"rendered":"https:\/\/ityet.com\/?p=10006431"},"modified":"2022-09-08T08:13:40","modified_gmt":"2022-09-08T00:13:40","slug":"%e4%bb%8e0%e5%88%b01%e4%bd%bf%e7%94%a8webpack5-react-ts%e6%9e%84%e5%bb%ba%e6%a0%87%e5%87%86%e5%8c%96%e5%ba%94%e7%94%a8","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006431","title":{"rendered":"\u4ece0\u52301\u4f7f\u7528Webpack5 + React + TS\u6784\u5efa\u6807\u51c6\u5316\u5e94\u7528"},"content":{"rendered":"<p>\u7b80\u4ecb\uff1a\u00a0\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u89e3\u5982\u4f55\u4ece\u4e00\u4e2a\u7a7a\u76ee\u5f55\u5f00\u59cb\uff0c\u5efa\u7acb\u8d77\u4e00\u4e2a\u57fa\u4e8ewebpack + react + typescript\u7684\u6807\u51c6\u5316\u524d\u7aef\u5e94\u7528\u3002<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444955\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u4f5c\u8005 | \u5218\u7687\u900a(\u606a\u8bed)\u6765\u6e90 | \u963f\u91cc\u5f00\u53d1\u8005\u516c\u4f17\u53f7\u524d\u8a00\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u89e3\u5982\u4f55\u4ece\u4e00\u4e2a\u7a7a\u76ee\u5f55\u5f00\u59cb\uff0c\u5efa\u7acb\u8d77\u4e00\u4e2a\u57fa\u4e8ewebpack + react + typescript\u7684\u6807\u51c6\u5316\u524d\u7aef\u5e94\u7528\u3002\u6280\u672f\u6808: webpack5 + React18 + TS\u5de5\u7a0b\u5316: eslint + prettier + husky + git hooks\u652f\u6301\u56fe\u7247\u3001less\u3001sass\u3001fonts\u3001\u6570\u636e\u8d44\u6e90(JSON\u3001csv\u3001tsv\u7b49)\u3001Antd\u6309\u9700\u52a0\u8f7d\u4ee5\u53ca\u4e3b\u9898\u652f\u6301\u70ed\u66f4\u65b0\u3001\u8d44\u6e90\u538b\u7f29\u3001\u4ee3\u7801\u5206\u79bb\uff08\u52a8\u6001\u5bfc\u5165\u3001\u61d2\u52a0\u8f7d\u7b49\uff09\u3001\u7f13\u5b58\u3001devServer\u80cc\u666f\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528create-react-app\u6216\u8005\u98de\u51b0\u7b49\u811a\u624b\u67b6\u5de5\u5177\uff0c\u90a3\u4e48\uff0c\u4e3a\u4ec0\u4e48\u6211\u4eec\u8981\u81ea\u5df1\u6765\u642d\u5efa\u4e00\u4e2a\u6807\u51c6\u5316\u9879\u76ee\uff1f\u539f\u56e0\u5f53\u6211\u4eec\u4f7f\u7528\u4f18\u79c0\u7684\u811a\u624b\u67b6\u5de5\u5177\u5f00\u53d1\u9879\u76ee\u65f6\uff0c\u5f53\u7136\u4f1a\u63d0\u5347\u5f88\u591a\u4fbf\u5229\uff0c\u4ed6\u4eec\u7684\u529f\u80fd\u66f4\u5168\u9762\u3001\u6027\u80fd\u66f4\u5f3a\u5927\uff0c\u4f46\u662f\u5728\u8fd9\u4e9b\u503c\u5f97\u5b66\u4e60\u7684\u699c\u6837\u9762\u524d\uff0c\u6211\u4eec\u9700\u8981\u4ece\u96f6\u5f00\u59cb\uff0c\u52a8\u624b\u53bb\u5b9e\u73b0\u6bcf\u4e00\u4e2a\u7ec6\u8282\u548c\u529f\u80fd\uff0c\u770b\u7684\u518d\u591a\u90fd\u4e0d\u5982\u81ea\u5df1\u52a8\u624b\u5b9e\u73b0\u4e00\u4e2ademo\u66f4\u6709\u6548\u679c\u3002\u5e76\u4e14\u52a8\u624b\u5b9e\u8df5\u4e5f\u53ef\u4ee5\u5e2e\u52a9\u6211\u4eec\u7406\u89e3\u9879\u76ee\u6253\u5305\u548c\u7f16\u8bd1\u7684\u539f\u7406\uff0c\u8fdb\u800c\u63d0\u5347\u81ea\u5df1\u7684\u6280\u672f\u719f\u7ec3\u5ea6\uff0c\u6269\u5c55\u6211\u4eec\u7684\u77e5\u8bc6\u9762\u3002Webpack \u5b9e\u73b0\u5de5\u7a0b\u5316\u65b9\u65b9\u9762\u9762\u7684\u529f\u80fd\uff0c\u81ea\u7136\u4e0d\u662f all in one code\u5b9e\u73b0\u7684\u3002\u4ece Webpack \u7684\u8bbe\u8ba1\u7406\u5ff5\u548c\u5b9e\u73b0\u539f\u7406\u4e2d\uff0c\u6211\u4eec\u80fd\u63a5\u89e6\u5230\u5de5\u7a0b\u5316\u65b9\u9762\u7684\u77e5\u8bc6\uff1a\u67b6\u6784\u6269\u5c55\u3001\u63d2\u4ef6\u5316\u3001\u7f13\u5b58\u673a\u5236\u3002\u5b66\u4e60Webpack\u4e5f\u4ee3\u8868\u7740\u5b66\u4e60\u524d\u7aef\u7684\u53d1\u5c55\u8d8b\u52bf\uff1a\u4f8b\u5982\u5728webpack\u7684\u7adf\u5bf9Vite\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b66\u5230bundleless\u7684\u7406\u5ff5\uff0c\u8df3\u8fc7\u4e86\u4f20\u7edf\u7684\u6253\u5305\u8fd9\u4e2a\u6982\u5ff5\uff0c\u5e76\u4e14\u5176\u4ed6\u5148\u8fdb\u7406\u5ff5\u90fd\u662f\u6211\u4eec\u9700\u8981\u53bb\u5b66\u4e60\u7684\u5730\u65b9\u3002\u5f00\u53d1\u4e2d\uff0c\u6211\u4eec\u53d1\u73b0\u4f7f\u7528def\u3001aone\u7b49\u751f\u6210\u4e00\u4e2a\u6210\u719f\u7684\u524d\u7aef\u9879\u76ee\u6a21\u7248\uff0c\u4e0d\u96be\u4f1a\u53d1\u73b0\uff0c\u9879\u76ee\u4e2d\u7684babel\u3001weback\u3001prettier\u3001loader\u7b49\u914d\u7f6e\u6587\u4ef6\u7f3a\u5931\uff0c\u800c\u4e14\u96be\u4ee5\u4fee\u6539\u73b0\u6210\u7684\u811a\u624b\u67b6\u914d\u7f6e\uff0c\u53ef\u6269\u5c55\u80fd\u529b\u8f83\u5f31\u3002\u5bfc\u81f4\u5728\u6027\u80fd\u4f18\u5316\u65b9\u9762\u80fd\u505a\u7684\u5de5\u4f5c\u6709\u9650\uff0c\u4f7f\u5f97\u5f00\u53d1\u53d7\u5230\u9650\u5236\u3002\u9879\u76ee\u7ed3\u6784\u76ee\u5f55\u251c\u2500\u2500 dist                                \/\/ \u9ed8\u8ba4\u7684 build \u8f93\u51fa\u76ee\u5f55<br \/>\u251c\u2500\u2500 .husky                              \/\/ pre-commit hook<br \/>\u251c\u2500\u2500 webpack.config.js                   \/\/ \u5168\u5c40\u914d\u7f6e\u6587\u4ef6\u53cawebpack\u914d\u7f6e\u6587\u4ef6<br \/>\u251c\u2500\u2500 test                                \/\/ \u6d4b\u8bd5\u76ee\u5f55<br \/>\u2514\u2500\u2500 src                                 \/\/ \u6e90\u7801\u76ee\u5f55<\/p>\n<pre><code>\u251c\u2500\u2500 assets                          \/\/ \u516c\u5171\u7684\u6587\u4ef6\uff08\u5982image\u3001css\u3001font\u7b49\uff09\n\u251c\u2500\u2500 components                      \/\/ \u9879\u76ee\u7ec4\u4ef6\n\u251c\u2500\u2500 constants                       \/\/ \u5e38\u91cf\/\u63a5\u53e3\u5730\u5740\u7b49\n\u251c\u2500\u2500 routes                          \/\/ \u8def\u7531\n\u251c\u2500\u2500 utils                           \/\/ \u5de5\u5177\u5e93\n\u251c\u2500\u2500 pages                           \/\/ \u9875\u9762\u6a21\u5757\n    \u251c\u2500\u2500 Home                        \/\/ Home\u6a21\u5757\uff0c\u5efa\u8bae\u7ec4\u4ef6\u7edf\u4e00\u5927\u5199\u5f00\u5934\n    \u251c\u2500\u2500 ...\n\u251c\u2500\u2500 App.tsx                         \/\/ react\u9876\u5c42\u6587\u4ef6\n\u251c\u2500\u2500 typing                          \/\/ ts\u7c7b\u578b\u6587\u4ef6<\/code><\/pre>\n<p>\u251c\u2500\u2500 .editorconfig                       \/\/ IDE\u683c\u5f0f\u89c4\u8303<br \/>\u251c\u2500\u2500 .eslintignore                       \/\/ eslint\u5ffd\u7565<br \/>\u251c\u2500\u2500 .eslintrc                           \/\/ eslint\u914d\u7f6e\u6587\u4ef6<br \/>\u251c\u2500\u2500 .gitignore                          \/\/ git\u5ffd\u7565<br \/>\u251c\u2500\u2500 .prettierrc                         \/\/ prettierc\u914d\u7f6e\u6587\u4ef6<br \/>\u251c\u2500\u2500 .babelrc                         \/\/ babel\u914d\u7f6e\u6587\u4ef6<br \/>\u251c\u2500\u2500 LICENSE.md                          \/\/ LICENSE<br \/>\u251c\u2500\u2500 package.json                        \/\/ package<br \/>\u251c\u2500\u2500 README.md                           \/\/ README<br \/>\u251c\u2500\u2500 tsconfig.json                       \/\/ typescript\u914d\u7f6e\u6587\u4ef6\u4f9d\u8d56 &#8220;dependencies&#8221;: {<\/p>\n<pre><code>&quot;antd&quot;: &quot;^4.22.4&quot;, \/\/ \u61c2\u5f97\u90fd\u61c2\n&quot;react&quot;: &quot;^18.2.0&quot;, \/\/ \u61c2\u5f97\u90fd\u61c2\n&quot;react-dom&quot;: &quot;^18.2.0&quot; \/\/ \u61c2\u5f97\u90fd\u61c2<\/code><\/pre>\n<p>},<br \/>  &#8220;devDependencies&#8221;: {<\/p>\n<pre><code>\/\/ babel\u5168\u5bb6\u6876\n&quot;@babel\/core&quot;: &quot;^7.18.10&quot;,\n&quot;@babel\/plugin-proposal-class-properties&quot;: &quot;^7.18.6&quot;, \/\/ React class\u652f\u6301\n&quot;@babel\/plugin-transform-runtime&quot;: &quot;^7.18.10&quot;, \/\/ \u62bd\u79bb\u63d0\u53d6 Babel\u7684\u6ce8\u5165\u4ee3\u7801\uff0c\u9632\u6b62\u91cd\u590d\u52a0\u8f7d\uff0c\u51cf\u5c0f\u4f53\u79ef\n&quot;@babel\/preset-env&quot;: &quot;^7.18.10&quot;, \/\/ \u63d0\u4f9b\u7684\u9884\u8bbe\uff0c\u5141\u8bb8\u6211\u4eec\u4f7f\u7528\u6700\u65b0\u7684JavaScript\n&quot;@babel\/preset-react&quot;: &quot;^7.18.6&quot;, \/\/ react\u652f\u6301\n  \n\/\/ ts\u7c7b\u578b\u68c0\u67e5\n&quot;@types\/node&quot;: &quot;^18.6.4&quot;,\n&quot;@types\/react&quot;: &quot;^18.0.15&quot;,\n&quot;@types\/react-dom&quot;: &quot;^18.0.6&quot;,\n\/\/ @types \u5f00\u5934\u7684\u662f\u5bf9\u5e94\u5305\u7684 TypeScript \u7c7b\u578b\u58f0\u660e\n&quot;@typescript-eslint\/eslint-plugin&quot;: &quot;^5.33.0&quot;,\n&quot;@typescript-eslint\/parser&quot;: &quot;^5.33.0&quot;,\n  \n\/\/ webpack loader\uff1a\u89e3\u6790\u5bf9\u5e94\u6587\u4ef6\n&quot;csv-loader&quot;: &quot;^3.0.5&quot;,\n&quot;sass-loader&quot;: &quot;^13.0.2&quot;,\n&quot;xml-loader&quot;: &quot;^1.2.1&quot;,\n&quot;ts-loader&quot;: &quot;^9.3.1&quot;,\n&quot;less-loader&quot;: &quot;^11.0.0&quot;,\n  \n\/\/ eslint\u5168\u5bb6\u6876\n&quot;eslint&quot;: &quot;^8.21.0&quot;,\n&quot;eslint-config-ali&quot;: &quot;^14.0.1&quot;, \/\/ ali\u524d\u7aef\u89c4\u7ea6\n&quot;eslint-config-prettier&quot;: &quot;^8.5.0&quot;, \/\/ \u5173\u95ed\u6240\u6709\u4e0d\u5fc5\u8981\u6216\u53ef\u80fd\u4e0e[Prettier]\u51b2\u7a81\u7684\u89c4\u5219\n&quot;eslint-import-resolver-typescript&quot;: &quot;^3.4.0&quot;, \/\/ \u6dfb\u52a0 ts \u8bed\u6cd5\u652f\u6301  eslint-plugin-import\n&quot;eslint-plugin-import&quot;: &quot;^2.26.0&quot;, \/\/ ES6+  import\/export \u8bed\u6cd5\u652f\u6301\n&quot;eslint-plugin-prettier&quot;: &quot;^4.2.1&quot;, \/\/ prettier\u8bed\u6cd5\u652f\u6301\n&quot;eslint-plugin-react&quot;: &quot;^7.30.1&quot;, \/\/ react\u8bed\u6cd5\u652f\u6301\n&quot;eslint-plugin-react-hooks&quot;: &quot;^4.6.0&quot;, \/\/ hooks\u8bed\u6cd5\u652f\u6301\n&quot;eslint-webpack-plugin&quot;: &quot;^3.2.0&quot;, \n\n\/\/ webpack plugin\n&quot;fork-ts-checker-webpack-plugin&quot;: &quot;^7.2.13&quot;, \/\/ \u907f\u514dwebpack\u4e2d\u68c0\u6d4bts\u7c7b\u578b\n&quot;html-webpack-plugin&quot;: &quot;^5.5.0&quot;, \/\/ \u7b80\u5316HTML\u6587\u4ef6\u7684\u521b\u5efa \uff0c\u914d\u5408webpack\u5305\u542bhash\u7684bundle\u4f7f\u7528\n&quot;mini-css-extract-plugin&quot;: &quot;^2.6.1&quot;, \/\/ css\u62c6\u5206\n&quot;optimize-css-assets-webpack-plugin&quot;: &quot;^6.0.1&quot;, \/\/ css\u538b\u7f29\n&quot;terser-webpack-plugin&quot;: &quot;^5.3.3&quot;, \/\/ \u4f7f\u7528 terser \u538b\u7f29 js \uff08terser \u662f\u4e00\u4e2a\u7ba1\u7406\u548c\u538b\u7f29 ES6+ \u7684\u5de5\u5177\uff09\n&quot;webpack-bundle-analyzer&quot;: &quot;^4.5.0&quot;, \/\/ webpack\u6253\u5305\u4f53\u79ef\u53ef\u89c6\u5316\u5206\u6790\n&quot;webpack-cli&quot;: &quot;^4.10.0&quot;, \/\/ \u63d0\u4f9b\u811a\u624b\u67b6\u547d\u4ee4\n&quot;webpack&quot;: &quot;^5.74.0&quot;, \/\/ webpack\u5f15\u64ce\n&quot;webpack-dev-server&quot;: &quot;^4.9.3&quot;, \/\/ \u5f00\u53d1\u73af\u5883\u7684live server\n \n\/\/ \u5de5\u5177\n&quot;husky&quot;: &quot;^8.0.1&quot;, \/\/ \u81ea\u52a8\u914d\u7f6e Git hooks \u94a9\u5b50\n&quot;less&quot;: &quot;^4.1.3&quot;, \/\/ css\u7c7b\u578b\n&quot;sass&quot;: &quot;^1.54.3&quot;, \/\/ css\u7c7b\u578b\n&quot;typescript&quot;: &quot;^4.7.4&quot;, \/\/ ts\n&quot;lint-staged&quot;: &quot;^13.0.3&quot;, \/\/ \u5bf9\u6682\u5b58\u7684git\u6587\u4ef6\u8fd0\u884clinter\n\n\/\/ prettier \u683c\u5f0f\u5316\n&quot;prettier&quot;: &quot;^2.7.1&quot;,\n&quot;pretty-quick&quot;: &quot;^3.1.3&quot;, \/\/ \u5728\u66f4\u6539\u7684\u6587\u4ef6\u4e0a\u8fd0\u884c prettier<\/code><\/pre>\n<p>}\u5b9e\u73b0\u8fc7\u7a0b\u9879\u76ee\u521d\u59cb\u5316\u9996\u5148\u4ece\u4e00\u4e2a\u7a7a\u76ee\u5f55\u5f00\u59cb\uff0c\u5bf9\u9879\u76ee\u521d\u59cb\u5316\uff1amkdir demo<br \/>cd demo<br \/>git init<br \/>npm initReact\u548cBabel\u5f15\u5165\u5bf9\u4e8e\u4e00\u4e2aReact\u9879\u76ee\uff0c\u6211\u4eec\u9996\u5148\u8981\u5b89\u88c5React\uff0c\u5199\u4e00\u4e2aHello World\uff01\u5b89\u88c5\u6211\u4eec\u4e3b\u8981\u7684\u9879\u76ee\u4f9d\u8d56\uff1atnpm i -S react react-dom\u7531\u4e8e\u6211\u4eec\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6700\u65b0\u7684ECMAScript\u8bed\u6cd5\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981Babel\u6765\u8f6c\u4e49\u4e3aES5\u6216\u8005ES6\u3002\u5b89\u88c5\u6211\u4eec\u7684Babel\u6765\u63d0\u9ad8\u517c\u5bb9\u6027:tnpm i -D @babel\/core babel-preset-env babel-preset-react @babel\/plugin-proposal-class-properties@babel\/core: babel\u8f6c\u7801\u7684\u6838\u5fc3\u5f15\u64cebabel-preset-env: \u6dfb\u52a0\u5bf9ES5\u3001ES6\u7684\u652f\u6301babel-preset-react: \u6dfb\u52a0\u5bf9JSX\u7684\u652f\u6301@babel\/plugin-proposal-class-properties: \u5bf9React\u4e2dclass\u7684\u652f\u6301Webpack\u5f15\u5165tnpm i -D webpack webpack-cli webpack-dev-server html-webpack-pluginwebpack: weback\u63d2\u4ef6\u7684\u6838\u5fc3\u4f9d\u8d56webpack-cli: \u4e3a\u63d2\u4ef6\u63d0\u4f9b\u547d\u4ee4\u884c\u5de5\u5177webpack-dev-server: \u5e2e\u52a9\u542f\u52a8live serverhtml-webpack-plugin: \u5e2e\u52a9\u521b\u5efaHTML\u6a21\u7248Babel\u914d\u7f6e.babelrc\u4e2d\u6dfb\u52a0\u57fa\u672c\u914d\u7f6e:{<br \/>  &#8220;presets&#8221;: [&#8220;@babel\/react&#8221;, &#8220;@babel\/env&#8221;],<br \/>  &#8220;plugins&#8221;: [&#8220;@babel\/plugin-proposal-class-properties&#8221;]<br \/>}Babel PluginBabel\u662f\u4ee3\u7801\u8f6c\u6362\u5668\uff0c\u501f\u52a9Babel\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u6700\u6d41\u884c\u7684js\u5199\u6cd5\uff0c\u800cplugin\u5c31\u662f\u5b9e\u73b0Babel\u529f\u80fd\u7684\u6838\u5fc3\u3002\u00a0<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444956\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u00a0\u8fd9\u91cc\u7684\u914d\u7f6e\u662f\u4e3a\u4e86\u652f\u6301react\u4e2dclass\u7684\u5199\u6cd5\u3002Babel PresetBabel\u7684Plugin\u4e00\u822c\u62c6\u6210\u5c3d\u53ef\u80fd\u5c0f\u7684\u7c92\u5ea6\uff0c\u5f00\u53d1\u8005\u53ef\u4ee5\u6309\u9700\u5f15\u8fdb\uff0c\u4f8b\u5982ES6\u5230ES5\u7684\u529f\u80fd\uff0c\u5b98\u65b9\u63d0\u4f9b\u4e8620+\u63d2\u4ef6\uff0c\u8fd9\u6837\u53ef\u4ee5\u63d0\u9ad8\u6027\u80fd\u548c\u6269\u5c55\u6027\uff0c\u4f46\u662f\u5f88\u591a\u65f6\u5019\u9010\u4e2a\u5f15\u5165\u5c31\u5f88\u8ba9\u4eba\u5934\u5927\uff0c\u800cBabel Preset\u5c31\u662f\u4e3a\u6b64\u800c\u751f\uff0c\u53ef\u4ee5\u89c6\u4e3aPresets\u662f\u76f8\u5173Plugins\u7684\u96c6\u5408\u3002@babel\/react: \u652f\u6301\u4e86React\u6240\u6709\u7684\u8f6c\u7801\u9700\u6c42@babel\/env: \u4e0d\u5938\u5f20\u6ef4\u8bb2\uff0c\u4ec5\u9700\u8981\u5b83\u81ea\u5df1\u5185\u90e8\u7684\u914d\u7f6e\u9879\uff0c\u5c31\u53ef\u4ee5\u5b8c\u6210\u73b0\u4ee3JS\u5de5\u7a0b\u51e0\u4e4e\u6240\u6709\u7684\u8f6c\u7801\u9700\u6c42Webpack\u57fa\u672c\u914d\u7f6e\u65b0\u5efa\u4e00\u4e2awebpack.config.js\u6587\u4ef6\u3002\/\/webpack.config.js<br \/>const path = require(&#8216;path&#8217;);<br \/>const HtmlWebpackPlugin = require(&#8216;html-webpack-plugin&#8217;);<br \/>module.exports = {<br \/>   entry: &#8216;.\/src\/index.js&#8217;,<br \/>   output: {<\/p>\n<pre><code>  path: path.join(__dirname, '\/dist'),\n  filename: 'bundle.js'<\/code><\/pre>\n<p>},<br \/>   devServer: {<\/p>\n<pre><code>  port: 8080<\/code><\/pre>\n<p>},<br \/>   module: {<\/p>\n<pre><code>  rules: [\n     {\n        test: \/\/.jsx?$\/,\n        exclude: \/node_modules\/,\n        loader: 'babel-loader',\n     },\n     {\n        test: \/\/.css$\/,\n        use: [ 'style-loader', 'css-loader' ]\n    }\n  ]<\/code><\/pre>\n<p>},<br \/>   plugins:[<\/p>\n<pre><code>   new HtmlWebpackPlugin({\n        template: path.join(__dirname,'\/src\/index.html')\n   }) <\/code><\/pre>\n<p>]<br \/>}entry: \u5165\u53e3\uff0c\u5f00\u59cb\u6253\u5305\u7684\u8d77\u70b9output: \u6253\u5305\u6587\u4ef6\u7684\u5730\u5740devServer: live server\u914d\u7f6etest: \u4f7f\u7528loader\u7684\u6587\u4ef6\u7c7b\u578bloader: \u5c06\u8981\u4f7f\u7528\u7684loaderPackage.json\u57fa\u672c\u914d\u7f6e&#8221;start&#8221;: &#8220;webpack serve &#8211;mode development &#8211;open &#8211;hot&#8221;,<br \/>&#8220;build&#8221;: &#8220;webpack &#8211;mode production&#8221;mode: process.env.NODE_ENV &#8211;&gt; development, \u4e3amodules\u548cchunks\u542f\u7528\u6709\u610f\u4e49\u7684\u540d\u79f0open: \u544a\u8bc9server\u5728\u670d\u52a1\u542f\u52a8\u540e\u6253\u5f00\u9ed8\u8ba4\u6d4f\u89c8\u5668hot: \u5f00\u542f\u70ed\u66f4\u65b0\u5199\u4e00\u4e2aReact Demo\u76ee\u524d\u7684\u9879\u76ee\u7ed3\u6784\u5982\u4e0b\u56fe\u6240\u793a\uff1a\u00a0<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444957\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u00a0js\u548chtml\u6587\u4ef6\u5982\u4e0b\u56fe\u6240\u793a\uff1a<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444958\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u6700\u540e\uff0c\u53ea\u8981start\u4e00\u4e0b\uff0c\u9879\u76ee\u5c31\u4f1a\u542f\u52a8\u57288080\u7aef\u53e3\u3002TypeScript\u914d\u7f6etnpm install -D typescript ts-loader @types\/node @types\/react @types\/react-domtypescript: TypeScript\u7684\u4e3b\u8981\u5f15\u64cets-loader: \u8f6c\u4e49.ts &#8211;&gt; .js \u5e76\u6253\u5305@types\/node @types\/react @types\/react-dom: \u5bf9node\u3001react\u3001react dom\u7c7b\u578b\u7684\u5b9a\u4e49\u540c\u65f6\u5728\u6839\u76ee\u5f55\u52a0\u5165tsconfig.json\u6765\u5bf9ts\u7f16\u8bd1\u8fdb\u884c\u914d\u7f6e\uff1a\/\/_tsconfig.json_<\/p>\n<p>{<br \/>  &#8220;compilerOptions&#8221;: {<\/p>\n<pre><code>&quot;outDir&quot;: &quot;.\/dist\/&quot;,\n&quot;noImplicitAny&quot;: true,\n&quot;module&quot;: &quot;es6&quot;,\n&quot;target&quot;: &quot;es5&quot;,\n&quot;jsx&quot;: &quot;react&quot;,\n&quot;allowJs&quot;: true,\n&quot;allowSyntheticDefaultImports&quot;: true,\n&quot;moduleResolution&quot;: &quot;Node&quot;<\/code><\/pre>\n<p>}<br \/>}\u6700\u540e\u5728webpack\u4e2d\u6dfb\u52a0\u5bf9ts\u7684\u652f\u6301\u3002\u6dfb\u52a0ts-loader\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>{<br \/>  test: \/.tsx?$\/,<br \/>  exclude: \/node_modules\/,<br \/>  loader: &#8216;ts-loader&#8217;<br \/>}<br \/>&#8230;\u8bbe\u7f6eresolve\u5c5e\u6027\uff0c\u6765\u6307\u5b9a\u6587\u4ef6\u5982\u4f55\u88ab\u89e3\u6790\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>resolve: <br \/>{<br \/>   extensions: [ &#8216;.tsx&#8217;, &#8216;.ts&#8217;, &#8216;.js&#8217; ],<br \/>}<br \/>&#8230;rename\u5165\u53e3\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>entry: &#8220;.\/src\/index.tsx&#8221;,<br \/>&#8230;\u6700\u540e\u542f\u52a8\u4e00\u4e0bserver\u6765\u770b\u4e00\u4e0bts\u914d\u7f6e\u662f\u5426\u6b63\u786e\u3002\u00a0<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444959\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u00a0\u4e0a\u8ff0\u6211\u4eec\u7684\u914d\u7f6e\u5176\u5b9e\u76f8\u5f53\u4e8e\u6267\u884c\u4e86\u4e00\u6b21\uff1anpx create-react-app my-app &#8211;template typescript\u5728\u8fd9\u79cd\u6d41\u7a0b\u4e0b\u5f88\u662f\u9ebb\u70e6\uff0c\u5c06 *.ts \u63d0\u4f9b\u7ed9 TypeScript\uff0c\u7136\u540e\u5c06\u8fd0\u884c\u7684\u7ed3\u679c\u63d0\u4f9b\u7ed9 Babel\uff0c\u800c\u4e14\u8fd8\u8981\u501f\u52a9\u5f88\u591aloader\u3002\u00a0<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444960\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u00a0\u90a3\u4e48\u6211\u4eec\u80fd\u4e0d\u80fd\u7b80\u5316\u4e00\u4e0b\u8fd9\u6837\u7684\u6d41\u7a0b\uff0c\u56e0\u4e3aBabel7\u4e2d\u63d0\u4f9b\u7684babel-loader\u5c31\u53ef\u4ee5\u5b8c\u7f8e\u8fdb\u884c\u7f16\u8bd1ts\uff0c\u7b54\u6848\u662f\u53ef\u4ee5\u7684\uff0c\u8fd9\u79cd\u65b9\u5f0f\u76f4\u63a5\u7b80\u5316\u4e86\u8fc7\u7a0b\u3002\u00a0<br \/><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042444961\" alt=\"\u56fe\u7247\" title=\"\u56fe\u7247\" loading=\"lazy\"><br \/>\u00a0module: {<\/p>\n<pre><code>rules: [\n  {\n    test: \/\/.tsx?$\/,\n    exclude: \/node_modules\/,\n    loader: ['babel-loader']\n  }\n]<\/code><\/pre>\n<p>},\u5e76\u4e14\u5728.babelrc\u4e2d\u4e5f\u53ea\u591a\u4e86\u4e00\u884c@babel\/preset-typescript\uff0c\u8fd9\u79cd\u914d\u7f6e\u66f4\u7b80\u5355\uff0c\u800c\u4e14\u6253\u5305\u901f\u5ea6\u66f4\u5feb\u4e00\u70b9\uff0c\u903b\u8f91\u66f4\u52a0\u6e05\u6670\u3002\u90a3\u4e48\u4e3a\u4ec0\u4e48\u8fd8\u8981\u5728\u9879\u76ee\u4e2d\u4f7f\u7528ts-loader\u5462\uff1fts-loader \u5728\u5185\u90e8\u662f\u8c03\u7528\u4e86 TypeScript \u7684\u5b98\u65b9\u7f16\u8bd1\u5668 &#8212; tsc\u3002\u6240\u4ee5\uff0cts-loader \u548c tsc \u662f\u5171\u4eab tsconfig.json\uff0c\u6240\u4ee5\u4f1a\u63d0\u4f9b\u5b8c\u6574\u7684\u62a5\u9519\u4fe1\u606f\uff0cts-loader\u4e5f\u4e0e vscode \u63d0\u4f9b\u7684\u8bed\u6cd5\u6821\u9a8c\u8868\u73b0\u4e00\u81f4\u800c@babel\/preset-typescript\u6709\u7684\u65f6\u5019\u4f1a\u65e0\u6cd5\u63d0\u4f9b\u5b8c\u6574\u7684\u62a5\u9519\u4fe1\u606f\u548c\u7c7b\u578b\u63d0\u793a\u7ba1\u7406\u8d44\u6e90webpack \u53ea\u80fd\u7406\u89e3 JavaScript \u548c JSON \u6587\u4ef6\uff0c\u8fd9\u662f webpack \u5f00\u7bb1\u53ef\u7528\u7684\u81ea\u5e26\u80fd\u529b\u3002loader \u8ba9 webpack \u80fd\u591f\u53bb\u5904\u7406\u5176\u4ed6\u7c7b\u578b\u7684\u6587\u4ef6\uff0c\u5e76\u5c06\u5b83\u4eec\u8f6c\u6362\u4e3a\u6709\u6548\u7684\u6a21\u5757\u4e2d\u3002loader\u4e2d\uff0ctest\u5c5e\u6027\u53ef\u4ee5\u8bc6\u522b\u51fa\u54ea\u4e9b\u6587\u4ef6\u4f1a\u88ab\u8f6c\u6362\uff1buse\u5c5e\u6027\u53ef\u4ee5\u5b9a\u4e49\u51fa\u8f6c\u6362\u65f6\uff0c\u5e94\u8be5\u662f\u7528\u54ea\u4e2aloader\u3002CSS\u3001Less\u3001Sass\u5b89\u88c5loader\uff1atnpm i -D less less-loader style-loader css-loader sass sass-loaderwebpack\u914d\u7f6e\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>rules: [<\/p>\n<pre><code>  {\n    test: \/\/.jsx?$\/,\n    exclude: \/node_modules\/,\n    loader: 'babel-loader',\n  },\n  {\n    test: \/\/.css$\/,\n    use: ['style-loader', 'css-loader'],\n  },\n  {\n    test: \/\/.tsx?$\/,\n    exclude: \/node_modules\/,\n    loader: 'ts-loader',\n  },\n  {\n    test: \/\/.(less|css)$\/,\n    exclude: \/\/.module\/.less$\/,\n    use: [\n      {\n        loader: 'css-loader',\n        options: {\n          importLoaders: 2,\n          sourceMap: !!DEV,\n        },\n      },\n      {\n        loader: 'less-loader',\n        options: {\n          sourceMap: !!DEV,\n        },\n      },\n    ],\n  },\n  {\n    test: \/\/.(sass|scss)$\/,\n    use: [\n      {\n        loader: 'css-loader',\n        options: {\n          importLoaders: 2,\n          sourceMap: !!DEV,\n        },\n      },\n      {\n        loader: 'sass-loader',\n        options: {\n          sourceMap: !!DEV,\n        },\n      },\n    ],\n  },<\/code><\/pre>\n<p>&#8230;\u56fe\u7247\u3001JSON\u8d44\u6e90\u5bf9\u4e8e\u56fe\u7247\u548c\u5b57\u4f53\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u5185\u7f6e\u7684Assets Modules\u6765\u8f7b\u677e\u5730\u628a\u8fd9\u4e9b\u5185\u5bb9\u52a0\u5230\u6211\u4eec\u7684\u7cfb\u7edf\u4e2d\uff0c\u5bf9\u4e8e\u7c7b\u578b\uff0c\u6211\u4eec\u53ef\u4ee5\u9009\u62e9\uff1aasset\/resource \u53d1\u9001\u4e00\u4e2a\u5355\u72ec\u7684\u6587\u4ef6\u5e76\u5bfc\u51fa URL\u3002asset\/inline \u5bfc\u51fa\u4e00\u4e2a\u8d44\u6e90\u7684 data URI\u3002asset\/source \u5bfc\u51fa\u8d44\u6e90\u7684\u6e90\u4ee3\u7801\u3002asset \u5728\u5bfc\u51fa\u4e00\u4e2a data URI \u548c\u53d1\u9001\u4e00\u4e2a\u5355\u72ec\u7684\u6587\u4ef6\u4e4b\u95f4\u81ea\u52a8\u9009\u62e9\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>module: {<br \/>  rules: [{<\/p>\n<pre><code>test: \/\/.png\/,\ntype: 'asset\/resource'<\/code><\/pre>\n<p>}]<br \/>},<br \/>&#8230;\u5bf9\u4e8e\u5176\u4ed6\u7c7b\u578b\u8d44\u6e90\uff0c\u6211\u4eec\u9700\u8981\u5b89\u88c5csv-loader\u3001xml-loader\u7b49\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>{<br \/>  test: \/.(csv|tsv)$\/i,<br \/>  use: [&#8216;csv-loader&#8217;],<br \/>},<br \/>{<br \/>  test: \/.xml$\/i,<br \/>  use: [&#8216;xml-loader&#8217;],<br \/>},<br \/>&#8230;\u642d\u5efa\u5f00\u53d1\u73af\u5883\u76ee\u524d\uff0c\u6211\u4eec\u7684\u5e94\u7528\u5df2\u7ecf\u53ef\u4ee5\u6b63\u5e38\u8fd0\u884ctsx\u6587\u4ef6\uff0c\u5e76\u4e14\u5728\u672c\u5730\u8fdb\u884c\u8c03\u8bd5\u548c\u5f00\u53d1\uff0c\u90a3\u4e48\u6211\u4eec\u6765\u770b\u770b\u5982\u4f55\u8bbe\u7f6e\u4e00\u4e2a\u5f00\u53d1\u73af\u5883\uff0c\u6765\u4f7f\u5f00\u53d1\u53d8\u5f97\u66f4\u52a0\u8f7b\u677e\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>const { DEV, DEBUG } = process.env;<br \/>process.env.BABEL_ENV = DEV ? &#8216;development&#8217; : &#8216;production&#8217;;<br \/>process.env.NODE_ENV = DEV ? &#8216;development&#8217; : &#8216;production&#8217;;<br \/>&#8230;<br \/>mode: DEV ? &#8216;development&#8217; : &#8216;production&#8217;,<br \/>devtool: DEV &#038;&#038; &#8216;source-map&#8217;,<br \/>&#8230;\u6211\u4eec\u53ef\u4ee5\u4eceprocess.env\u4e2d\u83b7\u53d6\u73af\u5883\u53d8\u91cf\u6765\u533a\u5206\u5f00\u53d1\u73af\u5883\u548c\u751f\u4ea7\u73af\u5883\u3002\u5f53webpack\u5728\u672c\u5730\u6253\u5305\u4ee3\u7801\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528inline-source-map\uff0c\u53ef\u4ee5\u5c06\u7f16\u8bd1\u540e\u7684\u4ee3\u7801\u6620\u5c04\u56de\u539f\u59cb\u6e90\u4ee3\u7801\uff0c\u8fd9\u6837\u5728\u62a5\u9519\u7684\u65f6\u5019\uff0c\u9519\u8bef\u5c31\u4f1a\u88ab\u5b9a\u4e3a\u5230\u786e\u5207\u7684\u6587\u4ef6\u548c\u884c\u6570\u3002\u5f53\u7136\uff0c\u5728\u751f\u4ea7\u73af\u5883\u4e2d\uff0c\u4e3a\u4e86\u4fdd\u62a4\u9690\u79c1\uff0c\u6700\u597d\u628a\u8fd9\u4e2a\u8bbe\u7f6e\u52a8\u6001\u5173\u6389\u3002\u5728\u5f00\u53d1\u73af\u5883\u4e2d\uff0cwebpack-dev-server\u4f1a\u4e3a\u4f60\u63d0\u4f9b\u4e00\u4e2a\u57fa\u672c\u7684web server\uff0c\u5e76\u4e14\u5177\u6709\u5b9e\u65f6\u91cd\u65b0\u52a0\u8f7d\u529f\u80fd\u3002\u5b8c\u5584\u6253\u5305\u914d\u7f6e\u4e0e\u7f13\u5b58\u6211\u4eec\u5e0c\u671b\u6bcf\u6b21\u6253\u5305\u90fd\u628a\u4e0a\u6b21\u7684\u6253\u5305\u6587\u4ef6\u5220\u9664\uff0c\u53ef\u4ee5\u4f7f\u7528CleanWebpackPlugin\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>const { CleanWebpackPlugin } = require(&#8216;clean-webpack-plugin&#8217;);<\/p>\n<p>module.exports = {<br \/>  plugins: [<\/p>\n<pre><code>new CleanWebpackPlugin(),<\/code><\/pre>\n<p>]<br \/>}<br \/>&#8230;\u5e76\u4e14\uff0c\u5728\u6211\u4eec\u751f\u4ea7\u73af\u5883\uff0c\u6211\u4eec\u5e0c\u671b\u6539\u52a8\u540e\u7684\u65b0\u7248\u672c\u53ef\u4ee5\u4e22\u5f03\u7f13\u5b58\uff0c\u5e76\u4e14\u6ca1\u6709\u6539\u52a8\u7684\u7248\u672c\u53ef\u4ee5\u4fdd\u7559\u7f13\u5b58\uff1b\u4f46\u662f\u5728\u5f00\u53d1\u73af\u5883\uff0c\u6211\u4eec\u4e0d\u5e0c\u671b\u6709\u7f13\u5b58\uff0c\u800c\u662f\u6bcf\u6b21\u90fd\u662f\u62ff\u5230\u6700\u65b0\u7684\u8d44\u6e90\u3002\u6240\u4ee5\uff0c\u9700\u8981\u5bf9webpack config\u505a\u4e00\u6b21\u62c6\u5206\uff1a\u5206\u6210webpack.prod.js \u751f\u4ea7\u73af\u5883\u6253\u5305\u914d\u7f6ewebpack.dev.js \u5f00\u53d1\u73af\u5883\u6253\u5305\u914d\u7f6e\u91cc\u9762\u7684\u533a\u522b\u4e3b\u8981\u5728\u4e8e\u6253\u5305\u540e\u7684\u6587\u4ef6\u540d\u79f0\u3001sourceMap\u7b49\u3002\u751f\u4ea7\u73af\u5883contenthash\uff1a\u53ea\u6709\u6a21\u5757\u7684\u5185\u5bb9\u6539\u53d8\uff0c\u624d\u4f1a\u6539\u53d8hash\u503c\uff1aoutput: {<\/p>\n<pre><code>filename: 'js\/[name].[contenthash:8].js', \/\/ contenthash\uff1a\u53ea\u6709\u6a21\u5757\u7684\u5185\u5bb9\u6539\u53d8\uff0c\u624d\u4f1a\u6539\u53d8hash\u503c<\/code><\/pre>\n<p>},\u5f00\u53d1\u73af\u5883output: {<br \/>  filename: &#8216;js\/[name].[hash:8].js&#8217;,<br \/>}\u6027\u80fd\u4f18\u5316\u6253\u5305\u5206\u6790\u5de5\u5177\u53ef\u4ee5\u4f7f\u7528webpack-bundle-analyzer\u6765\u5206\u6790\u6211\u4eec\u6253\u5305\u8d44\u6e90\u7684\u5927\u5c0f\uff1aconst { BundleAnalyzerPlugin } = require(&#8216;webpack-bundle-analyzer&#8217;);<br \/>plugins: [<br \/>  DEBUG &#038;&#038; new BundleAnalyzerPlugin(),<br \/>]\u540c\u65f6\u8bbe\u7f6epackage.json\u7684\u542f\u52a8\u9879\u8d44\u6e90\u538b\u7f29OptimizeCSSAssetsPlugin\u4e3b\u8981\u7528\u6765\u4f18\u5316css\u6587\u4ef6\u7684\u8f93\u51fa\uff0c\u5305\u62ec\u6448\u5f03\u91cd\u590d\u7684\u6837\u5f0f\u5b9a\u4e49\u3001\u780d\u6389\u6837\u5f0f\u89c4\u5219\u4e2d\u591a\u4f59\u7684\u53c2\u6570\u3001\u79fb\u9664\u4e0d\u9700\u8981\u7684\u6d4f\u89c8\u5668\u524d\u7f00\u7b49\u3002TerserPlugin\u4e3b\u8981\u7528\u6765\u4f18\u5316js\u4f53\u79ef\uff0c\u5305\u62ec\u91cd\u547d\u540d\u53d8\u91cf\uff0c\u751a\u81f3\u662f\u5220\u9664\u6574\u4e2a\u7684\u8bbf\u95ee\u4e0d\u5230\u7684\u4ee3\u7801\u5757\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>const OptimizeCSSAssetsPlugin = require(&#8216;optimize-css-assets-webpack-plugin&#8217;);<br \/>const TerserPlugin = require(&#8216;terser-webpack-plugin&#8217;);<br \/>&#8230;<br \/>optimization: {<br \/>  minimizer: [<\/p>\n<pre><code>new TerserPlugin({\n  parallel: false,\n  terserOptions: {\n    output: {\n      comments: false,\n    },\n  },\n}),\nnew OptimizeCSSAssetsPlugin({}),<\/code><\/pre>\n<p>],<\/p>\n<pre><code>minimize: !DEV,\n  splitChunks: {\n    minSize: 500000,\n      cacheGroups: {\n        vendors: false,\n      },\n  },<\/code><\/pre>\n<p>},<br \/>&#8230;\u4ee3\u7801\u5206\u79bb\u8d44\u6e90\u5206\u79bb1)\u591a\u5165\u53e3webpack\u5185\u7f6e\u7684\u7279\u6027\u80fd\u591f\u628a\u4ee3\u7801\u5206\u79bb\u5230\u4e0d\u540c\u7684bundle \u4e2d\uff0c\u7136\u540e\u53ef\u4ee5\u6309\u9700\u52a0\u8f7d\u6216\u5e76\u884c\u52a0\u8f7d\u8fd9\u4e9b\u6587\u4ef6\u3002\u4ee3\u7801\u5206\u79bb\u53ef\u4ee5\u7528\u4e8e\u83b7\u53d6\u66f4\u5c0f\u7684bundle\uff0c\u4ee5\u53ca\u63a7\u5236\u8d44\u6e90\u52a0\u8f7d\u4f18\u5148\u7ea7\uff0c\u5982\u679c\u4f7f\u7528\u5408\u7406\uff0c\u4f1a\u6781\u5927\u5f71\u54cd\u52a0\u8f7d\u65f6\u95f4\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>entry: {<br \/>  index: &#8216;.\/src\/index.js&#8217;,<br \/>  another: &#8216;.\/src\/another-module.js&#8217;,<br \/>},<br \/>output: {<br \/>  filename: &#8216;[name].bundle.js&#8217;<br \/>&#8230;2)Tree ShakingWebpack5\u5728\u751f\u4ea7\u73af\u5883\u5df2\u7ecf\u96c6\u6210\u4e86Tree Shaking\u529f\u80fd\uff0c\u4e0d\u7528\u7684\u4ee3\u7801\u4f1a\u88abshaking\u6389\uff1a\/\/ <em>webpack.config.js<\/em><br \/>module.exports = {<br \/>  \/\/ &#8230;<br \/>  mode: &#8216;production&#8217;,<br \/>};\u4f46\u662f\u5728\u5f00\u53d1\u73af\u5883\u4e2d\u9700\u8981\u624b\u52a8\u914d\u7f6e(Not Recommend)\uff1a\/\/ <em>webpack.config.js<\/em><br \/>module.exports = {<br \/>  \/\/ &#8230;<br \/>  mode: &#8216;development&#8217;,<br \/>  optimization: {<\/p>\n<pre><code>usedExports: true,<\/code><\/pre>\n<p>}<br \/>};\u5904\u4e8e\u597d\u5947\uff0cwebpack\u662f\u5982\u4f55\u5b8c\u7f8e\u7684\u907f\u5f00\u6ca1\u6709\u4f7f\u7528\u7684\u4ee3\u7801\u7684\u5462\uff1f\u5f88\u7b80\u5355\uff1a\u5c31\u662f Webpack \u6ca1\u770b\u5230\u4f60\u4f7f\u7528\u7684\u4ee3\u7801\u3002Webpack \u8ddf\u8e2a\u6574\u4e2a\u5e94\u7528\u7a0b\u5e8f\u7684import\/export \u8bed\u53e5\uff0c\u56e0\u6b64\uff0c\u5982\u679c\u5b83\u770b\u5230\u5bfc\u5165\u7684\u4e1c\u897f\u6700\u7ec8\u6ca1\u6709\u88ab\u4f7f\u7528\uff0c\u5b83\u4f1a\u8ba4\u4e3a\u90a3\u662f\u672a\u5f15\u7528\u4ee3\u7801(\u6216\u53eb\u505a\u201c\u6b7b\u4ee3\u7801\u201d\u2014\u2014 dead-code )\uff0c\u5e76\u4f1a\u5bf9\u5176\u8fdb\u884c tree-shaking \u3002\u6b7b\u4ee3\u7801\u5e76\u4e0d\u603b\u662f\u90a3\u4e48\u660e\u786e\u7684\u3002\u4e0b\u9762\u662f\u4e00\u4e9b\u4f8b\u5b50\uff1a\/\/ <em>test.js<\/em><br \/>\/\/ \u8fd9\u4f1a\u88ab\u770b\u4f5c\u201c\u6d3b\u201d\u4ee3\u7801\uff0c\u4e0d\u4f1a\u505a tree-shaking<br \/>import { add } from &#8216;.\/math&#8217;<br \/>console.log(add(5, 6))\/\/ \u5bfc\u5165\u4f46\u6ca1\u6709\u8d4b\u503c\u7ed9 JavaScript \u5bf9\u8c61\uff0c\u4e5f\u6ca1\u6709\u5728\u4ee3\u7801\u91cc\u7528\u5230<br \/>\/\/ \u8fd9\u4f1a\u88ab\u5f53\u505a\u201c\u6b7b\u201d\u4ee3\u7801\uff0c\u4f1a\u88ab tree-shaking<br \/>import { add, minus } from &#8216;.\/math&#8217;<br \/>console.log(&#8216;hello webpack&#8217;)\/\/ \u5bfc\u5165\u6574\u4e2a\u5e93\uff0c\u4f46\u662f\u6ca1\u6709\u8d4b\u503c\u7ed9 JavaScript \u5bf9\u8c61\uff0c\u4e5f\u6ca1\u6709\u5728\u4ee3\u7801\u91cc\u7528\u5230<br \/>\/\/ \u975e\u5e38\u5947\u602a\uff0c\u8fd9\u7adf\u7136\u88ab\u5f53\u505a\u201c\u6d3b\u201d\u4ee3\u7801\uff0c\u56e0\u4e3a Webpack \u5bf9\u5e93\u7684\u5bfc\u5165\u548c\u672c\u5730\u4ee3\u7801\u5bfc\u5165\u7684\u5904\u7406\u65b9\u5f0f\u4e0d\u540c\u3002<br \/>import { add, minus } from &#8216;.\/math&#8217; \/\/ \u6b7b\u7684<br \/>import &#8216;lodash&#8217; \/\/ \u6d3b\u7684<br \/>console.log(&#8216;hello webpack&#8217;)<br \/>\u6240\u4ee5\u5bf9\u4e8e\u8fd9\u79cd\u4e09\u65b9\u5e93\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u7684Shimming\u65b9\u6cd5\u3002\u6ce8\u610f Webpack \u4e0d\u80fd\u767e\u5206\u767e\u5b89\u5168\u5730\u8fdb\u884c tree-shaking\u3002\u6709\u4e9b\u6a21\u5757\u5bfc\u5165\uff0c\u53ea\u8981\u88ab\u5f15\u5165\uff0c\u5c31\u4f1a\u5bf9\u5e94\u7528\u7a0b\u5e8f\u4ea7\u751f\u91cd\u8981\u5f71\u54cd\u3002\u4e00\u4e2a\u5f88\u597d\u7684\u4f8b\u5b50\u5c31\u662f\u5168\u5c40\u6837\u5f0f\u8868\uff0c\u6216\u8005\u8bbe\u7f6e\u5168\u5c40\u914d\u7f6e\u7684JavaScript \u6587\u4ef6\u3002Webpack \u8ba4\u4e3a\u8fd9\u6837\u7684\u6587\u4ef6\u6709\u201c\u526f\u4f5c\u7528\u201d\u3002\u5177\u6709\u526f\u4f5c\u7528\u7684\u6587\u4ef6\u4e0d\u5e94\u8be5\u505a tree-shaking\uff0c\u56e0\u4e3a\u8fd9\u5c06\u7834\u574f\u6574\u4e2a\u5e94\u7528\u3002\u6bd4\u8f83\u597d\u7684\u544a\u8bc9Webpack\u4f60\u7684\u4ee3\u7801\u6709\u526f\u4f5c\u7528\u7684\u65b9\u6cd5\u5c31\u662f\u5728package.json\u91cc\u9762\u8bbe\u7f6esideEffects\u3002{<br \/>  &#8220;name&#8221;: &#8220;your-project&#8221;,<br \/>  &#8220;sideEffects&#8221;: [&#8220;.\/src\/some-side-effectful-file.js&#8221;, &#8220;*.css&#8221;]<br \/>}3)Shimming\u9884\u7f6e\u4f9d\u8d56\u5bf9\u4e8e\u4e0a\u9762\u7684lodash\u5e93\u65e0\u6cd5\u88abshaking\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7ec6\u7c92\u5ea6shimming\u9884\u7f6e\u7684\u65b9\u6cd5\u6765\u4f18\u5316\uff0c\u9996\u5148\u5f15\u5165ProvidePlugin\u63d2\u4ef6\uff0c\u628a\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u6a21\u5757\u4f9d\u8d56\uff0c\u6539\u4e3a\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u4f9d\u8d56\uff0c\u8ba9\u6211\u4eec\u5148\u79fb\u9664 lodash \u7684 import\u8bed\u53e5\uff0c\u6539\u4e3a\u901a\u8fc7\u63d2\u4ef6\u63d0\u4f9b\u5b83\uff0c\u5e76\u4e14\u63d0\u53d6\u51fajoin\u65b9\u6cd5\u6765\u5168\u5c40\u4f7f\u7528\u5b83\uff1a\/\/ _src\/index.tsx<br \/>console.log(join([&#8216;hello&#8217;, &#8216;webpack&#8217;], &#8216; &#8216;))<br \/>\/\/ <em>webpack.config.js<\/em><br \/>plugins: [<br \/>  new webpack.ProvidePlugin({<\/p>\n<pre><code>\/\/_: 'lodash'\n\/\/ \u5982\u679c\u6ca1\u6ce8\u91ca\u7684\u8bdd\uff0c\u9700\u8981\u8fd9\u6837\u5f15\u7528console.log(_.join(['hello', 'webpack'], ' '))\njoin: ['lodash', 'join'],<\/code><\/pre>\n<p>})<br \/>]\u7ec6\u7c92\u5ea6Shimming\u4e00\u4e9b\u9057\u7559\u7684\u6a21\u5757\u4f9d\u8d56\u7684this\u6307\u5411\u7684window\u5bf9\u8c61\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528import-loaders\uff0c\u5b83\u5bf9\u4f9d\u8d56 window \u5bf9\u8c61\u4e0b\u7684\u5168\u5c40\u53d8\u91cf\uff08\u6bd4\u5982 $ \u6216 this \uff09\u7684\u7b2c\u4e09\u65b9\u6a21\u5757\u975e\u5e38\u6709\u7528\u3002CommonJS \u4e0a\u4e0b\u6587\u4e2d\uff0c\u8fd9\u5c06\u4f1a\u53d8\u6210\u4e00\u4e2a\u95ee\u9898\uff0c\u4e5f\u5c31\u662f\u8bf4\u6b64\u65f6\u7684 this\u6307\u5411\u7684\u662f module.exports\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 imports-loader\u8986\u76d6 this \u6307\u5411\uff1a\/\/ <em>webpack.config.js<\/em><br \/>module: {<br \/>  rules: [<\/p>\n<pre><code>{\n  test: require.resolve('.\/src\/index.js'),\n  use: 'imports-loader?wrapper=window',\n},<\/code><\/pre>\n<p>]<br \/>},4)\u516c\u5171\u90e8\u5206\u63d0\u53d6\u9632\u6b62\u91cd\u590d\u53ef\u4ee5\u4f7f\u7528splitChunk\uff0c\u63d0\u53d6\u51fa\u4ee3\u7801\u4e2d\u7684\u516c\u5171\u90e8\u5206\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>minimize: !DEV,<br \/>  splitChunks: {<\/p>\n<pre><code>minSize: 500000,\n  cacheGroups: {\n    vendors: false,\n  },<\/code><\/pre>\n<p>},<br \/>&#8230;minSize\uff1a\u5f62\u6210\u4e00\u4e2a\u65b0\u4ee3\u7801\u5757\u6700\u5c0f\u7684\u4f53\u79efcacheGroups\uff1a\u8fd9\u91cc\u5f00\u59cb\u8bbe\u7f6e\u7f13\u5b58\u7684 chunks5)\u6309\u9700\u5206\u79bb\u5728React\u9879\u76ee\u4e2d\uff0c\u4ee3\u7801\u6309\u9700\u5206\u79bb\u53ef\u4ee5\u4f7f\u7528\u5982\u4e0b\u65b9\u6cd5\uff0cwebpack \u628a import() \u4f5c\u4e3a\u4e00\u4e2a\u5206\u79bb\u70b9(split-point)\uff0c\u5e76\u628a\u5f15\u5165\u7684\u6a21\u5757\u4f5c\u4e3a\u4e00\u4e2a\u5355\u72ec\u7684 chunk\u3002import() \u5c06\u6a21\u5757\u540d\u5b57\u4f5c\u4e3a\u53c2\u6570\u5e76\u8fd4\u56de\u4e00\u4e2a Promoise \u5bf9\u8c61\uff0c\u5373 import(name) -&gt; Promise\u3002\/\/_index.tsx_<br \/>&#8230;<br \/>const WdAndDxEntry = lazy(() =&gt; import(\/<em> webpackChunkName: &#8220;wd-and-dx&#8221; <\/em>\/ &#8216;..\/..\/old-code\/component\/wd-and-dx\/entry&#8217;));<br \/>const WdAndDxFallback = () =&gt; ()<br \/>const SSRCompatibleSuspense = (props: Parameters&lt; typeof Suspense&gt;[&#8216;0&#8217;]) =&gt; {<br \/>  const isMounted = useMounted();<\/p>\n<p>if (isMounted) {<\/p>\n<pre><code>return &lt; Suspense {...props} \/&gt;;<\/code><\/pre>\n<p>}<br \/>  return &lt; &gt;{props.fallback}&lt; \/&gt;;<br \/>} <br \/>&#8230;<br \/>return (<br \/>  &lt; SSRCompatibleSuspense fallback={&lt; WdAndDxFallback \/&gt;}&gt;<\/p>\n<pre><code>&lt; WdAndDxEntry\n  className=&quot;&quot;\n  data={data}\n  style={{\n    height: 150,\n  }}\n  \/&gt;<\/code><\/pre>\n<p>&lt; \/SSRCompatibleSuspense&gt;<br \/>); 6)\u5206\u79bb\u4e09\u65b9\u5e93\u914d\u7f6e dependOn option \u9009\u9879\uff0c\u8fd9\u6837\u53ef\u4ee5\u5728\u591a\u4e2a chunk \u4e4b\u95f4\u5171\u4eab\u6a21\u5757\uff1a\/\/_webpack.config.js_<br \/>&#8230;<br \/>module.exports = {<br \/>  entry: {<\/p>\n<pre><code>index: {\n  import: '.\/src\/index.js',\n  dependOn: 'shared',<\/code><\/pre>\n<p>},<br \/>  another: {<\/p>\n<pre><code>import: '.\/src\/another-module.js',\ndependOn: 'shared',<\/code><\/pre>\n<p>},<br \/>  shared: &#8216;lodash&#8217;,<br \/>  }<br \/>}<br \/>&#8230;CSS\u5206\u79bb\u8be5\u63d2\u4ef6MiniCssExtractPlugin\u5c06CSS\u63d0\u53d6\u5230\u5355\u72ec\u7684\u6587\u4ef6\u4e2d\u3002\u5b83\u4e3a\u6bcf\u4e2a\u5305\u542bCSS\u7684JS\u6587\u4ef6\u521b\u5efa\u4e00\u4e2aCSS\u6587\u4ef6\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>const MiniCssExtractPlugin = require(&#8216;mini-css-extract-plugin&#8217;);<br \/>&#8230;<br \/>{<br \/>  test: \/.(sass|scss)$\/,<br \/>  use: [<\/p>\n<pre><code>{\n  loader: MiniCssExtractPlugin.loader,\n},\n{\n  loader: 'css-loader',\n  options: {\n    importLoaders: 2,\n    sourceMap: !!DEV,\n  },\n},\n{\n  loader: 'sass-loader',\n  options: {\n    sourceMap: !!DEV,\n  },\n},<\/code><\/pre>\n<p>],<br \/>},<br \/>&#8230;<br \/>DEBUG &#038;&#038; new BundleAnalyzerPlugin(),<br \/>  new MiniCssExtractPlugin({<br \/>  filename: &#8216;[name].css&#8217;,<br \/>  chunkFilename: &#8216;[name].css&#8217;,<br \/>}),<br \/>&#8230;\u63d0\u9ad8\u6784\u5efa\u901f\u5ea6\u5f53\u9879\u76ee\u4f53\u79ef\u589e\u5927\u65f6\uff0c\u7f16\u8bd1\u65f6\u95f4\u4e5f\u968f\u4e4b\u589e\u52a0\u3002\u5176\u4e2d\u65f6\u95f4\u5927\u5934\u5c31\u662fts\u7684\u7c7b\u578b\u68c0\u6d4b\u8017\u65f6\u3002ts-loader \u63d0\u4f9b\u4e86\u4e00\u4e2a transpileOnly \u9009\u9879\uff0c\u5b83\u9ed8\u8ba4\u4e3a false\uff0c\u6211\u4eec\u53ef\u4ee5\u628a\u5b83\u8bbe\u7f6e\u4e3a true\uff0c\u8fd9\u6837\u9879\u76ee\u7f16\u8bd1\u65f6\u5c31\u4e0d\u4f1a\u8fdb\u884c\u7c7b\u578b\u68c0\u67e5\uff0c\u4e5f\u4e0d\u4f1a\u8f93\u51fa\u58f0\u660e\u6587\u4ef6\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>module: {<br \/>  rules: [<\/p>\n<pre><code>{\n  test: \/\/.tsx?$\/,\n  use: [\n    {\n      loader: 'ts-loader',\n      options: {\n        transpileOnly: true\n      }\n    }\n  ]\n}<\/code><\/pre>\n<p>]<br \/>}<br \/>&#8230;\u53ef\u4ee5\u770b\u4e00\u4e0b\u5f00\u5173\u8fd9\u4e2a\u9009\u9879\u540e\u7684\u524d\u540e\u5bf9\u6bd4\uff1a\u5f00\u542f\u68c0\u67e5\u524d$ webpack &#8211;mode=production &#8211;config .\/build\/webpack.config.js<br \/>Hash: 36308e3786425ccd2e9d<br \/>Version: webpack 4.41.0<br \/>Time: 2482ms<br \/>Built at: 12\/20\/2019 4:52:43 PM<\/p>\n<pre><code> Asset       Size  Chunks             Chunk Names\napp.js  932 bytes       0  [emitted]  main<\/code><\/pre>\n<p>index.html  338 bytes          [emitted]<br \/>Entrypoint main = app.js<br \/>[0] .\/src\/index.ts 14 bytes {0} [built]<br \/>Child html-webpack-plugin for &#8220;index.html&#8221;:<\/p>\n<pre><code> 1 asset\nEntrypoint undefined = index.html\n[0] .\/node_modules\/html-webpack-plugin\/lib\/loader.js!.\/index.html 489 bytes {0} [built]\n[2] (webpack)\/buildin\/global.js 472 bytes {0} [built]\n[3] (webpack)\/buildin\/module.js 497 bytes {0} [built]\n    + 1 hidden module<\/code><\/pre>\n<p>\u2728  Done in 4.88s.\u5173\u95ed\u68c0\u67e5\u540e$ webpack &#8211;mode=production &#8211;config .\/build\/webpack.config.js<br \/>Hash: e5a133a9510259e1f027<br \/>Version: webpack 4.41.0<br \/>Time: 726ms<br \/>Built at: 12\/20\/2019 4:54:20 PM<br \/>Asset       Size  Chunks             Chunk Names<br \/>app.js  932 bytes       0  [emitted]  main<br \/>index.html  338 bytes          [emitted]<br \/>Entrypoint main = app.js<br \/>[0] .\/src\/index.ts 14 bytes {0} [built]<br \/>Child html-webpack-plugin for &#8220;index.html&#8221;:<br \/>1 asset<br \/>Entrypoint undefined = index.html<br \/>[0] .\/node_modules\/html-webpack-plugin\/lib\/loader.js!.\/index.html 489 bytes {0} [built]<br \/>[2] (webpack)\/buildin\/global.js 472 bytes {0} [built]<br \/>[3] (webpack)\/buildin\/module.js 497 bytes {0} [built]<\/p>\n<ul>\n<li>\n<p>1 hidden module<br \/>\u2728  Done in 2.40s.From 4.88s &#8211;&gt; 2.4s\uff0c\u4f46\u662f\u7f3a\u5c11\u4e86\u7c7b\u578b\u68c0\u67e5\u3002\u8fd9\u91cc\u5b98\u65b9\u63a8\u8350\u4e86\u4e00\u4e2a\u89e3\u51b3\u65b9\u6848\uff0c\u4f7f\u7528fork-ts-checker-webpack-plugin\uff0c\u5b83\u5728\u4e00\u4e2a\u5355\u72ec\u7684\u8fdb\u7a0b\u4e0a\u8fd0\u884c\u7c7b\u578b\u68c0\u67e5\u5668\uff0c\u6b64\u63d2\u4ef6\u4f7f\u7528 TypeScript \u800c\u4e0d\u662f webpack \u7684\u6a21\u5757\u89e3\u6790\uff0c\u6709\u4e86 TypeScript \u7684\u6a21\u5757\u89e3\u6790\uff0c\u6211\u4eec\u4e0d\u5fc5\u7b49\u5f85webpack \u7f16\u8bd1\u3002\u53ef\u4ee5\u6781\u5927\u52a0\u5feb\u7f16\u8bd1\u901f\u5ea6\u3002\/\/_webpack.config.js_<br \/>&#8230;<br \/>module: {<br \/>  rules: [<\/p>\n<pre><code>{\n  test: \/\/.tsx?$\/,\n  use: [\n    {\n      loader: 'ts-loader',\n      options: {\n        transpileOnly: true\n      }\n    }\n  ]\n}<\/code><\/pre>\n<p>]<br \/>},<br \/>plugins: [<br \/>  new ForkTsCheckerWebpackPlugin()<br \/>]<br \/>&#8230;\u7528editorconfig\u7edf\u4e00\u7f16\u8f91\u5668\u89c4\u8303\u5728\u6839\u76ee\u5f55\u65b0\u5efa.editorconfig\u5373\u53ef\uff0c\u6ce8\u610f\u4e0d\u8981\u4e0e\u5df2\u6709\u7684lint\u89c4\u5219\u51b2\u7a81\uff1a\/\/ <strong>.editorconfig<\/strong><\/p>\n<h2><a href=\"https:\/\/link.segmentfault.com\/?enc=opG5ZlcOQzTaPtHtrxqFnw%3D%3D.oKUqfMHW%2FdeVfMLqzaCSXOFYmS4tKDEmdau5ZJJNZsE%3D\" rel=\"nofollow\">http:\/\/editorconfig.org<\/a><\/h2>\n<p>root = true<\/p>\n<\/li>\n<\/ul>\n<p>[*]<br \/> indent_style = space<br \/> indent_size = 2<br \/> end_of_line = lf<br \/> charset = utf-8<br \/> trim_trailing_whitespace = true<br \/> insert_final_newline = true<\/p>\n<p>[*.md]<br \/>trim_trailing_whitespace = false<\/p>\n<p>[makefile]<br \/>indent_style = tab<br \/>indent_size = 4Antd\u914d\u7f6ebabel\u4e2d\u914d\u7f6e\u6309\u9700\u52a0\u8f7d\uff1a{<br \/>  &#8220;presets&#8221;: [&#8220;@babel\/react&#8221;, &#8220;@babel\/env&#8221;],<br \/>  &#8220;plugins&#8221;: [<\/p>\n<pre><code>&quot;@babel\/plugin-proposal-class-properties&quot;,\n[\n  &quot;import&quot;,\n  {\n    &quot;libraryName&quot;: &quot;antd&quot;,\n    &quot;libraryDirectory&quot;: &quot;es&quot;,\n    &quot;style&quot;: true \/\/ or 'css'\n  },\n  &quot;antd&quot;\n]<\/code><\/pre>\n<p>]<br \/>}webpack\u4e2d\u5b9a\u5236\u4e3b\u9898\uff1amodule: {<\/p>\n<pre><code>rules: [\n  \/\/ \u5904\u7406 .css\n  {\n    test: \/\/.css$\/,\n    use: ['style-loader', 'css-loader'],\n  },\n  \/\/ \u5904\u7406 .less\n  {\n    test: \/\/.less$\/,\n    use: [\n      'style-loader',\n      'css-loader',\n      \/\/ less-loader\n      {\n        loader: 'less-loader',\n        options: {\n          lessOptions: {\n            \/\/ \u66ff\u6362antd\u7684\u53d8\u91cf\uff0c\u53bb\u6389 @ \u7b26\u53f7\u5373\u53ef\n            \/\/ https:\/\/ant.design\/docs\/react\/customize-theme-cn\n            modifyVars: {\n              'primary-color': '#1DA57A',\n            },\n            javascriptEnabled: true, \/\/ \u652f\u6301js\n          },\n        },\n      },\n    ],\n  },\n]<\/code><\/pre>\n<p>}<br \/>\u6ce8\u610f\u6837\u5f0f\u5fc5\u987b\u52a0\u8f7d less \u683c\u5f0f\uff0c\u4e00\u4e2a\u5e38\u89c1\u7684\u95ee\u9898\u5c31\u662f\u5f15\u5165\u4e86\u591a\u4efd\u6837\u5f0f\uff0cless \u7684\u6837\u5f0f\u88ab css \u7684\u6837\u5f0f\u8986\u76d6\u4e86\u3002ESlint\u914d\u7f6eESlint\u4e3b\u8981\u529f\u80fd\u5305\u542b\u4ee3\u7801\u683c\u5f0f\u548c\u4ee3\u7801\u8d28\u91cf\u7684\u6821\u9a8c\uff0c\u5e76\u4e14\u53ef\u4ee5\u914d\u7f6epre-commit\u6765\u89c4\u8303\u4ee3\u7801\u7684\u63d0\u4ea4\u3002tnpm install -D eslint eslint-webpack-plugin @typescript-eslint\/parser @typescript-eslint\/eslint-plugin eslint-plugin-reacteslint: eslint\u4e3b\u8981\u5f15\u64ceeslint-webpack-plugin: webpack loader@typescript-eslint\/parser: \u5e2e\u52a9ESlint lint ts\u4ee3\u7801@typescript-eslint\/eslint-plugin: \u5305\u542bTS\u6269\u5c55\u89c4\u5219\u7684\u63d2\u4ef6eslint-plugin-react: \u5305\u542bReact\u6269\u5c55\u89c4\u5219\u7684\u63d2\u4ef6ESlint\u914d\u7f6e\u6587\u4ef6\/\/ <em>eslintrc<\/em><br \/>module.exports =  {<br \/>  parser:  &#8216;@typescript-eslint\/parser&#8217;,  \/\/ ESlint Parser<br \/>  extends:  [<\/p>\n<pre><code>'plugin:react\/recommended',  \/\/ \u4ece@eslint-plugin-react\u4e2d\u9009\u62e9\u63a8\u8350\u7684\u89c4\u5219\n'plugin:@typescript-eslint\/recommended',  \/\/ \u4ece@typescript-eslint\/eslint-plugin\u9009\u62e9\u63a8\u8350\u7684\u89c4\u5219<\/code><\/pre>\n<p>],<br \/>  parserOptions:  {<\/p>\n<pre><code>ecmaVersion:  2018,  \/\/ \u5e2e\u52a9\u8f6c\u5316\u6700\u5148\u8fdb\u7684ECMAScript\u529f\u80fd\nsourceType:  'module',  \/\/ \u5141\u8bb8imports\u7684\u7528\u6cd5\necmaFeatures:  {\n  jsx:  true,  \/\/ JSX\u517c\u5bb9\n},<\/code><\/pre>\n<p>},<br \/>  rules:  {<br \/>  },<br \/>  settings:  {<\/p>\n<pre><code>react:  {\n  version:  'detect',  \/\/ \u544a\u8bc9eslint-plugin-react\u81ea\u52a8\u68c0\u6d4b\u6700\u65b0\u7248\u672c\u7684react\n},<\/code><\/pre>\n<p>},<br \/>};Prettier\u914d\u7f6e\u867d\u7136 ESLint \u4e5f\u53ef\u4ee5\u6821\u9a8c\u4ee3\u7801\u683c\u5f0f\uff0c\u4f46 Prettier \u66f4\u64c5\u957f\uff0c\u6240\u4ee5\u9879\u76ee\u4e2d\u4e00\u822c\u4f1a\u642d\u914d\u4e00\u8d77\u4f7f\u7528\u3002\u4e3a\u4e86\u907f\u514d\u4e8c\u8005\u7684\u51b2\u7a81\uff0c\u4e00\u822c\u7684\u89e3\u51b3\u601d\u8def\u662f\u7981\u6389 ESLint \u4e2d\u4e0e Prettier \u51b2\u7a81\u7684\u89c4\u5219\uff0c\u7136\u540e\u4f7f\u7528 Prettier \u505a\u683c\u5f0f\u5316\uff0c ESLint \u505a\u4ee3\u7801\u6821\u9a8c\u3002prettier\u914d\u7f6e\u6587\u4ef6{<br \/>  &#8220;arrowParens&#8221;: &#8220;avoid&#8221;,<br \/>  &#8220;bracketSpacing&#8221;: true,<br \/>  &#8220;embeddedLanguageFormatting&#8221;: &#8220;auto&#8221;,<br \/>  &#8220;htmlWhitespaceSensitivity&#8221;: &#8220;css&#8221;,<br \/>  &#8220;insertPragma&#8221;: false,<br \/>  &#8220;jsxBracketSameLine&#8221;: true,<br \/>  &#8220;jsxSingleQuote&#8221;: false,<br \/>  &#8220;printWidth&#8221;: 100,<br \/>  &#8220;proseWrap&#8221;: &#8220;preserve&#8221;,<br \/>  &#8220;quoteProps&#8221;: &#8220;as-needed&#8221;,<br \/>  &#8220;requirePragma&#8221;: false,<br \/>  &#8220;semi&#8221;: true,<br \/>  &#8220;singleQuote&#8221;: true,<br \/>  &#8220;tabWidth&#8221;: 2,<br \/>  &#8220;trailingComma&#8221;: &#8220;es5&#8221;,<br \/>  &#8220;useTabs&#8221;: true,<br \/>  &#8220;vueIndentScriptAndStyle&#8221;: false<br \/>}\u4ee3\u7801\u63d0\u4ea4\u89c4\u8303prettier \u53ea\u662f\u4fdd\u8bc1\u4e86\u5728\u901a\u8fc7\u7f16\u8f91\u5668\uff08vs code\uff09\u8fdb\u884c\u683c\u5f0f\u5316\u4ee3\u7801\u7684\u65f6\u5019\uff0c\u683c\u5f0f\u5316\u6210\u9700\u8981\u7684\u683c\u5f0f\uff08\u5f53\u7136\u53ef\u4ee5\u901a\u8fc7\u914d\u7f6e onSave \u5728\u4ee3\u7801\u4fdd\u5b58\u65f6\u81ea\u52a8\u683c\u5f0f\u5316\uff09\uff0c\u4f46\u662f\u65e0\u6cd5\u4fdd\u8bc1\u6240\u6709\u4eba\u90fd\u4f1a\u4e3b\u52a8\u8fdb\u884c\u3002\u56e0\u6b64\u8fdb\u884c\u81ea\u52a8\u683c\u5f0f\u5316\u663e\u5f97\u975e\u5e38\u91cd\u8981\uff0c\u800c\u81ea\u52a8\u683c\u5f0f\u5316\u7684\u662f\u65f6\u673a\u9009\u62e9 pre-commit \u6700\u6070\u5f53\uff0c\u901a\u8fc7 git hook \uff0c\u80fd\u591f\u5728 commit \u4e4b\u524d\u683c\u5f0f\u5316\u597d\u4ee3\u7801\uff08\u5982\u679c\u5df2\u7ecf commit\uff0c\u4f1a\u5c06\u6682\u5b58\u8f6c\u4e3a\u63d0\u4ea4\uff0c\u751f\u6210\u63d0\u4ea4\u8bb0\u5f55\uff0c\u9700\u8981\u56de\u6eda\u624d\u4f1a\u64a4\u9500\uff09\u3002tnpm i -D pretty-quick prettier husky pretty-quick: \u914d\u5408git-hooks\u8fdb\u884c\u4ee3\u7801\u68c0\u6d4b\uff0c\u5e76\u4e14fixhusky: \u53ef\u4ee5\u901a\u8fc7\u914d\u7f6e\u7684\u65b9\u5f0f\u6765\u4f7f\u7528git-hooks\uff0c\u907f\u514d\u624b\u52a8\u4fee\u6539package.json\u8bbe\u7f6e&#8221;pretty&#8221;: &#8220;.\/node_modules\/.bin\/pretty-quick &#8211;staged&#8221;<br \/>&#8230;<br \/>&#8220;husky&#8221;: {<\/p>\n<pre><code>&quot;hooks&quot;: {\n  &quot;pre-commit&quot;: &quot;tnpm run pretty&quot;\n}<\/code><\/pre>\n<p>},Webpack\u5b8c\u6574\u914d\u7f6e\u6700\u540e\u8d34\u4e00\u4e0b\u5b8c\u6574\u7684\u914d\u7f6e\uff0c\u56e0\u4e3aAone\u53d1\u5e03\u81ea\u52a8\u66f4\u65b0\u7248\u672c\u53f7\uff0c\u6240\u4ee5\u4e0d\u7528\u62c6\u5206config\u6587\u4ef6\u6765\u6839\u636e\u73af\u5883\u8bbe\u7f6e\u7f13\u5b58\uff0c\u5e76\u4e14\u914d\u7f6e\u5df2\u7ecf\u5c3d\u53ef\u80fd\u7b80\u5316\uff0c\u62c6\u5206\u53cd\u800c\u4f1a\u589e\u52a0\u7ef4\u62a4\u6210\u672c\u3002\/\/_webpack.config.js_<br \/>\/\/webpack.config.js<br \/>const path = require(&#8216;path&#8217;);<br \/>const HtmlWebpackPlugin = require(&#8216;html-webpack-plugin&#8217;);<br \/>const MiniCssExtractPlugin = require(&#8216;mini-css-extract-plugin&#8217;);<br \/>const OptimizeCSSAssetsPlugin = require(&#8216;optimize-css-assets-webpack-plugin&#8217;);<br \/>const TerserPlugin = require(&#8216;terser-webpack-plugin&#8217;);<br \/>const ForkTsCheckerWebpackPlugin = require(&#8216;fork-ts-checker-webpack-plugin&#8217;);<br \/>const { BundleAnalyzerPlugin } = require(&#8216;webpack-bundle-analyzer&#8217;);<br \/>const ESLintPlugin = require(&#8216;eslint-webpack-plugin&#8217;);<\/p>\n<p>const { DEV, DEBUG } = process.env;<\/p>\n<p>process.env.BABEL_ENV = DEV ? &#8216;development&#8217; : &#8216;production&#8217;;<br \/>process.env.NODE_ENV = DEV ? &#8216;development&#8217; : &#8216;production&#8217;;<\/p>\n<p>module.exports = {<br \/>  entry: &#8216;.\/src\/index.tsx&#8217;,<br \/>  output: {<\/p>\n<pre><code>path: path.join(__dirname, '\/dist'),\nfilename: 'bundle.js',\nclean: true,<\/code><\/pre>\n<p>},<br \/>  devServer: {<\/p>\n<pre><code>port: 8080,<\/code><\/pre>\n<p>},<br \/>  mode: DEV ? &#8216;development&#8217; : &#8216;production&#8217;,<br \/>  devtool: DEV &#038;&#038; &#8216;source-map&#8217;,<br \/>  module: {<\/p>\n<pre><code>rules: [\n  {\n    test: \/\/.jsx?$\/,\n    exclude: \/node_modules\/,\n    loader: 'babel-loader',\n  },\n  {\n    test: \/\/.tsx?$\/,\n    exclude: \/node_modules\/,\n    loader: 'ts-loader',\n  },\n  {\n    test: \/\/.css$\/,\n    use: ['style-loader', 'css-loader'],\n  },\n  \/\/ \u5904\u7406 .less\n  {\n    test: \/\/.less$\/,\n    use: [\n      'style-loader',\n      'css-loader',\n      \/\/ less-loader\n      {\n        loader: 'less-loader',\n        options: {\n          lessOptions: {\n            \/\/ \u66ff\u6362antd\u7684\u53d8\u91cf\uff0c\u53bb\u6389 @ \u7b26\u53f7\u5373\u53ef\n            \/\/ https:\/\/ant.design\/docs\/react\/customize-theme-cn\n            modifyVars: {\n              'primary-color': '#1DA57A',\n              'border-color-base': '#d9d9d9', \/\/ \u8fb9\u6846\u8272\n              'text-color': '#d9d9d9'\n            },\n            javascriptEnabled: true, \/\/ \u652f\u6301js\n          },\n        },\n      },\n    ],\n  },\n  {\n    test: \/\/.(sass|scss)$\/,\n    use: [\n      {\n        loader: MiniCssExtractPlugin.loader,\n      },\n      {\n        loader: 'css-loader',\n        options: {\n          importLoaders: 2,\n          sourceMap: !!DEV,\n        },\n      },\n      {\n        loader: 'sass-loader',\n        options: {\n          sourceMap: !!DEV,\n        },\n      },\n    ],\n  },\n  {\n    test: \/\/.png\/,\n    type: 'asset\/resource',\n  },\n  {\n    test: \/\/.(woff|woff2|eot|ttf|otf)$\/i,\n    type: 'asset\/resource',\n  },\n  {\n    test: \/\/.(csv|tsv)$\/i,\n    use: ['csv-loader'],\n  },\n  {\n    test: \/\/.xml$\/i,\n    use: ['xml-loader'],\n  },\n],<\/code><\/pre>\n<p>},<br \/>  optimization: {<\/p>\n<pre><code>minimizer: [\n  new TerserPlugin({\n    parallel: false,\n    terserOptions: {\n      output: {\n        comments: false,\n      },\n    },\n  }),\n  new OptimizeCSSAssetsPlugin({}),\n],\nminimize: !DEV,\nsplitChunks: {\n  minSize: 500000,\n  cacheGroups: {\n    vendors: false,\n  },\n},<\/code><\/pre>\n<p>},<br \/>  resolve: {<\/p>\n<pre><code>modules: ['node_modules'],\nextensions: ['.json', '.js', '.jsx', '.ts', '.tsx', '.less', 'scss'],<\/code><\/pre>\n<p>},<br \/>  plugins: [<\/p>\n<pre><code>new HtmlWebpackPlugin({\n  template: path.join(__dirname, '\/src\/index.html'),\n  filename: 'app.html',\n  inject: 'body',\n}),\nDEBUG &amp;&amp; new BundleAnalyzerPlugin(),\nnew MiniCssExtractPlugin({\n  filename: '[name].css',\n  chunkFilename: '[name].css',\n}),\nnew ESLintPlugin(),\nnew ForkTsCheckerWebpackPlugin(),<\/code><\/pre>\n<p>].filter(Boolean),<br \/>};\u603b\u7ed3\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb0\u5f55\u4e86\u5f00\u53d1\u8fc7\u7a0b\u4e2d\u4ece\u9879\u76ee\u521d\u59cb\u5316\u5f00\u59cb\uff0c\u518d\u5230\u4e00\u4e2a\u6807\u51c6\u5316\u524d\u7aef\u9879\u76ee\u7684\u642d\u5efa\u8def\u7a0b\u3002\u6d89\u53ca\u76f8\u5173\u4ee3\u7801\u89c4\u8303\u3001\u5f00\u53d1\u73af\u5883\u642d\u5efa\u3001\u751f\u4ea7\u73af\u5883\u4f18\u5316\u7b49\uff0c\u65e8\u5728\u6253\u9020\u51fa\u4e00\u4e2a\u53ef\u5feb\u901f\u4f7f\u7528\u7684\u73b0\u4ee3Webpack5.x+React18.x+Typescript+Antd4.x\u6a21\u677f\uff0c\u4ee5\u4f9b\u5728\u4ee5\u540e\u7684\u5b9e\u9645\u4e1a\u52a1\u573a\u666f\u9700\u6c42\u4e2d\u96f6\u6210\u672c\u4f7f\u7528\u3002\u63a8\u8350\u9605\u8bfb1.\u7814\u53d1\u6548\u80fd\u7684\u601d\u8003\u603b\u7ed32.\u5173\u4e8e\u6280\u672f\u80fd\u529b\u7684\u601d\u8003\u548c\u603b\u7ed33. \u5982\u4f55\u7ed3\u6784\u5316\u548c\u6e05\u6670\u5730\u8fdb\u884c\u8868\u8fbe\u00a0\u91cd\u78c5\u6765\u88ad\uff012022\u4e0a\u534a\u5e74\u963f\u91cc\u4e91\u793e\u533a\u6700\u70ed\u7535\u5b50\u4e66\u699c\u5355\uff01\u00a0\u5343\u4e07\u9605\u8bfb\u91cf\u3001\u767e\u4e07\u4e0b\u8f7d\u91cf\u3001\u4e0a\u767e\u672c\u7535\u5b50\u4e66\uff0c\u8fd1200\u4f4d\u963f\u91cc\u4e13\u5bb6\u53c2\u4e0e\u7f16\u5199\u3002\u591a\u5143\u5316\u9009\u62e9\u3001\u5168\u9886\u57df\u8986\u76d6\uff0c\u6c47\u805a\u963f\u91cc\u5df4\u5df4\u6280\u672f\u5b9e\u8df5\u7cbe\u534e\uff0c\u8bfb\u3001\u5b66\u3001\u7ec3\u4e00\u952e\u4e09\u8fde\u3002\u5f00\u53d1\u8005\u85cf\u7ecf\u9601\uff0c\u5f00\u53d1\u8005\u7684\u5de5\u4f5c\u4f34\u4fa3~\u70b9\u51fb\u8fd9\u91cc\uff0c\u67e5\u770b\u8be6\u60c5\u3002\u539f\u6587\u94fe\u63a5\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=qXajslV8BCNNGajQ48vT9A%3D%3D.seMOYBDT%2BvzHBh9yB7EPP5NMCRKAYsYGALPNXD8Epue35AyOfNAWBKPcscRHdpX4\" rel=\"nofollow\">https:\/\/click.aliyun.com\/m\/10&#8230;<\/a>\u672c\u6587\u4e3a\u963f\u91cc\u4e91\u539f\u521b\u5185\u5bb9\uff0c\u672a\u7ecf\u5141\u8bb8\u4e0d\u5f97\u8f6c\u8f7d\u3002<\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042444953\">https:\/\/segmentfault.com\/a\/1190000042444953<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u4ecb\uff1a\u00a0\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u89e3\u5982\u4f55\u4ece\u4e00\u4e2a\u7a7a\u76ee\u5f55\u5f00\u59cb\uff0c\u5efa\u7acb\u8d77\u4e00\u4e2a\u57fa\u4e8ewebpack + react + typescr [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10006431","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10006431"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006431\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}