• Re:用webpack从零开始的vue-cli搭建‘生活‘


    有了vue-cli的帮助,我们创建vue的项目非常的方便,使用vue create然后选择些需要的配置项就能自动帮我们创建配置好的webpack项目脚手架了,实在是‘居家旅行’必备良药。这次借着学习webpack的机会,不用vue-cli搭建一个vue项目。

    注:基于webpack5,其运行于 Node.js v10.13.0+ 的版本。

    完整代码:https://github.com/mashiro-cat/learn_webpack

    webpack基础

    webpack官网:https://webpack.js.org/
    webpack中文官网:https://webpack.docschina.org/
    安装:

    npm i webpack webpack-cli -D
    
    • 1

    运行:

    npx webpack ./src/main.js --mode=development
    # 根目录有配置文件
    npx webpack
    
    • 1
    • 2
    • 3

    打开文档就能看到五个核心配置点:

    1. 入口(entry)
    2. 输出(output)
    3. loader
    4. 插件(plugin)
    5. 模式(mode)

    webpack本身只提供了对js中ES Module和压缩的支持,很多功能都要通过使用loader或者plugin拓展。

    webpack.config.js配置文件编写:

    module.exports = {
      // 入口 多入口则配置成对象形式
      entry:"",
      // 输出 需使用绝对路径
      output:{},
      // loader
      module:{
        rules:[]
      },
      // 插件
      plugins:[],
      // development 或者 production
      // 生产模式默认开启js和html压缩
      mode:"development"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    样式资源处理

    配置资源输出的路径和名称

    输出:

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'static/js/main.js' // 将js输出到 static/js 目录中
      }
    
    • 1
    • 2
    • 3
    • 4

    module中:

    generator: {
              // 将图片文件输出到 static/imgs 目录中
              // 将图片文件命名 [hash:8][ext][query]
              // [hash:8]: hash值取8位 直接[hash]则不截取
              // [ext]: 使用之前的文件扩展名
              // [name]: 会使用之前的名字
              // [query]: 添加之前的query参数
              filename: "static/imgs/[hash:8][ext][query]",
            },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    css处理

    安装两个loader,其使用顺序是css-loader会处理css,而将编译的css经style-loader后会动态创建style标签。
    css-loader

    # 安装
    npm i css-loader style-loader -D
    
    • 1
    • 2
    rules: [
          // 两个loader顺序按此 它会先使用后面的
          { test: /\.css$/i, use: ["style-loader", "css-loader"] }
        ]
    
    • 1
    • 2
    • 3
    • 4
    提取css到单独文件

    现在是css全部是打包到js中,然后动态插入的。若需要提取到单独文件,则可以借助插件。

    // 安装插件
    npm i mini-css-extract-plugin -D
    
    // 配置插件
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    // 将styel-loader改为MiniCssExtractPlugin.loader
    {
      // 用来匹配 .css 结尾的文件
      test: /\.css$/,
      // use 数组里面 Loader 执行顺序是从右到左
      use: [MiniCssExtractPlugin.loader, "css-loader"],
    },
    
    plugins:[
    new MiniCssExtractPlugin({
          // 定义输出文件名和目录
          filename: "static/css/main.css",
        }),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    css兼容处理
    // 安装
    npm i postcss-loader postcss postcss-preset-env -D
    
    // 配置
    
    {
            // 用来匹配 .css 结尾的文件
            test: /\.css$/,
            // use 数组里面 Loader 执行顺序是从右到左
            use: [
              MiniCssExtractPlugin.loader,
              "css-loader",
              { // 在css-loader之后,预处理器loader之前
                loader: "postcss-loader",
                options: {
                  postcssOptions: {
                    plugins: [
                      "postcss-preset-env", // 能解决大多数样式兼容性问题
                    ],
                  },
                },
              },
            ],
          },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    控制兼容性:
    package.json 文件中添加 browserslist 来控制样式的兼容性的程度:

    {
      // 其他省略
      //"browserslist": ["ie >= 8"]
      // 实际开发中我们一般不考虑旧版本浏览器了,所以我们可以这样设置:
      // 所有浏览器的最新两个版本 支持市面上99%浏览器 还没死的浏览器
      "browserslist": ["last 2 version", "> 1%", "not dead"]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    css压缩

    安装插件:

    npm i css-minimizer-webpack-plugin -D
    
    • 1

    webpack配置:

    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    
    plugins:[
      // css压缩
      new CssMinimizerPlugin(),
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    预处理器

    使用less,scss等预处理都要安装对应的loader进行编译,webpack才能识别处理。

    less的使用:

    // 安装less-loader
    npm i less-loader -D
    
    // 配置
    // less-loader将less转为css后还是要交给css-loader处理的
    {
      test: /\.less$/,
      use: ["style-loader", "css-loader", "less-loader"]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    scss, sass的使用:

    // 安装
    npm i sass-loader sass -D
    
    // 配置
    {
      test: /\.s[ac]ss$/,
      use: ["style-loader", "css-loader", "sass-loader"],
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    点击查看完整配置
    
    const path = require('path')
    
    module.exports = {
      // 入口 多入口则配置成对象形式
      entry: "./src/main.js",
      // 输出 需使用绝对路径
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
      },
      // loader
      module: {
        rules: [
          // 两个loader顺序按此 它会先使用后面的
          { test: /\.css$/i, use: ["style-loader", "css-loader"] },
          // less-loader将less转为css后还是要交给css-loader处理的
          { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] },
          {
            test: /\.s[ac]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
        ]
      },
      // 插件
      plugins: [],
      // development 或者 production
      mode: "development"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    图片资源处理

    Webpack4使用file-loader 和 url-loader处理图片资源,而webpack5将那俩都内置了,直接配置开启就可。

    {
      test: /\.(png|jpe?g|gif|webp)$/,
      type: "asset",
    },
    
    • 1
    • 2
    • 3
    • 4

    将小于某个大小的图片转化成Base64可添加此配置:

    {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
              }
            }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    点击查看完整配置
    
    const path = require('path')
    
    module.exports = {
      // 入口 多入口则配置成对象形式
      entry: "./src/main.js",
      // 输出 需使用绝对路径
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
      },
      // loader
      module: {
        rules: [
          // 两个loader顺序按此 它会先使用后面的
          { test: /\.css$/i, use: ["style-loader", "css-loader"] },
          // less-loader将less转为css后还是要交给css-loader处理的
          { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] },
          {
            test: /\.s[ac]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
          {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
              }
            }
          },
        ]
      },
      // 插件
      plugins: [],
      // development 或者 production
      mode: "development"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    其它资源处理

    若项目中引用了字体,视频等资源,则是希望不要处理它,直接输出就好了。配置为type: "asset/resource"它就会原封不动的输出了。

    {
            // 处理字体图标或者视频等其它资源
            test: /\.(ttf|woff2?|map4|map3)$/,
            type: "asset/resource",
            generator: {
              filename: "static/media/[hash:8][ext][query]",
            },
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    点击查看完整配置
    
    const path = require('path')
    
    module.exports = {
      // 入口 多入口则配置成对象形式
      entry: "./src/main.js",
      // 输出 需使用绝对路径
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'static/js/main.js', // 将js输出到 static/js 目录中
        clean: true
      },
      // loader
      module: {
        rules: [
          // 两个loader顺序按此 它会先使用后面的
          { test: /\.css$/i, use: ["style-loader", "css-loader"] },
          // less-loader将less转为css后还是要交给css-loader处理的
          { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] },
          {
            test: /\.s[ac]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
          {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
              }
            },
            generator: {
              // 将图片文件输出到 static/imgs 目录中
              // 将图片文件命名 [hash:8][ext][query]
              // [hash:6]: hash值取6位
              // [ext]: 使用之前的文件扩展名
              // [query]: 添加之前的query参数
              filename: "static/imgs/[hash:6][ext][query]",
            },
          },
          {
            // 处理字体图标或者视频等其它资源
            test: /\.(ttf|woff2?|map4|map3)$/,
            type: "asset/resource",
            generator: {
              filename: "static/media/[hash:8][ext][query]",
            },
          },
        ]
      },
      // 插件
      plugins: [],
      // development 或者 production
      mode: "development"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    js资源处理

    代码质量检测 Eslint

    安装:

    npm i eslint-webpack-plugin eslint -D
    
    • 1

    在webpack配置中使用eslint插件

    const ESLintWebpackPlugin = require("eslint-webpack-plugin");
    
    plugins: [
        new ESLintWebpackPlugin({
          // 指定检查文件的根目录
          context: path.resolve(__dirname, "src"),
        }),
      ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    编写配置:
    配置文件由很多种写法:.eslintrc.*:新建文件,位于项目根目录

    • .eslintrc
    • .eslintrc.js
    • .eslintrc.json

    区别在于配置格式不一样package.json 中 eslintConfig:不需要创建文件,在原有文件基础上写,ESLint 会查找和自动读取它们,所以以上配置文件只需要存在一个即可

    根目录创建.eslintrc.js配置文件

    // .eslintrc.js
    module.exports = {
      // 解析配置项
      parserOptions: {
        ecmaVersion: 6, // ES 语法版本
        sourceType: "module", // ES 模块化
      },
      env: {
        node: true, // 启用node中全局变量
        browser: true, // 启用浏览器中全局变量 不开启则像 console Math 等全局变量无法使用
      },
      // 继承规则
      extends: ['eslint:recommended'],
      // 检测规则
      // 自定义的规则会覆盖继承的规则
      // "off" 或 0 - 关闭规则
      // "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
      // "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
      rules: {
        semi: "off", // 禁止使用分号
        'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告
        'default-case': [
          'warn', // 要求 switch 语句中有 default 分支,否则警告
          { commentPattern: '^no default$' } // 允许在最后注释 no default, 就不会有警告了
        ],
        eqeqeq: [
          'warn', // 强制使用 === 和 !==,否则警告
          'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
        ],
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    babel兼容处理

    安装:

    npm i babel-loader @babel/core @babel/preset-env -D
    
    • 1

    babel配置编写:
    配置文件由很多种写法:

    1. babel.config.*:新建文件,位于项目根目录
    • babel.config.js
    • babel.config.json
    1. .babelrc.*:新建文件,位于项目根目录
    • .babelrc
    • .babelrc.js
    • .babelrc.json

    package.json 中 babel:不需要创建文件,在原有文件基础上写

    presets 预设:
    简单理解:就是一组 Babel 插件, 扩展 Babel 功能
    @babel/preset-env: 一个智能预设,允许您使用最新的 JavaScript。
    @babel/preset-react:一个用来编译 React jsx 语法的预设
    @babel/preset-typescript:一个用来编译 TypeScript 语法的预设

    // 创建.babelrc.js
    module.exports = {
      presets: ["@babel/preset-env"],
    };
    
    • 1
    • 2
    • 3
    • 4

    webpack增加babel

    {
      test: /\.js$/,
      exclude: /node_modules/, // 排除node_modules代码不编译
      loader: "babel-loader",
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    html自动导入处理

    安装html-webpack-plugin

    npm i html-webpack-plugin -D
    
    • 1

    webpack配置, 配置好后就会自动的引入所需的js了。

    const HtmlWebpackPlugin = require("html-webpack-plugin");
    
    plugins: [
        new HtmlWebpackPlugin({
          // 以 public/index.html 为模板创建文件
          // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
          template: path.resolve(__dirname, "public/index.html"),
        }),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    webpackSever

    使用webpacksever后,在开发时就能自动检测文件变化,并实时编译展示出来了。

    // 安装
    npm i webpack-dev-server -D
    
    // 配置
    devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行:

    // 此时不会打包生成文件,都是在内存中进行编译的
    npx webpack serve
    
    • 1
    • 2
    点击查看完整配置
    
    const path = require('path')
    const ESLintWebpackPlugin = require("eslint-webpack-plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    
    module.exports = {
      // 入口 多入口则配置成对象形式
      entry: "./src/main.js",
      // 输出 需使用绝对路径
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'static/js/main.js', // 将js输出到 static/js 目录中
        clean: true
      },
      // loader
      module: {
        rules: [
          // 两个loader顺序按此 它会先使用后面的
          { test: /\.css$/i, use: ["style-loader", "css-loader"] },
          // less-loader将less转为css后还是要交给css-loader处理的
          { test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"] },
          {
            test: /\.s[ac]ss$/,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
          {
            test: /\.(png|jpe?g|gif|webp)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
              }
            },
            generator: {
              // 将图片文件输出到 static/imgs 目录中
              // 将图片文件命名 [hash:8][ext][query]
              // [hash:6]: hash值取6位
              // [ext]: 使用之前的文件扩展名
              // [query]: 添加之前的query参数
              filename: "static/imgs/[hash:6][ext][query]",
            },
          },
          {
            // 处理字体图标或者视频等其它资源
            test: /\.(ttf|woff2?|map4|map3)$/,
            type: "asset/resource",
            generator: {
              filename: "static/media/[hash:8][ext][query]",
            },
          },
          { // babel配置
            test: /\.js$/,
            exclude: /node_modules/, // 排除node_modules代码不编译
            loader: "babel-loader",
          },
        ]
      },
      // 插件
      plugins: [
        new ESLintWebpackPlugin({
          // 指定检查文件的根目录
          context: path.resolve(__dirname, "src"),
        }),
        new HtmlWebpackPlugin({ // html处理的插件
          // 以 public/index.html 为模板创建文件
          // 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
          template: path.resolve(__dirname, "public/index.html")
        })
      ],
      devServer: {
        host: "localhost", // 启动服务器域名
        port: "666", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
      },
      // development 或者 production
      mode: "development"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    webpack进阶

    使用sourcemap

    SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。
    通过查看Webpack DevTool文档可知,SourceMap 的值有很多种情况.
    开发时我们只需要关注两种情况即可:
    开发模式:cheap-module-source-map,优点:打包编译速度快,只包含行映射,缺点:没有列映射
    生产模式:source-map,优点:包含行/列映射,缺点:打包编译速度更慢。

    配置:

    devtool: "cheap-module-source-map",
    
    • 1

    提升打包速度

    HotModuleReplacement:它(HMR/热模块替换):在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。

    module.exports = {
      // 其他省略
      devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
        hot: true, // 开启HMR功能(只能用于开发环境,生产环境不需要了)
      },
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    此时 css 样式经过 style-loader 处理,已经具备 HMR 功能了。 但是 js 可以使用vue-loader, react-hot-loader实现。

    OneOf配置(开发和正式都能用):
    匹配到一条规则就不继续匹配了

    module: {
        rules: [
            {
                oneOf: [
                    { test: /\.css$/, use: ["style-loader", "css-loader"] },
                    .........
                ]
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Include/Exclude
    如在配置babel排除node_moudels文件夹

    使用缓存Cache
    每次打包时 js 文件都要经过 Eslint 检查 和 Babel 编译,速度比较慢。我们可以缓存之前的 Eslint 检查 和 Babel 编译结果,这样第二次打包时速度就会更快了

    // babel
    {
                test: /\.js$/,
                // exclude: /node_modules/, // 排除node_modules代码不编译
                include: path.resolve(__dirname, "../src"), // 也可以用包含
                loader: "babel-loader",
                options: {
                  cacheDirectory: true, // 开启babel编译缓存
                  cacheCompression: false, // 缓存文件不要压缩
                },
              },
    
    
    // Eslint
    new ESLintWebpackPlugin({
          // 指定检查文件的根目录
          context: path.resolve(__dirname, "../src"),
          exclude: "node_modules", // 默认值
          cache: true, // 开启缓存
          // 缓存目录
          cacheLocation: path.resolve(
            __dirname,
            "../node_modules/.cache/.eslintcache"
          ),
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    打包启用多线程:
    开启线程也需要时间,小项目可能提升不明显。
    npm i thread-loader -D安装loader,然后配置:

    // nodejs核心模块,直接使用
    const os = require("os");
    const TerserPlugin = require("terser-webpack-plugin"); // webpack自带的js压缩模块
    
    // cpu核数
    const threads = os.cpus().length;
    
    // babel使用多线程
    {
                test: /\.js$/,
                // exclude: /node_modules/, // 排除node_modules代码不编译
                include: path.resolve(__dirname, "../src"), // 也可以用包含
                use: [
                  {
                    loader: "thread-loader", // 开启多进程
                    options: {
                      workers: threads, // 数量
                    },
                  },
                  {
                    loader: "babel-loader",
                    options: {
                      cacheDirectory: true, // 开启babel编译缓存
                    },
                  },
                ],
              },
    
    // Eslint使用多线程
    new ESLintWebpackPlugin({
          // 指定检查文件的根目录
          context: path.resolve(__dirname, "../src"),
          exclude: "node_modules", // 默认值
          cache: true, // 开启缓存
          // 缓存目录
          cacheLocation: path.resolve(
            __dirname,
            "../node_modules/.cache/.eslintcache"
          ),
          threads, // 开启多进程
        }),
    
    // js压缩使用多线程
    optimization: {
        minimize: true,
        minimizer: [
          // css压缩也可以写到optimization.minimizer里面,效果一样的
          new CssMinimizerPlugin(),
          // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
          new TerserPlugin({
            parallel: threads // 开启多进程
          })
        ],
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    减少的代码体检

    Tree Shaking: 默认开启,通常用于描述移除 JavaScript 中的没有使用上的代码。

    Babel优化:
    @babel/plugin-transform-runtime: 禁用了 Babel 自动对每个文件的 runtime 注入,而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。

    // 安装
    npm i @babel/plugin-transform-runtime -D
    
    // 配置
    {
                    loader: "babel-loader",
                    options: {
                      cacheDirectory: true, // 开启babel编译缓存
                      cacheCompression: false, // 缓存文件不要压缩
                      plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
                    },
                  },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    优化代码运行性能

    打包代码分块
    Preload / prefetch
    使用Core-js
    使用PWA

    从零开始搭建vue-webpack项目

    使用的库:
    设置环境变量:
    https://www.npmjs.com/package/cross-env

    // 安装
    npm install --save-dev cross-env
    
    // package.json
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    vue-loder文档: https://vue-loader.vuejs.org/zh/
    安装vue-loader

    npm i vue
    npm install -D vue-loader vue-template-compiler
    
    module: {
        rules: [
          // ... 其它规则
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          }
        ]
      },
      plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin()
      ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    样式处理

    style-loader 替换为 vue-style-loader,并安装预处理器loader

    npm i -D css-loader vue-style-loader less-loader less-loader sass-loader stylus-loader
    
    • 1

    设置拓展名自动布局

    resolve: {
        extensions: [".vue", ".js", ".json"], // 自动补全文件扩展名,让vue可以使用
      },
    
    • 1
    • 2
    • 3

    Eslint配置指定为vue的

    npm i -D @babel/eslint-parser
    
    // .eslintrc.js
    module.exports = {
      root: true,
      env: {
        node: true,
      },
      extends: ["plugin:vue/vue3-essential", "eslint:recommended"],
      parserOptions: {
        parser: "@babel/eslint-parser",
      },
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Bable配置

    npm i -D @vue/cli-plugin-babel
    
    // babel.config.js
    module.exports = {
      presets: ["@vue/cli-plugin-babel/preset"],
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    提供对js的变量,解决页面警告

    // 解决页面警告
    new DefinePlugin({
      __VUE_OPTIONS_API__: "true",
      __VUE_PROD_DEVTOOLS__: "false",
    }),
    
    • 1
    • 2
    • 3
    • 4
    • 5

    除了以上vue中专用的配置,然后加上less,scss的loader,把前面的html插件加上去。就是一个基本的vue-cli了。完整的配置可以看最前面的仓库链接。

    优化

    按需引入第三库

    如 elment plus 按需引入可参照其官网进行配置

    https://yk2012.github.io/sgg_webpack5/
    https://vue-loader.vuejs.org/zh/
    https://webpack.docschina.org/

  • 相关阅读:
    【LC简单】387. 字符串中的第一个唯一字符
    夯实基础,编译器原理前端部分浅析
    编程竞赛之哈希算法应用
    Unity 文字显示动画(2)
    二叉树的练习题
    AtCoder Beginner Contest 277 F. Sorting a Matrix(拓扑排序+虚点)
    比肩Gen-2,全新开源文生视频模型
    Navigation 组件(一) Fragment 跳转
    Linux友人帐之Vim编译器
    Kubernetes和Docker对不同OS和CPU架构的适配关系
  • 原文地址:https://blog.csdn.net/weixin_40425481/article/details/125895536