webpack

webpack

解决的问题

  • 编译浏览器无法理解的东西

ES6、ts、.vue

  • 代替一些人工操作

文件合并与拆分、图片压缩、资源处理、代码转换等

  • 帮助开发

提供本地服务器、热更新、代理

配置项

  • entry 入口(必须项)
  • output 出口(必须项)
  • module loader编写的地方
  • plugins 插件
  • mode 模式(必须项)
    • development 开发模式下,Webpack 会自动优化打包速度,添加一些调试过程中的辅助;
    • production 生产模式下,Webpack 会自动优化打包结果;(例如:代码的压缩混淆等)
    • none Webpack 就是运行最原始的打包,不做任何额外处理;
  • optimization 优化
  • devServer 开发模式配置
  • resolve 解析提供一些简化功能

文件后缀别名等

  • cache 缓存

缓存生成的 webpack 模块和 chunk,来改善构建速度

  • devtool

是否生成,以及如何生成 source map。

处理JS

  • es6 转换

babel-loader

安装:@babel/preset-env 用来转换es6语法到这个版本,需要配置(可以卸载babel配置文件中),不然不会进行转换

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

配置:

{
              test: '/\.js$/',
              use: {
                  loader: "babel-loader",
                  options: { // babel 配置
                      presets:[
                          [
                              '@babel/preset-env',
                              {
                                  targets:{
                                      browsers: [
                                          ">1%", // 占有率大于1%
                                          "last 2 versions",// 支持浏览器最后两个版本
                                          "not ie<=8"// 不支持ie8及之前的浏览器
                                      ]
                                  }
                              }
                          ]
                      ]
                  }
              }
          }
  • 代码规范

eslint-loader(webpack5 废弃),使用eslint-webpack-plugin

安装:eslint-webpack-plugin

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

配置:

// webpack.config.js
const ESLintPlugin = require('eslint-webpack-plugin');

 new eslintPlugin()

规范:

定义不同规则,可在开源规则中继承

//.eslintrc.ts
module.exports = {
  env: {
    browsers: true, //环境 浏览器环境,
    es2021: true //版本
  },
  // 继承 如
  // eslint-config-standard
  // eslint-config-airbnb
  exports:[
    "standard", //eslint-config-standard
    "plugin:vue/strongly-recommended", //eslint-config-airbnb
  ],
  // eslint-plugin-vue
  plugins:[// 插件 提供一些特殊语法 如Vue书写规则
    "vue"
  ],
  parserOptions: {
    ecmaVersion: 6, //版本
    sourceType:'module', //模块
    ecmaFeatures: {
      jsx: true //是否使用jsx
    }
  },
  rules: {

  }
}

处理TS

  • 安装
npm install --save-dev typescript ts-loader
  • 配置
{
    test: /\.ts$/,
    use: 'ts-loader',
    exclude: /node_modules/
}

处理css

css-loader 解析css文件,将css文件变成js模块

之后有两种方式:

style-loader 将css作为 style 插入到html中

mini-css-extract-plugin 提取css到单独的文件中

  • 安装
npm install --save-dev style-loader css-loader mini-css-extract-plugin
  • 配置
const miniCssExtractPlugin = require("mini-css-extract-plugin")

// module.rules
{
    test: /\.css$/,
     use: ['miniCssExtractPlugin.loader', 'css-loader']
}

// plugins
new miniCssExtractPlugin({ // css 处理
            filename: "[name].bundle.css"
        })

css预编译处理:

先将sass/scss/less 编译成css文件,然后再进行css处理

  • sass-loader

安装:npm install --save-dev sass sass-loader
配置:{ test: /\.scss$/, use: ['style-loader', 'css-loader','sass-loader'] }

  • less-loader

安装:npm install --save-dev less less-loader
配置:{ test: /\.less$/, use: ['style-loader', 'css-loader','less-loader'] }

css压缩:

  • css-minimizer-webpack-plugin

安装:npm install --save-dev css-minimizer-webpack-plugin
配置:

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

