从零开始搭建react基础开发环境(基于webpack5)

  • 从零开始搭建react基础开发环境(基于webpack5)已关闭评论
  • 151 次浏览
  • A+
所属分类:Web前端
摘要

最近利用闲暇时间把webpack系统的学习了下,搭建出一个react环境的脚手架,写篇文章总结一下,帮助正在学习webpack小伙伴们,如有写的不对的地方或还有可以优化的地方,望大佬们指出,及时改正。


前言

最近利用闲暇时间把webpack系统的学习了下,搭建出一个react环境的脚手架,写篇文章总结一下,帮助正在学习webpack小伙伴们,如有写的不对的地方或还有可以优化的地方,望大佬们指出,及时改正。

git项目地址:https://github.com/handsomezyw/my-webpack

初始化项目

  1. 新建文件夹起名为my-webpack(文件夹名字任意取),然后初始化项目,使用如下指令,会在你的项目根目录生成package.json文件,-y 参数是省去填写初始化的package.json信息。
npm init -y 

接着安装webpack、webpack-cli、webpack-dev-server

npm install webpack webpack-cli webpack-dev-server --save-dev 
  1. 创建src文件夹存放代码等文件,在src文件夹下创建webpack入口文件app.tsx
  2. 创建config文件夹用来保存我们的webpack配置文件,方便扩展管理,使用webpack-merge库将我们写的配置文件组合起来(记得用npm安装webpack-merge)。
  • 创建基础配置文件 webpack.base.js
  • 创建开发环境配置文件 webpack.dev.js
  • 创建生产环境配置文件 webpack.prod.js

从零开始搭建react基础开发环境(基于webpack5)

配置文件编写

webpack.base.js文件(基础配置)

const path = require("path");  // 当前项目工作目录根路径 const RootProject = process.cwd(); // 根据参数获取需要的绝对路径 const getPath = (pathStr) => {   return path.resolve(RootProject, `${pathStr}`); };  module.exports = {   // 入口文件路径   entry:getPath("./src/app.tsx"),    // 使用插件   plugins: [],   module: {     // 对模块(module)应用 loader     rules: [],   }, }; 

webpack.dev.js文件

const path = require("path"); // 合并文件配置 const { merge } = require("webpack-merge"); // 基础配置 const baseConfig = require("./webpack.base"); // 当前项目工作目录根路径 const RootProject = process.cwd(); // 根据参数获取需要的绝对路径 const getPath = (pathStr) => {   return path.resolve(RootProject, `${pathStr}`); };  // 开发环境配置 const devConfig = {   // 开发模式   mode: "development",   // 只在发生错误时输出   stats: "errors-only",   // source map风格   devtool: "inline-source-map",   // webpack-dev-server 配置   devServer: {     // 从目录提供静态文件的选项(默认是 'public' 文件夹)     static: getPath("./public"),     // 启用 webpack 的 热模块替换 特性     hot: true,     // 当使用HTML5 History API时,index.html页面可能要代替404响应。     // 解决了使用react-router-dom 使用 BrowserRouter 模式时,在     // 浏览器输入路由地址是会请求接口报错的问题     historyApiFallback: true,    }, };  module.exports = merge(baseConfig, devConfig); 

webpack.prod.js文件

const path = require("path"); // 合并文件配置 const { merge } = require("webpack-merge"); // 基础配置 const baseConfig = require("./webpack.base"); // 当前项目工作目录根路径 const RootProject = process.cwd(); // 根据参数获取需要的绝对路径 const getPath = (pathStr) => {   return path.resolve(RootProject, `${pathStr}`); };  // 生产环境配置 const prodConfig = {     // 生产模式   mode: "production",   // 打包输出配置   output: {     // 打包输出路径     path: getPath("./dist"),     // 打包输出文件名     filename: "[name]_[chunkhash:8].js",     // 开启打包清理文件夹功能     clean: true,   },   // 使用插件   plugins: [], };  module.exports = merge(baseConfig, prodConfig); 

