【菜狗学前端】超超超详尽Webpack实践笔记

【菜狗学前端】超超超详尽Webpack实践笔记

码农世界 2024-05-22 前端 58 次浏览 0个评论

一 认识Webpack

  • 官网:https://webpack.js.org/
    • 中文网站:https://www.webpackjs.com/ 或者 https://webpack.docschina.org/guides/

      webpack 是一个用于现代 JavaScript 应用程序的 打包工具。

      当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,可以在浏览器上直接运行。在 webpack 看来, 前端的所有资源文件(js、json、css、img 、html...)都会作为模块处理。

      (一) webpack的五大核心概念

      1. 五大核心概念

      webpack的五大核心概念:

      • Entry: 指示 webpack 从哪个文件开始打包 。
        • Output: 指示 webpack 打包完的文件输出到哪里去,如何命名等 。
          • Mode:模式,有生产模式 production 和开发模式 development 两种。
            • Loader: webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析 。
              • Plugins: 扩展 webpack 的功能 ,如打包优化、压缩等。

      2. 生产模式VS开发模式

      生产模式VS开发模式

      • 生产模式 production(默认)
        • 生产模式是开发完成代码后,我们需要得到代码将来部署上线。这个模式下我们主要对代码进行优化,让其运行性能更好。优化主要从两个角度出发:
          • 优化代码运行性能
            • 优化代码打包速度
              • 开发模式 development
                • 开发模式顾名思义就是我们开发代码时使用的模式。这个模式下我们主要做两件事:
                  • 编译代码,使浏览器能识别运行,开发时我们有样式资源、字体图标、图片资源、html 资源等,webpack 默认都不能处理这些资源,所以我们要加载配置来编译这些资源。
                    • 代码质量检查,树立代码规范,提前检查代码的一些隐患,让代码运行时能更加健壮。提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。

      (二) 总结

      • webapck是一个构建工具,是基于node的,电脑上必须安装node,node版本需要大于16
        • 打包器,是从入口开始,按照模块依赖进行打包,最终得到浏览器的可以识别的静态资源。
          • 从某种程度来说,webpack代表的是一种架构能力。

            二 基础使用Webpack

            (一) 搭建环境

            1.创建一个文件夹

            2.初始化一个配置文件

            Plain Text

            npm init -y

            3.写入package.json所需要的依赖

            JavaScript

              "devDependencies": {

                "@babel/core": "^7.18.5",
                "@babel/preset-env": "^7.18.2",

                "@babel/preset-react": "^7.17.12",

                "autoprefixer": "^10.4.7",

                "axios": "^0.27.2",
                "babel-loader": "^8.2.5",

                "clean-webpack-plugin": "^3.0.0",

                "css-loader": "^6.7.1",

                "eslint": "^8.18.0",

                "eslint-config-airbnb-base": "^15.0.0",

                "eslint-plugin-import": "^2.26.0",

                "eslint-webpack-plugin": "^3.1.1",

                "file-loader": "^6.2.0",
                "html-webpack-plugin": "^5.5.0",

                "less": "^4.1.3",

                "less-loader": "^11.0.0",

                "mini-css-extract-plugin": "^2.6.1",

                "optimize-css-assets-webpack-plugin": "^6.0.1",

                "postcss": "^8.4.14",

                "postcss-loader": "^7.0.0",

                "postcss-preset-env": "^7.7.1",

                "sass": "^1.52.3",

                "sass-loader": "^13.0.0",

                "style-loader": "^3.3.1",

                "url-loader": "^4.1.1",

                "vue-loader": "^17.0.0",

                "vue-style-loader": "^4.1.3",

                "vue-template-compiler": "^2.6.14",

                "vue-template-loader": "^1.1.0",
                "webpack": "^5.73.0",

                "webpack-bundle-analyzer": "^4.5.0",
                "webpack-cli": "^4.10.0",
                "webpack-dev-server": "^4.9.2",

                "webpack-merge": "^5.8.0"

              },

              "dependencies": {

                "vue": "^3.2.37",

                "react": "^18.2.0",

                "react-dom": "^18.2.0"

              }

            4.安装依赖

            Plain Text

            npm i

            (二) 零配置打包

            现在,就涉及webpack,webpack-cli。

            • webpack 是核心内容提供了很多的API,插件。
              • webpack-cli 是在运行 webpack命令时,所依赖的一个工具。
                • 本地安装的话,使用 npx 可以执行安装在本地的命令行可执行命令。
                  • webpack版本是5.x版本

            Plain Text

            npx webpack

            1. 参数:指定模式打包、指定入口文件(直接写)、指定出口路径--output-path、指定出口文件名--output-filename
            1. 默认参数值:
            1. 入口文件:src/index.js
            1. 出口文件:dist/main.js
            1. 打包模式:production

            Plain Text

            # 将 src/index.js 打包至 dist/main.js  模式默认值:production

            npx webpack

            # 将 src/index.js 打包至 dist/main.js  模式指定为:development

            npx webpack --mode development

            # 将 src/one.js 打包至 dist/main.js

            npx webpack ./src/one.js --mode development

            # 将 src/one.js、two.js 打包至 dist/main.js

            npx webpack ./src/one.js ./src/two.js --mode development

            # 将 src/one.js 打包至 build/main.js

            npx webpack ./src/one.js --output-path build --mode development

            # 将 src/two.js 打包至 dist/index.js

            npx webpack ./src/two.js --output-filename index.js --mode development

            # 将 src/one.js 和 src/two.js 打包至 build/index.js

            npx webpack ./src/one.js ./src/two.js --output-path build --output-filename index.js --mode development

            (三) 基础配置打包

            1.在项目根目录创建webpack.config.js文件

            2.配置模式mode、入口entry、出口output

            模式mode、入口entry、出口output(路径path只能是绝对路径)

            JavaScript

            const path = require("path")

            module.exports = {

              mode: "development", // 开发打包

              // 入口

              // entry: "./src/main.js",

              // entry: path.resolve(__dirname, "src/main.js"),

              entry: {

                // app表示你打包后的资源名字就是app

                app: path.resolve(__dirname, "src/main.js"),  // 绝对路径

              },

              // 出口

              output: {

                path: path.resolve(__dirname, "dist"),  // 绝对路径

                // filename:"bundle.js"  // 一捆  一束

                filename: "js/[name].[chunkhash:8].js",  // 一捆  一束
                //每次打包时自动删除之前的打包文件
                clean: true
              }

            }

            3.配置开发服务器并使用其打包

            到目前为止 webpack 基本上可以正常使用了,但在实际开发中你可能会需要:

            • 提供 HTTP 服务而不是使用本地文件预览;
              • 监听文件的变化并自动刷新网页,做到实时预览;
                • 支持 Source Map,以方便调试。

                  前面打包是把包打包到硬盘上的。在开发时,需要配置一个开发服务器,这个开发服务器可以直接让我们在内存中打包,速度是远远高于硬盘的。我们之前用的脚手架,都是在内存中打开。

                  前面已安装该开发服务器,叫webpack-dev-server

                  webpack-dev-server能够修改后实时更新打包

                  但是一旦动了配置文件,便需要重新打包

                  在webpack.config.js中配置开发服务器

                  JavaScript

                      //配置开发服务器端口
                      devServer: {
                          port: 8080
                      }

                  之前打包是使用webpack进行打包的,直接是在硬盘上的打包,现在我们需要使用内存打包。

                  在终端控制台输入:

                  Bash
                  npx webpack serve

                  访问之,如下:(因为此时打包的文件里无index.html)

                  4.配置开发、生产模式脚本并执行

                  在package.json中配置脚本,如下 :

                  执行脚本,如下:

                  5.html-webpack-plugin将打包后的js插入html页面

                  JavaScript

                  const path = require("path")
                  const HtmlWebpackPlugin = require("html-webpack-plugin")

                  module.exports = {

                    mode: "development", // 开发打包

                    // 入口

                    // entry: "./src/main.js",

                    // entry: path.resolve(__dirname, "src/main.js"),  // 绝对路径

                    entry: {

                      // app表示你打包后的资源名字就是app

                      app: path.resolve(__dirname, "src/main.js"),  // 绝对路径

                    },

                    // 出口

                    output: {

                      path: path.resolve(__dirname, "dist"),  // 绝对路径

                      // filename:"bundle.js"  // 一捆  一束

                      filename: "js/[name].[chunkhash:8].js"  // 一捆  一束

                    },

                    // 配置开发服务器

                    devServer: {

                      port: 8080

                    },
                    plugins: [
                      new HtmlWebpackPlugin({

                        //相对路径 相对于启动nodejs服务器的目录在这里也就是react-webpack
                        template: "./public/index.html"
                      })
                    ]

                  }

                  回顾一下,目前用到的依赖:

                  JavaScript

                  //webpack核心插件

                  "webpack": "^5.73.0",

                  //webpack命令插件

                  "webpack-cli": "^4.10.0",

                  //开发服务器插件

                  "webpack-dev-server": "^4.9.2",

                  //将打包的js插入指定html页面插件

                  "html-webpack-plugin": "^5.5.0",

                  三 配置loader处理除JS|JSON外JS高级语法|JSX|CSS|图片等

                  (一) 前置知识

                  webpack眼中一切都是模块,默认情况下,只能理解js文件和json文件,这是webpack自带的能力,其它模块,webpack默认就不能处理了。

                  loader 能让 webpack 能够去处理其他类型的文件(比如css类型文件,图片类型等),并将它们转换为有效模块。

                  所以说要学习很多loader

                  • less-loader 把less翻译成css
                    • css-loader 把css代码转换为有效模块,让webpack处理
                      • sass-loader 把sass翻译成css
                        • babel-loader 可以转译 JavaScript 文件,加载后,让一些插件来翻译语法。如:箭头函数==>普通函数,let==>var。只有babel-loader还不行,还需要学习很多插件。ES6+它里面的语法非常多,意味着翻译语法的插件非常多。有一个概念,叫预设,预设是插件的集合。

                          谷歌浏览器可以识别,但是有的浏览器是不认识的。也就是说,webapck对于ES6+中的一些语法,它也不能直接转化成ES5,不能转化成ES5,浏览器对ES5的兼容性是最好。

                          我们需要使用loader,loader就是把webpack不能识别的模块,转化成webpack可以识别的模块。

                          如下:

                          JS模块中有高级语法,高级语法,如何转化成低级语法,让webpack识别呢?

                          答:最最最最最厉害的就是babel。

                          ES6中的语法,非常多,你要转化语法,需要安装对应插件

                          如你要把箭头函数转化成普通函数,那你就需要安装一个箭头函数转普通函数的插件,如你要把let转化成var,你需要安装一把let转成var的插件。也就说如果项目中用到了非常多的ES6语法,都需要转化,那就可以安装500个插件

                          babel给我们封装了很多预设,预设是插件集合,也就是集合中包含了很多的插件

                          如有一个预设,它可以把ES6中的大部分语法,转化成ES5,这个预设叫@babel/preset-env。

                          预设并不是转化所有语法,仅仅是大部分的,个别语法转化不了,需要单独安装插件。

                          • 后面需要学习一堆的loader,去转化不同的模块(使用loader来处理)。
                            • .js
                              • .vue vue-loader
                                • .jsx
                                  • .ts
                                    • .png
                                      • .less
                                        • .sass
                                          • .css
                                            • .json
                                              • .....
                                                • 也需要学习一堆的插件,插件是用来增强webpack。

                                                  (二) 打包JS模块中的高级语法

                                                  1.相关依赖

                                                  • babel-loader依赖:加载指定js
                                                    • @babel/preset-env依赖:翻译指定的js--将es6+转回为es5让所有浏览器可以识别

                                                      2.配置

                                                      1. 配置babel-loader加载

                                                      JavaScript

                                                          module: {
                                                              rules: [
                                                                  // 当webpack在工作时,遇到了以.js结束的模块,使用bable-loader进行加载
                                                                  // babel-loader是用来加载模块的,加载完成后,还需要使用@babel/xxx进行编译
                                                                  // 编译成ES5代码

                                                                  //查找以.js结束的字符串文件名?
                                                                  { test: /\.js$/, use: "babel-loader" }
                                                              ]
                                                          },

                                                      1. 配置@babel/preset-env预设

                                                      JavaScript

                                                      module.exports = {
                                                          // 预设(是插件的集合)
                                                          presets: [
                                                              ['@babel/preset-env']
                                                          ],

                                                          // 插件(某个特定的语法)

                                                          plugins: [

                                                          ]

                                                      }

                                                      4.执行

                                                      使let变var等...

                                                      5.说明

                                                      上面使用的预设不能打包装饰器,需要单独去安装对应的插件(打补丁),如下:

                                                      (三) 打包JSX模块(react)

                                                      1.相关依赖

                                                      JSON
                                                      "@babel/preset-react": "^7.17.12",

                                                      "react": "^18.2.0",

                                                      "react-dom": "^18.2.0"

                                                      2.配置

                                                      1. 配置babel-loader加载

                                                      JavaScript

                                                          module: {

                                                              rules: [

                                                      // 打包时,我们不希望webpack去打包node_module配置exclude: /node_modules/

                                                                  { test: /\.(js|jsx|ts|tsx)$/, use: "babel-loader", exclude: /node_modules/ },

                                                              ]

                                                          }

                                                      1. 配置@babel/preset-react预设

                                                      JavaScript

                                                      module.exports = {

                                                          // 预设(是插件的集合)

                                                          presets: [
                                                              ['@babel/preset-react']

                                                          ],

                                                          // 插件(某个特定的语法)

                                                          plugins: [

                                                          ]

                                                      }

                                                      (四) 打包VUE模块(vue)

                                                      1.相关依赖

                                                      JSON
                                                          "vue-loader": "^17.0.0",
                                                          "vue-style-loader": "^4.1.3",
                                                          "vue-template-compiler": "^2.6.14",
                                                          "vue-template-loader": "^0.4.1",

                                                          "vue": "^3.2.37"

                                                      2.配置

                                                      1. 配置vue-loader加载

                                                      JavaScript
                                                       { test: /\.vue$/, use: "vue-loader" }

                                                      1. 配置VueLoaderPlugin插件

                                                      JavaScript
                                                          const { VueLoaderPlugin } = require("vue-loader")

                                                          plugins: [
                                                              new VueLoaderPlugin()

                                                          ]

                                                      (五) 打包CSS、SASS(SCSS)、LESS模块(内部样式)

                                                      1.相关依赖

                                                      JSON
                                                          "css-loader": "^6.7.1",
                                                          "style-loader": "^3.3.1",

                                                          "sass-loader": "^13.0.0",
                                                          "less-loader": "^11.0.0",

                                                          "sass": "^1.52.3",

                                                          "less": "^4.1.3"

                                                      2.配置xxx-loader加载

                                                      JavaScript

                                                                  // webpack工作时,遇到css结尾文件,先用css-loader加载解析,返回css代码

                                                                  // 交给style-loader处理,后以js形式将css代码插入head标签中,也就是内部样式

                                                                  // 从后往前处理,先css-loader后style-loader use: ["style-loader", "css-loader"]
                                                                  { test: /\.css$/, use: ["style-loader", "css-loader"] },

                                                                  // 先sass-loader后css-loader后style-loader
                                                                  { test: /\.(sass|scss)$/, use: ["style-loader", "css-loader","sass-loader"] }

                                                                  { test: /\.less$/, use: ["style-loader", "css-loader","less-loader"] }

                                                      (六) 打包图片

                                                      1.前置知识

                                                      在webpack眼中,一切都是模块,图片当然也是模块。

                                                      在webpack4中,有两个laoder可以处理,在wabpack5中这两个laoder就淘汰了,这两个laoder如下:(url-loader比file-loader更强大)

                                                      • url-loader
                                                        • file-loader

                                                          在webpack5中上面的两个laoder就淘汰了,对于图片的处理,webpack内置好了

                                                          相当于是file-loader

                                                          2.相关依赖

                                                          JSON
                                                              "file-loader": "^6.2.0",
                                                              "url-loader": "^4.1.1"

                                                          3.配置

                                                          1. 方式一 url-loader

                                                          JavaScript

                                                                     //字符串,不过可设置limit:小于字符串,超过图片
                                                                     //{ test: /\.(png|jpg|svg|gif|jepg|webp)$/, use: "url-loader" }           

                                                                      {
                                                                          test: /\.(png|jpg|svg|gif|jpeg|webp)$/,
                                                                          use: [{
                                                                              loader: 'url-loader',

                                                                              options: {

                                                                                  // limit单位是字节    1个字节 = 8位

                                                                                  //                  1KB = 1024个字节

                                                                                  //                  1MB = 1024KB

                                                                                  limit: 1024 * 50, // 如果图片小于50kb,打包字符串,如果图片大于50kb,打包成图片

                                                                                  name: 'imgs/[name].[hash:8].[ext]'

                                                                              }

                                                                          }]

                                                                      },

                                                          1. 方式二 file-loader

                                                          JavaScript

                                                                      //直接图片
                                                                      { test: /\.(png|jpg|svg|gif|jepg|webp)$/, use: "file-loader" }

                                                          1. 方式三 webpack内置图片处理

                                                          JavaScript

                                                            // type: "asset/resource" 相当于使用了file-loader

                                                                      {

                                                                          test: /\.(png|jpg|svg|gif|jpeg|webp)$/, type: "asset/resource", generator: {

                                                                              filename: 'imgs/[name].[hash:8].[ext]'

                                                                          }

                                                                      },

                                                          四 进阶使用Webpack

                                                          (一) 将配置拆分为公共、开发、生产配置

                                                          打包分两种,一种是开发时的打包,一种是生产时的打包。

                                                          不同的打包方式有不同的配置的,两种打包方式,也就是有两种配置,但是这两种配置中有一些公共的配置。

                                                          把这些配置区分出来,创建如下的文件,如下:

                                                          1.公共的配置

                                                          2.开发配置

                                                          3.生产配置

                                                          4.导入至webpack.config.js并用webpack-merge合并

                                                          JavaScript
                                                          const { merge } = require('webpack-merge')

                                                          //导入三个配置
                                                          const config = require("./config/config")
                                                          const dev = require("./config/dev")
                                                          const pro = require("./config/pro")

                                                          //合并三个配置-简化版

                                                          // 当运行npm run dev 期望dev.js和config.js生效

                                                          // 当运行npm run pro 期望pro.js和config.js生效

                                                          //{ development }是执行脚本传入的env的属性
                                                          module.exports = function ({ development }) {
                                                              return merge(config, development ? dev : pro)
                                                          }

                                                          // 合并三个配置-普通版

                                                          // module.exports = function (dev) {
                                                          // 在webpack.config.js中就可以得到执行脚本传入的env  
                                                          // console.log(env);//{ WEBPACK_SERVE: true, development: true }

                                                          // 这里是对象解构赋值,取哪个属性值写哪个属性名即可

                                                          //     let { development } = env

                                                          //     if (development) {

                                                          //         return merge(config, dev)

                                                          //     } else {

                                                          //         return merge(config, pro)

                                                          //     }

                                                          // }

                                                          5.在package.json中配置脚本并执行

                                                          JSON

                                                            "scripts": {

                                                            ...

                                                              "dev": "webpack serve --env development --config webpack.config.js",

                                                              "pro": "webpack --env production --config webpack.config.js"

                                                              }

                                                          Bash

                                                          //生产模式

                                                          npm run pro

                                                          //开发模式

                                                          npm run dev

                                                          (二) html-webpack-plugin将js引入指定html

                                                          1.配置

                                                          JavaScript

                                                                  // 将js引入指定html插件

                                                                  new HtmlWebpackPlugin({

                                                                      template: './public/index.html',//相对路径 相对于启动nodejs服务器的目录在这里也就是react-webpack

                                                                      // template: path.resolve(__dirname, "../", 'public/index.html')//绝对路径

                                                                      inject:"body",//把js脚本注入到body结束标签之前

                                                                      filename: "index1.html",// 指定打包成功后页面的名字

                                                                      title: "htmlwebpackplugin",//用来指定页面的title标题

                                                                      favicon: path.resolve(__dirname, "../", "favicon.ico")//配置icon

                                                                  }),

                                                          2.注意

                                                          • title: "htmlwebpackplugin"

                                                            还需要在页面中title标签位置写如下代码

                                                            HTML
                                                            <%= htmlWebpackPlugin.options.title %>

                                                            • inject:"body"

                                                              不设inject的话,默认把打包后js插入到了head结束标签之前

                                                              2.执行

                                                              (三) postcss-loader处理css兼容

                                                              postcss是JavaScript转换样式的工具,这个工具能处理css兼容问题。

                                                              就是这个工具能给我们写的css代码添加一些兼容的前缀

                                                              1.相关依赖

                                                              JSON
                                                              "autoprefixer": "^10.4.7",
                                                              "postcss": "^8.4.14",
                                                              "postcss-loader": "^7.0.0",
                                                              "postcss-preset-env": "^7.7.1"

                                                              2.配置

                                                              1. 在项目根目录下创建 postcss.config.js 文件

                                                              JavaScript

                                                              module.exports = {

                                                                  plugins: {

                                                                      "autoprefixer": {

                                                                          "overrideBrowserslist": [

                                                                              // 兼容IE7以上浏览器

                                                                              "ie >= 8",

                                                                              // 兼容火狐版本号大于3.5浏览器

                                                                              "Firefox >= 3.5",

                                                                              // 兼容谷歌版本号大于35浏览器,

                                                                              "chrome >= 35"

                                                                          ]

                                                                      }

                                                                  }

                                                              }

                                                              1. 修改webpack配置

                                                              JavaScript

                                                                          { test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"] },

                                                                          { test: /\.(sass|scss)$/, use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"] },

                                                              3.执行

                                                              (四) 配置代理解决跨域(前端处理)

                                                              在做网络请求的时候,前端最常见的问题就是跨域,分别可以在前端和后端处理

                                                              • 前端处理
                                                                • JSONP(需要服务器端支持)
                                                                  • proxy代理(开发模式)
                                                                    • 后端处理
                                                                      • cors

                                                              1.出现跨域问题

                                                              1. 后端
                                                              • 创建服务器:

                                                                JavaScript

                                                                const express = require("express")

                                                                const path = require("path")// 创建 express 实例const app = express();

                                                                app.get("/malu",(req,res)=>{

                                                                    res.send({code:1,data:"你好,我是服务器~"})})

                                                                app.listen(3000,()=>{

                                                                    console.log('服务器启动了,端口是3000');})

                                                                • 依赖:

                                                                  • 测试服务器:

                                                                    1. 前端
                                                                    • 写axios代码,向服务器发请求
                                                                      • 产生了跨域问题

                                                                        2.webpack配置代理解决跨域

                                                                        JavaScript

                                                                            devServer: {

                                                                                port: 8080,

                                                                                client: {

                                                                                    // 只弹出报错

                                                                                    overlay: {

                                                                                        errors: true,

                                                                                        warnings: false

                                                                                    }

                                                                                },

                                                                                // 代理
                                                                                proxy: {
                                                                                    '/api': {//定义一个标记,如以后api开头的请求都走代理的设置
                                                                                        target: 'http://localhost:3000/',// 目标域名
                                                                                        // 发送请求头中host会设置成target
                                                                                        changeOrigin: true,// 改变源到目标域名,允许设置请求头
                                                                                        pathRewrite: { '^/api': '' }// 重写路径,去除/api部分
                                                                                        }
                                                                                    }

                                                                                }

                                                                        (五) ProvidePlugin把某些包放到全局(webpack内置)

                                                                        1.分析需要原因

                                                                        如何把某些包放到全局中,此时需要使用ProvidePlugin

                                                                        2.配置

                                                                        JavaScript

                                                                        const { ProvidePlugin } = require("webpack")

                                                                            plugins: [

                                                                                // 配置ProvidePlugin将某些包如React放到全局中
                                                                                new ProvidePlugin({
                                                                                    React: path.resolve(__dirname, "../", "node_modules/react/index.js")
                                                                                })

                                                                            ]

                                                                        (六) source-map在Debug时显示原始代码位置信息(而非压缩后)

                                                                        1.分析需要原因

                                                                        我们可以通过 devtool 来设置增强调试过程,通过设置 devtool 生成source map。

                                                                        • source map 是一个信息文件,里面存储着代码压缩前后的位置信息。
                                                                          • 即可以在Debug时直接显示原始代码的位置信息,而不是压缩后的,极大方便后期调试

                                                                            开发环境下默认生成的Source Map ,记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。

                                                                            看一下控制台,如下:

                                                                            解决方案:在webpack.dev.config.js中添加如下配置,即可保证运行时报错的行数与源代码的行数保持一致。

                                                                            2.配置

                                                                            Source Map 的最佳实践

                                                                            • 开发模式下,建议直接把devtool 的值设置为 source-map ,可以直接定位到具体的错误行
                                                                              • 生产环境下,建议关闭Source Map 或者 将devtool 设置为 hidden-nosources-source-map ,防止源码泄漏,提高网站的安全性

                                                                            JavaScript

                                                                                // 使报错行对应的是源代码而非打包后代码

                                                                                devtool: "source-map"

                                                                            此时报错的位置和控制台中就保持一样的了,如下:

                                                                            在生产中,可以不去配置source-map,上线的也是打包后的代码

                                                                            可以不配置,也可以配置 :

                                                                            或者不配置:

                                                                            JavaScript

                                                                            module.exports = {mode:"development",// devtool:"hidden-nosources-source-map"}

                                                                            (七) 把第三方包抽离出来

                                                                            1.分析需要原因

                                                                            现在尝试去打包,如下:

                                                                            分析之,如下:

                                                                            可以看一下,之前打包vue,生成的js文件,如下:

                                                                            2.配置

                                                                            JavaScript
                                                                                entry: {

                                                                                    // 把react和react-dom分离出去,形成一个chunk

                                                                                    // 方便后面cdn优化
                                                                                    chunk: ['react', 'react-dom/client'],

                                                                                    //app可随便修改,为main.js打包后的文件名

                                                                                    app: {

                                                                                        import: path.resolve(__dirname, "../", "src/main.js"),
                                                                                        // 写的业务代码是依赖第三方包的
                                                                                        dependOn: "chunk"

                                                                                    }

                                                                                },

                                                                            3.执行

                                                                            (七点五) 抽离css(外部样式)

                                                                            在生产打包时,需要把css抽离出来

                                                                            此时我们需要用到一个插件,这个插件中带了一个loader

                                                                            1.依赖

                                                                            JSON
                                                                                "mini-css-extract-plugin": "^2.6.1",

                                                                            2.配置

                                                                            JavaScript

                                                                            const MiniCssExtractPlugin = require("mini-css-extract-plugin")

                                                                                plugins: [
                                                                                    // 分离css出来单独打包
                                                                                    new MiniCssExtractPlugin({
                                                                                        filename: 'css/[name].[contenthash:8].css'
                                                                                    })

                                                                                ]

                                                                            3.执行

                                                                            (八) 压缩CSS

                                                                            1.分析需要原因

                                                                            打包CSS,书写CSS代码如下:

                                                                            在main.js中引入css,如下:

                                                                            打包:

                                                                            2.依赖

                                                                            JSON
                                                                            "optimize-css-assets-webpack-plugin": "^6.0.1"

                                                                            3.配置

                                                                            JavaScript

                                                                            // 压缩打包后的css

                                                                            const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
                                                                                plugins: [

                                                                                    // 分离css出来单独打包

                                                                                    new MiniCssExtractPlugin({

                                                                                        filename: 'css/[name].[contenthash:8].css'

                                                                                    }),
                                                                                    // 压缩打包后的css--即变成一行
                                                                                    new OptimizeCssAssetsWebpackPlugin()

                                                                                ]

                                                                            (九) ESLint

                                                                            1.前提知识

                                                                            为了统一规范团队代码习惯,降低代码出错风险,eslint已经成为前端项目必备法器。简单来说,写代码必须遵循一定的规范,至于是什么规范,我们可以自己定义。

                                                                            eslint是用来进行代码检测。也非常重要,在很多公司,都是要求使用eslint的,如果代码写的不符合要求,有可能代码就提交到不到仓库。在很早之前,有一个laoder,叫eslint-loader来校验代码,现在这个laoder已经淘汰了。现在使用的是一个插件,如下:

                                                                            2.依赖

                                                                            JavaScript
                                                                                "eslint": "^8.18.0",
                                                                                "eslint-webpack-plugin": "^3.1.1"

                                                                            • eslint里面包含了很多的校验规则
                                                                              • eslint-webpack-plugin使用eslint来查找和修复js代码中的问题
                                                                                • eslint-webpack-plugin这个插件不能进行校验,这个插件是把eslint集成到webpack中的。
                                                                                  • 代码校验是在开发时进行校验的,配置就需要配置到开发环境中

                                                                                    3.配置

                                                                                    JavaScript
                                                                                    const ESLintPlugin = require("eslint-webpack-plugin")

                                                                                    module.exports = {

                                                                                        mode:"development",

                                                                                        devServer:{

                                                                                            port:8080

                                                                                        },

                                                                                        plugins:[
                                                                                            new ESLintPlugin({
                                                                                                eslintPath:'eslint',
                                                                                                extensions:['js','jsx','ts','tsx','vue'],
                                                                                                exclude:['node_modules']
                                                                                            })

                                                                                        ]

                                                                                    }

                                                                                    此时打包后报错

                                                                                    上面的插件仅仅是把eslint集成到webpack中,对于eslint的配置文件,还需要单独配置

                                                                                    创建eslint的配置文件,有多种方式

                                                                                    创建一个eslint的配置文件, 如下

                                                                                    JavaScript
                                                                                    module.exports = {
                                                                                        env: {
                                                                                            node: true,
                                                                                            browser: true,
                                                                                            es6: true,
                                                                                        },
                                                                                        // 支持ES6并不代表支持所有ES6新语法, 设置为"module" 支持 ECMAScript 模块
                                                                                        // 解析配置
                                                                                        parserOptions: {
                                                                                            sourceType: 'module',
                                                                                            ecmaFeatures: {
                                                                                                'jsx': true
                                                                                            }
                                                                                        },
                                                                                        // 个人难以制定大而全的规范
                                                                                        // 可以借用大公司已成熟方案,再根据项目情况稍加修改
                                                                                        // 这里我们引用Airbnb
                                                                                        extends: "airbnb-base",

                                                                                        // 配置自定义的规则
                                                                                        rules: {
                                                                                            // JS文件中不支持console.log()
                                                                                            // 'no-console': 'warn',
                                                                                            // "semi": "error",
                                                                                        },
                                                                                    };

                                                                                    • eslint中还有哪些规则呢?

                                                                                      如下:https://www.cnblogs.com/zhenfeng25/p/15567427.html

                                                                                      Plain Text

                                                                                      "no-alert": 0,//禁止使用alert confirm prompt

                                                                                      "no-array-constructor": 2,//禁止使用数组构造器

                                                                                      "no-bitwise": 0,//禁止使用按位运算符

                                                                                      "no-caller": 1,//禁止使用arguments.caller或arguments.callee

                                                                                      ......

                                                                                      • 如果不想让eslint检测我们的src下面所有的代码

                                                                                             可以创建一个.eslintignore的配置文件,如下:

                                                                                        4.执行

                                                                                        (十) 使用vue脚手架中的eslint

                                                                                        创建vue脚手架创建项目,如下:

                                                                                        弹出vue脚手架中webpack的配置,如下:

                                                                                        五 "鸡肋"系列

                                                                                        (一) 配置路径别名

                                                                                        1.配置

                                                                                        JavaScript
                                                                                            // 配置路径相关
                                                                                            resolve: {
                                                                                                // 别名
                                                                                                alias: {
                                                                                                    "@": path.resolve(__dirname, "../", "src")
                                                                                                },
                                                                                                // 扩展、延长
                                                                                                extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue']
                                                                                            }

                                                                                        2.使用

                                                                                        (二) browserslistrc表示当前项目的浏览器兼容情况

                                                                                        browserslistrc文件是为了表示当前项目的浏览器兼容情况,使用方式有三种:

                                                                                        • 在package.json中设置
                                                                                          • 设置成独立的配置文件
                                                                                            • 某些插件需要重新设置browserslist

                                                                                              我们参考Vue项目的环境配置,选择第二种方式,设置成独立的配置文件

                                                                                              Plain Text

                                                                                              1%   // 兼容市场上占有率超过1%的浏览器(世界级)

                                                                                              last 2 versions  // 兼容浏览器最近的两个版本

                                                                                              not dead // 不支持24个月内没有官方支持或者更新的浏览器

                                                                                              not ie 11  // 不支持ie 11

                                                                                              (三) 配置ProgressPlugin插件(webpack内置)

                                                                                              1.配置

                                                                                              JavaScript
                                                                                              const { ProgressPlugin } = require("webpack")

                                                                                              2.执行

转载请注明来自码农世界,本文标题:《【菜狗学前端】超超超详尽Webpack实践笔记》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,58人围观)参与讨论

还没有评论,来说两句吧...

Top