new CssMinimizerPlugin({
    minimizerOptions: {
        preset: [
            "default",
            {
                discardComments: { removeAll: true },
            },
        ],
    },
})

资源文件处理

webpack5 自带了资源文件处理,不需要再配置。

  • 图片

file-loader 处理图片文件,将图片文件变成base64的字符串,然后将字符串插入到js中
url-loader 处理图片文件,将图片文件变成base64的字符串,然后将字符串插入到js中,但是如果图片大小超过了limit,则会将图片文件变成base64的字符串,然后将字符串插入到js中

  • 优化操作

图片操作:

使用webpack自带的,只用配置type即可

type:

  • asset: 根据配置决定

  • asset/inline: 全部转换为base64的字符串

  • asset/resource: 使用图片地址

// 资源文件 webpack自带
{
  test: '/\.(jpg|jpeg|png|gif|svg)$/',
          type: "asset" ,// asset/inline  asset/resource
        parser: {
  dataUrlCondition: {
    maxSize: 5000 // 大小零界配置
  }
},
  generator: {
    filename: "[name].[hash][etx]" // 本名 + hash + 后缀
  }
}

html处理

使用插件 html-webpack-plugin

  • 提供一个html模板,复用固定内容
  • 打包生成一个html
  • 打包出来的html自动引入js

安装 npm install --save-dev html-webpack-plugin
配置

// plugins
// html
new HtmlWebpackPlugin({
  template: "./public/index.html", //用来做模板的html的文件路径(从项目根目录开始)
  filename: "index.html", //生成的html的名字
  title:'vue3+webpack5',// 标题名称
  inject: "body" // 打包出来的那个js文件,放置在生成的body标签内
})

vue 处理

  • 安装
npm install --save-dev vue-loader @vue/compiler-sfc 
  • 配置
// module.rules
{
    test: /\.vue$/,
    use: 'vue-loader'
}
// plugins
new VueLoaderPlugin()

loader 本质

loader 本质就是一个函数,接受源文件作为参数,返回转换后的结果

代码分割

用来将代码分割成多个文件,然后再进行打包,然后再进行代码分割,这样可以减少首屏加载时间

  • 异步加载
import("./home").then(({default:home})=>{
  console.log(home)
})
  • 动态导入
import(/* webpackChunkName: "home" */ "./home")
  • 路由懒加载
const Home = () => import(/* webpackChunkName: "home" */ "./home")
  • 代码分割

runtime + vendor + 核心代码 + 异步代码

// optimization
splitChunks: { // 项目代码
  chunks: "all", // 所有的chunk
  minSize: 20000, // 最小的chunk大小
  minChunks: 1, // 最少的chunk数量
  maxAsyncRequests: 5, // 最多的异步请求数量
  maxInitialRequests: 3, // 最多的初始请求数量
  automaticNameDelimiter: "~", // 分割符
  cacheGroups: { // 缓存组
    defaultVendors: { // 第三方库
      test: /[\\/]node_modules[\\/]/,
      priority: -10, // 优先级
      name: "vendors"
    },
    default: { // 公共库
      minChunks: 2,
      priority: -20,
      reuseExistingChunk: true
    }
  }
},
runtimeChunk: { //webpack运行时代码
  name: 'runtime'
}

技巧性配置

文件hash : 解决缓存问题,在浏览器中缓存文件,下次访问时,直接从缓存中获取,不用重新请求服务器,导致重复从缓存中获取。

使用 [chunkhash] 控制只有当前文件改变时,才会更改文件hash

resolve 配置

  • alias 别名
alias:{
    "@": "/src"  
}, 
  • extensions 后缀名
extensions: ['.tsx', '.ts', '.js']

批量引入指定文件下的所有文件

require.context(<路径>, <是否递归>, <匹配的文件>)

const r = request.context("./model", false, /.js/)
const keys = r.keys()
const value = r(keys[0])

将打包结果放入某个文件下