接着我们在package.json文件添加运行指令

从零开始搭建react基础开发环境(基于webpack5)

--config参数是指定运行使用的配置文件路径

当我们在命令行使用npm run start命令的时候就会运行webpack-dev-server开启 web server服务,并具有实时重新加载的功能,当我们修改文件时,不需要手动刷新浏览器,就能看到修改后的效果。

当我们在命令行使用npm run start命令的时候就会运行webpack构建打包我们的项目

至此webpack的基础配置结构就写好了,接下来就是开始完善配置文件功能。

使用html-webpack-plugin

这个插件可以帮我们生成一个html文件,在 body 中使用 script 标签引入你所有 webpack 生成的 bundle,也即是我们output输出的文件。这样就不需要每次手动创建一个html文件,在手动引入我们打包好的js文件。
安装依赖

npm install --save-dev html-webpack-plugin 

在我们的webpack.base.js加入使用

// webpack.base.js // 生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = {     new HtmlWebpackPlugin({       // 模版文件       template: getPath("./public/index.html"),       filename: "index.html",       inject: true,       minify: {         html5: true, // 根据HTML5规范解析输入         collapseWhitespace: true, // 折叠构成文档树中文本节点的空白         preserveLineBreaks: false, // 当标签之间的空格包含换行符时,总是折叠为1个换行符(永远不要完全删除它)。必须与collapseWhitespace=true一起使用         minifyCSS: true, // 在样式元素和样式属性中缩小CSS(使用clean-css)         minifyJS: true, // 在脚本元素和事件属性中最小化JavaScript(使用Terser)         removeComments: false, // 带HTML注释       },     }), } 

解析jsx语法

  • 将es2015+的语法代码转换为向后兼容的 JavaScript 语法
  • 解析jsx语法

为了提升webpack构建速度,我们可以在使用loader的时候限定解析的范围,使用include,这里需要注意的是,
一般设置src,但是有时node_modules的第三方依赖打包好的库,可能含有es6的语法,为了更好的兼容性,我们可以把第三方的依赖库通过include加入到解析名单,比如:include:["./src","./node_modules/react-router-dom"],不过觉得麻烦的话,又不在意构建速度的话,可以不限定解析范围。

这里我们使用babel-loader来帮助我们解析jsx和es2015以后的版本语法。

使用core-js给我们新的js api打补丁(polyfill)。

关于babel可前往babel官网查看更多配置用法。

安装所需依赖

npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react core-js 

接着在webpack.base.js文件中添加babel-loader解析js,jsx文件

// webpack.base.js //...  module: {     // 对模块(module)应用 loader     rules: [       {         test: /.jsx?$/,         // include限定解析范围         include: getPath("./src"),         use: [           {             loader: "babel-loader",             options: {               presets: [                 [                    // 解析js预设                   "@babel/preset-env",                   {                     // 自动打补丁                     useBuiltIns: "usage",                     // 指定core-js版本                     corejs: { version: "3.24.1", proposals: true },                   },                 ],                 // 解析jsx预设                 "@babel/preset-react",               ],               plugins: [],             },           },         ],       },     ],   }, //... 

解析css、less文件

  • 解析css、less
  • 提取css成单独文件
  • css浏览器前缀补齐
  • 开启css modules
  • 引入全局less变量

安装所需依赖

npm install --save-dev css-loader less less-loader mini-css-extract-plugin postcss-loader postcss style-resources-loader 

这里需要注意的是css前缀补齐,还需要在package.json文件添加browserlist属性指定版本,不然css补齐前缀不生效。

从零开始搭建react基础开发环境(基于webpack5)