在 filename 配置中前面添加路径

  filename: "./css/[name].bundle.css"

CDN引入加前缀

// output
publicPath: 'URL_ADDRESS'

开发模式

  • devServer
devServer: {
        hot: true, // 热更新
        open: true, // 启动服务打开浏览器
        port: 8080, // 端口
        host: "localhost", // 地址
        proxy: { // 代理
            "/": {
                target: "http://localhost:3000/", // 代理地址
                pathRewrite: { //路径重写
                    "^/num": "/api/getNum"
                },
                headers:{ //请求头

                }
            }
        }
    },
  • devtool
devtool: "eval-cheap-source-map",

区分环境

  • 生产模式

代码压缩、tree shaking、代码混淆

  • 开发模式

热更新、source map

区分环境:

  • 根据不同环境不同打包 process.env.NODE_ENV
  • JS获取环境 webpack 提供的插件

将开发环境和生产环境的配置分离,再将公共配置导入,形成不同的配置文件,
最后在不同的环境中使用不同的配置文件。

webpack提供了合并工具 merge

// 开发环境
// webpack.dev.config.js
const merge = require("webpack-merge")
const baseConfig = require("./webpack.base.config.js")

module.exports = merge(baseConfig, {
  mode: "production",
})
// 生产环境
// webpack.prod.config.js
const merge = require("webpack-merge")
const baseConfig = require("./webpack.base.config.js")

module.exports = merge(baseConfig, {
  mode: "production",
  devtool: "source-map",
  devServer: {
    hot: true,
    open: true,
    port: 8080,
    host: "localhost",
    proxy: {
      "/": {
        target: "URL_ADDRESS",
        pathRewrite: {
          "^/num": "/api/getNum"
        }
      }
    }
  }
})

配置环境变量

  • 安装:npm install --save-dev cross-env dotenv

dotenv: 读取.env文件环境变量
cross-env:指令跨平台库
NODE_ENV 可以通过process.env.NODE_ENV获取环境变量

// package.json
"scripts": {
    "dev": "cross-env NODE_ENV=dev webpack-dev-server --config webpack.dev.config.js",
    "build": "cross-env NODE_ENV=prod webpack --config webpack.prod.config.js"
  }
if (process.env.NODE_ENV === "dev") {
    console.log("dev")
}

打包优化

打包分析

  • 安装:npm install --save-dev webpack-bundle-analyzer
  • 配置:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

// plugins
new BundleAnalyzerPlugin()

dll优化

dll:动态链接库
先将第三方库打包成一个dll文件,然后再将dll文件引入到项目中,这样就可以减少打包时间。
dll-plugin webpack已经提供了dll插件

  • 配置:
// webpack.dll.config.js
const webpack = require("webpack");

// plugins
new webpack.DllPlugin({
  name: "dll", // 生成的dll文件的名字
  path: path.resolve(__dirname, "dll", "manifest.json") // 生成的dll文件的路径
  context: __dirname // 上下文
})
// package.json
"scripts": {
    "dll": "webpack --config webpack.dll.config.js"
  }
// 生产环境引用
// webpack.prod.config.js
const path = require("path");
const webpack = require("webpack");

//plugins
new webpack.DllReferencePlugin({
  manifest: path.resolve(__dirname, "dll", "manifest.json")
})

dll打包的东西需要手动在index.html中引入

<!-- index.html -->
<script  src="./dll/vendors.dll.js"></script>

代码压缩混淆

  • 安装:npm install --save-dev terser-webpack-plugin,webpack5自带了
const TerserPlugin = require('terser-webpack-plugin');
// optimization
optimization: {
    minimize:true,// 压缩代码
  minimizer: [
    new TerserPlugin({
      terserOptions: {
        compress: {
          drop_console: true, // 删除console
          drop_debugger: true, // 删除debugger
          pure_funcs: ["console.log"] // 压缩console.log
        }
      }
    })
  ]
}

tree shaking

// optimization
  usedExports: true, // 只导出使用的模块
  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天将降大任于我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值