//webpack.base.js // 将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //... plugins: [     new MiniCssExtractPlugin({       // 提取css文件 文件名       filename: "[name]_[contenthash:8].css",     }), ]  module: {     // 对模块(module)应用 loader     rules: [        {         test: /.css$/,         use: [           // "style-loader",           MiniCssExtractPlugin.loader,           {             loader: "css-loader",             options: {               modules: {                 auto: true,                 localIdentName: "[path][name]__[local]--[hash:base64:5]",               },               importLoaders: 1,             },           },           {             loader: "postcss-loader",             options: {               postcssOptions: {                 plugins: ["postcss-preset-env"],               },             },           },         ],       },       {         test: /.less$/,         use: [           // "style-loader", //将style插入到head中           MiniCssExtractPlugin.loader, // 提取css成单独文件           {             loader: "css-loader",             options: {               modules: {                 auto: true, // 允许根据文件名中含有module的文件开启css modules                 localIdentName: "[path][name]__[local]--[hash:base64:5]", // 允许配置生成的本地标识符(ident)               },               // css-loader之前加载多少个loader               importLoaders: 3,             },           },           {             loader: "postcss-loader",             options: {               postcssOptions: {                 // 包含添加css前缀的预设                 plugins: ["postcss-preset-env"],               },             },           },           {             loader: "less-loader",             options: {               // 生成source map               sourceMap: true,             },           },           {             // 将定义全局的less变量注入到其他样式文件,无须手动引入             loader: "style-resources-loader",             options: {               patterns: [getPath("./src/global.less")],             },           },         ],       },     ],   }, //... 

解析图片资源

// webpack.base.js //... module:{     rules: [       {         test: /.(png|jpg|gif|jpeg)$/,         type: "asset/resource",       },     ] } //... 

解析字体资源

// webpack.base.js //... module:{     rules: [       {         test: /.(woff|woff2|eot|ttf|otf)$/,         type: "asset/resource",       },     ] } //... 

解析ts、tsx

安装所需依赖

npm install --save-dev typescript ts-loader fork-ts-checker-webpack-plugin 

安装完依赖后,初始化ts生成ts配置文件tsconfig.json,使用如下指令(确保当前命令行所处位置为项目根目录):

 node_modules/.bin/tsc --init 

从零开始搭建react基础开发环境(基于webpack5)
修改tsconfig.json文件的配置(关于配置可前往ts官网查询)

{     "compilerOptions": {         "target": "ES5",         "module": "ES6",         "jsx": "react",         "paths": {           "@/*": ["./src/*"]         },         "sourceMap": true,     } } 
// webpack.base.js // 在一个独立进程上运行TypeScript类型检查器的Webpack插件。 const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); //... plugins: [     new ForkTsCheckerWebpackPlugin() ], module:{     rules: [       {         test: /.tsx?$/,         use: "ts-loader",         include: getPath("./src"),       },     ] } //... 

命令行显示的信息优化

通常我们运行项目时都会显示很多构建信息

从零开始搭建react基础开发环境(基于webpack5)

每次重新编译都会有一大堆信息,显然不利于我们专注研发,为此我们可以通过stats设置显示信息的风格。

在使用一个插件优化显示命令行显示。

npm install --save-dev @soda/friendly-errors-webpack-plugin 
// webpack.base.js // 命令行提示优化插件 const FriendlyErrorsWebpackPlugin = require("@soda/friendly-errors-webpack-plugin"); module.exports = { // ... // 只在发生错误时输出 stats: "errors-only", plugins: [new FriendlyErrorsWebpackPlugin()] // ... } 

效果如下

从零开始搭建react基础开发环境(基于webpack5)

eslint prettier配置

使用eslint和prettier帮助我们检查代码格式是否正确和统一代码格式。

vscode安装ESLint、Prettier插件。

这里我们使用airbnb公司的eslint基础规则。

先安装依赖

npm install --save-dev eslint-config-airbnb eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y 

然后在创建.eslintrc.js文件,配置我们的eslint规则。配置选项可前往eslint官网查看。

module.exports = {   env: {     node: true, // 启用node中全局变量     browser: true, // 启用浏览器中全局变量   },   // extends: "eslint:recommended",   extends: ["airbnb", "airbnb/hooks", "plugin:prettier/recommended", "prettier"],    parserOptions: {     ecmaFeatures: {       jsx: true,     },     ecmaVersion: "latest",     sourceType: "module",   },   settings: {     "import/resolver": {       webpack: {         config: "./config/webpack.base.js",       },     },   },   rules: {     // "off" or 0 - 关闭规则     // "warn" or 1 - 将规则视为一个警告(不会影响退出码)     // "error" or 2 - 将规则视为一个错误 (退出码为1)      // 要求或禁止在类成员之间出现空行     "lines-between-class-members": [0, "always"],     // 允许的扩展集是可配置的 jsx可以出现在js中     "react/jsx-filename-extension": [       1,       {         extensions: [".js", ".jsx"],       },     ],     // 函数组件声明方式     "react/function-component-definition": [       2,       {         namedComponents: ["function-declaration", "function-expression", "arrow-function"],         unnamedComponents: ["function-expression", "arrow-function"],       },     ],     // 禁用 console     "no-console": "off",     // 要求 require() 出现在顶层模块作用域中     "global-require": "off",     "import/no-extraneous-dependencies": "off",   }, }; 

接着安装eslint-webpack-plugin插件,该插件使用 eslint 来查找和修复 JavaScript 代码中的问题。

npm install eslint-webpack-plugin --save-dev 

接着在我们webpack配置文件中使用eslint-webpack-plugin插件

// webpack.base.js const path = require("path"); // 使用 eslint 来查找和修复 JavaScript 代码中的问题 const ESLintWebpackPlugin = require("eslint-webpack-plugin"); // 当前项目工作目录根路径 const RootProject = process.cwd(); // 根据参数获取需要的绝对路径 const getPath = (pathStr) => {   return path.resolve(RootProject, `${pathStr}`); }; module.exports = {     plugins: [          new ESLintWebpackPlugin({           // 指定检查文件的根目录           context: getPath("./src"),         }),     ] } 

eslint配置完后,在创建.prettierrc.js文件配置Prettier。配置选项可前往Prettier官网查看。

module.exports = {   // 一行最多 100 字符   printWidth: 100,   // 关闭 tab 缩进   useTabs: false,   // 使用 2个tab 缩进   tabWidth: 2,   // 行尾需要有分号   semi: true,   // 使用单引号   singleQuote: false,   // 对象key是否使用引号    // as-needed 仅在需要的时候使用   // consistent 有一个属性需要引号,就都需要引号   // preserve 保留用户输入的情况   quoteProps: "as-needed",   // jsx 使用单引号代替双引号   jsxSingleQuote: false,   // 末尾不需要逗号    trailingComma: "all",   // 大括号内的首尾需要空格   bracketSpacing: true,   // jsx 标签的反尖括号需要换行   jsxBracketSameLine: false,   // 箭头函数,只有一个参数的时候,也需要括号 <always|avoid>   arrowParens: "always", }; 

需要注意的是ESLint和Prettier配置可能会产生冲突,这时我们可以安装eslint-config-prettier插件和eslint-plugin-prettier插件,来解决冲突。

eslint-config-prettier插件 关闭所有可能与Prettier冲突的ESlint规则 使用要在eslint配置文件的extends数组最后加"prettier"

eslint-plugin-prettier插件 将Prettier作为ESLint的规则来使用,相当于代码不符合Prettier的规范时,会有提示信息 使用要在eslint配置文件的extends数组加入"plugin:prettier/recommended"

安装依赖

npm install --save-dev eslint-config-prettier eslint-plugin-prettier prettier 

这样配置就完成了,如果有什么需要修改的规则可在.eslintrc.js文件中修改rules来修改elslint规则。

单元测试

我们可以写一些单元测试检测我们脚手架基础功能是否有问题,比如是否生成js文件,css文件,index.html。

这里我们使用mocha测试框架来编写我们的测试用例。

安装依赖

npm install --save-dev mocha 

接着在我们项目下创建test文件夹

从零开始搭建react基础开发环境(基于webpack5)

接着在test文件夹下创建index.js文件编写测试用例。

// index.js // 这里我们使用了glob-all库来判断是否有文件(记得安装这个库) const glob = require("glob-all");  describe("检查是否生成了html文件", () => {   it("生成html文件", (done) => {     const files = glob.sync(["./dist/index.html"]);      if (files.length > 0) {       done();     } else {       throw new Error("生成html文件失败");     }   }); }); 

然后在package.json文件加入运行测试指令

从零开始搭建react基础开发环境(基于webpack5)

先运行指令npm run build指令打包,成功后在运行npm run test指令

从零开始搭建react基础开发环境(基于webpack5)

这样一个简单的测试用例就完成了。

接下来就是查看测试覆盖率,可以使用nyc这个库,有兴趣可以去看看。

构建速度优化

随着项目文件的增多,webpack打包和运行项目的速度必然会下降,我们可以优化一下。

限定解析范围(include,exclude)

我们可以在使用loader的时候,使用include,exclude去控制解析文件的范围,比如只解析src文件夹下的文件include: ["./src"]。

开启多进程构建

使用 thread-loader 来开启多进程构建,提升我们的构建速度。

安装依赖

npm install --save-dev thread-loader 

然后在我们使用的loader前面加入(也就是放在use数组第一位),因为loader的解析是从右往左解析的,所以放在第一个。

需要注意的是ts-loader配合thread-loader,我们得多一点额外的设置

// 在一个独立进程上运行TypeScript类型检查器的Webpack插件。 const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");  module.exports = {     plugins: [             new ForkTsCheckerWebpackPlugin({               typescript: {                 diagnosticOptions: {                   semantic: true,                   syntactic: true,                 },           },         })     ],     module: {         rules: [             {                 test: /.tsx?$/,                 use: [                     {                         loader: "ts-loader",                         options: {                           happyPackMode: true,                         },                     }                 ]             }         ]     } } 
// webpack官网thread-loader的例子 use: [   {     loader: "thread-loader",     // 有同样配置的 loader 会共享一个 worker 池     options: {       // 产生的 worker 的数量,默认是 (cpu 核心数 - 1),或者,       // 在 require('os').cpus() 是 undefined 时回退至 1       workers: 2,        // 一个 worker 进程中并行执行工作的数量       // 默认为 20       workerParallelJobs: 50,        // 额外的 node.js 参数       workerNodeArgs: ['--max-old-space-size=1024'],        // 允许重新生成一个僵死的 work 池       // 这个过程会降低整体编译速度       // 并且开发环境应该设置为 false       poolRespawn: false,        // 闲置时定时删除 worker 进程       // 默认为 500(ms)       // 可以设置为无穷大,这样在监视模式(--watch)下可以保持 worker 持续存在       poolTimeout: 2000,        // 池分配给 worker 的工作数量       // 默认为 200       // 降低这个数值会降低总体的效率,但是会提升工作分布更均一       poolParallelJobs: 50,        // 池的名称       // 可以修改名称来创建其余选项都一样的池       name: "my-pool"     },   },   // 耗时的 loader(例如 babel-loader) ]; 

开启多进程压缩

webpack5默认是使用TerserWebpackPlugin插件来压缩js,可使用多进程并发运行以提高构建速度。
把下面的配置加入到我们的webpack.prod.js配置文件中,开启多进程并发运行压缩。

module.exports = {   optimization: {     minimize: true,     minimizer: [       new TerserPlugin({         // 开启多进程并发运行         parallel: true,       }),     ],   }, }; 

预编译资源

预编译资源就是我们可以把不需要经常变动的第三方依赖,如react,react-dom等,提前打包好,在webpack构建时不用在去编译已经编译好的依赖了,这样就可以大幅提升构建速度。

在webpack中,我们使用DllPlugin 和 DllReferencePlugin这两个webpack自带的插件,帮助我们完成资源预编译。

首先在我们的config文件夹下创建webpack.dll.js,写入如下代码

const path = require("path"); const webpack = require("webpack");  // 当前项目工作目录路径 const RootProject = process.cwd();  module.exports = {   entry: {     // 根据你的需要添加,这里是把react,react-dom预编译     library: ["react", "react-dom"],   },   output: {     filename: "[name].dll.js",     path: path.resolve(RootProject, "./library"),     library: "[name]_[hash]",   },   plugins: [     new webpack.DllPlugin({       // 与output.library保持一致       name: "[name]_[hash]",       path: path.resolve(RootProject, "./library/[name]-manifest.json"),     }),   ], }; 

然后在package.json加入运行构建指令

从零开始搭建react基础开发环境(基于webpack5)

然后我们预编译资源的配置就写好了,接着安装react,react-dom,

npm install react react-dom  

接着在命令行运行npm run dll指令生成预编译资源资源

从零开始搭建react基础开发环境(基于webpack5)

可以看到成功生成了library文件夹及文件夹下的预编译资源library.dll.js,文件夹中json文件是给DllReferencePlugin使用告诉webpack哪些是编译好的资源,不用在编译了。

最后在我们的webpack.prod.js文件中使用DllReferencePlugin。还有帮我们把预编译资源引入到项目中的插件add-asset-html-webpack-plugin(其实就是把我们生成的预编译文件复制一份到webpack的ouput输出目录,并把它通过script标签引入到output输出目录下的index.html文件中)

npm install --save-dev add-asset-html-webpack-plugin 
// webpack.prod.js const webpack = require("webpack"); // 将指定js文件提取至压缩目录,并用script标签引入 const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin");  module.exports = {     plugins: [         new webpack.DllReferencePlugin({           // 编译时用于加载 JSON manifest 的绝对路径           manifest: require(getPath("./library/library-manifest.json")),         }),         new AddAssetHtmlPlugin({           filepath: getPath("./library/library.dll.js"),           publicPath: "./",         }),     ] } 

这样就完成了预解析资源。

构建体积优化

随着项目文件的增多,打包出来bundle体积会越来越大,我们可以做些优化。

使用cdn引入第三方库

防止将某些import的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖。
比如下面的例子,lodash不会被打包到项目中,而是通过cdn的形式引入。

// 官方文档例子 module.exports = {   // ...   externalsType: 'script',   externals: {     lodash: ['https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js', '_'],   }, };  // 使用 import _ from 'lodash'; console.log(_.head([1, 2, 3])); 

包体积分析,针对优化

我们可以使用webpack-bundle-analyzer插件,分析打包好的文件大小,便于我们分析优化哪个文件过大,针对的去做一些优化。

安装依赖

npm install --save-dev webpack-bundle-analyzer 
// webpack.prod.js // 分析构建体积插件 const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");  module.exports = {     plugins: [         new BundleAnalyzerPlugin()     ] } 

运行完构建效果如下

从零开始搭建react基础开发环境(基于webpack5)

图片压缩

图片压缩我们可以使用image-minimizer-webpack-plugin插件(下载可能有点慢,多下几次),这里我们使用无损压缩。

npm install --save-dev image-minimizer-webpack-plugin imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo 
// webpack.prod.js // 图片压缩插件(使用无损压缩配置) const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); module.exports = {     new ImageMinimizerPlugin({       minimizer: {         // implementation: ImageMinimizerPlugin.imageminMinify,         implementation: ImageMinimizerPlugin.imageminGenerate,         options: {           // Lossless optimization with custom option           // Feel free to experiment with options for better result for you           plugins: [             ["gifsicle", { interlaced: true }],             ["jpegtran", { progressive: true }],             ["optipng", { optimizationLevel: 5 }],             // Svgo configuration here https://github.com/svg/svgo#configuration             [               "svgo",               {                 plugins: [                   {                     name: "preset-default",                     params: {                       overrides: {                         // customize default plugin options                         inlineStyles: {                           onlyMatchedOnce: false,                         },                         // or disable plugins                         removeDoctype: false,                       },                     },                   },                 ],               },             ],           ],         },       },     }), } 

css压缩

我们可以使用css-minimizer-webpack-plugin这个插件来帮我们压缩css文件。

需要注意的是,使用这个插件会导致terser-webpack-plugin插件压缩js失效,解决办法是再次引入terser-webpack-plugin

安装依赖

npm install --save-dev css-minimizer-webpack-plugin 
// webpack.prod.js // 这个插件使用 cssnano 优化和压缩 CSS。 const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 压缩js插件 const TerserPlugin = require("terser-webpack-plugin"); module.exports = {     optimization: {         minimize: true,         minimizer: [           new CssMinimizerPlugin(),           new TerserPlugin({             parallel: 4           }),         ],     } } 

SplitChunksPlugin

我们可以通过SplitChunksPlugin来抽取公共资源包,如lodash等,达到减小打包的体积。
使用如下配置,当我们项目中引用到了lodash库的时候,lodash会被单独抽取出来,在名为vendor开头的js文件中。

module.exports = {     splitChunks: {       cacheGroups: {         vendor: {           test: /[\/]node_modules[\/](lodash)[\/]/,           name: "vendor",           chunks: "all",         },       },     },   }, } 

从零开始搭建react基础开发环境(基于webpack5)

关于自动部署

之前买了个腾讯云的服务器,最近打算写写express练练手,但是发现个问题,我打包好的文件怎么弄到服务器上去,然后就去百度了解了下ssh传输文件,前提是你的服务器要安装openssh-server,可以百度一下安装方法,安装好了后,就可以使用sftp(安全文件传输)通过登录密码验证的形式连接你的服务器传输文件。也可以配置密钥连接省去每次输入密码。但是还是有个问题,服务器端我用pm2管理我的项目文件夹,只要每次把新的打包文件重新拷贝一份到服务器端的项目文件夹下,就可以完成项目更新,这导致服务器端的项目更新每次都得通过ssh去把文件传上去,这样才能完成服务器端的项目文件更新,感觉有点麻烦,如果能执行完npm run build后自动把我的文件传到服务端该多省事呀,基于这个想法,查了查文档写了个自动部署的插件@handsomezyw/auto-deploy-webpack-plugin完成这件事。

先安装插件

npm install --save-dev @handsomezyw/auto-deploy-webpack-plugin 

使用方法也很简单

// webpack.prod.js // 自动部署到服务端插件 const AutoDeployWebpackPlugin = require("@handsomezyw/auto-deploy-webpack-plugin");  module.exports = {     plugins: [         new AutoDeployWebpackPlugin({           // 服务器配置           serverOptions: {             // 服务器用户名             username: "administrator",             // 服务器ip地址             host: "xxx.xx.x.xxx",             // 服务器登录密码             password: "123456",           },           // 本地要上传到服务端的文件夹路径           localPath: "/Users/zengyongwen/Desktop/study/webpack-study/dist",           // 上传到服务器文件夹路径(这里需要注意的是,会把该文件夹先清理一遍,再上传)           serverPath: "Desktop/my-system/public",         }),     ] } 

最后我们在安装下react、react-dom的声明文件

npm install --save-dev @types/react @types/react-dom 

至此一个基础的react环境就搭建成功了。

总结

学习webpack的时候,我也是云里雾里,一开始就对着官方文档看,越看越头大,于是就去找一些关于webpack的文章和视频学习,发现好多都是webpack4的,于是我就对着官方文档的例子改改,找一些webpack5的实现方案等,多动手实践,慢慢的就对webpack的配置有了一点点了解,总的来说,搭建出一个自己的脚手架,还是有点成就感,哈哈。