了解webpack

1 概念

webpack是一个模块打包工具,他将各种不同类型的文件最终都打包成.js、.css、.png、.jpg4个类型的静态资源。

2 特点

  • 模块化开发

用webpack之前,项目都是在html中引入一个个js文件来开发;而在webpack中,一切皆模块(js、css、图片、字体、) ,可以通过import、require来实现模块开发。帮助我们优化代码,提升性能

  • 新语法

由于js、css等开发语言的语法在逐渐更新, 但浏览器不会实时更新兼容,webpack可以使用预处理器loader(例如less-loader、sass-loader、babel-loader)对文件进行预处理编译(例如less、sass、ES6、TS),这样使开发者更自由方便是使用最新的语法开发。

  • 主流框架脚手架

一些主流的框架的脚手架(例如vue的vue-cli、react的create-react-app)都使用了webpack,因此可以根据项目需求,自由的配置webpack,从而提升项目性能

  • 扩展性强、插件机制完善

开发者可以自定义插件、loader

  • 拥有丰富的配置

依赖管理、动态打包、代码分离、按需加载、代码压缩、静态资源压缩、缓存等配置

  • 社区庞大,轮子丰富

3 核心用法

3.1 dependency graph(依赖图)

webpack处理应用程序递归构建的一个依赖关系图,核心就是文件之间的直接依赖关系。webpack通过依赖关系图获取非代码资源,比如images或字体,并把他们作为依赖提供给应用程序。

3.2 entry(入口)

依赖关系图的开始,从入口开始寻找依赖,打包构建。(允许多个入口)

默认值是"./src/index.js"

例如:

javascript 复制代码
module.exports = {
    entry: "index.js"
}

3.3 output(输出)

指定打包的位置和文件名。

默认主要文件是"./dist/main.js"

其他默认文件位置是"./dist"

例如:

javascript 复制代码
const path = require('path');

module.exports = {
  entry: './my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
};

3.4 loader

webpack默认只识别js和json文件,其他类型的文件(如css、ts)需要安装loader处理,webpack将他们转换成模块,同时被添加到依赖图中。

loader属性

  • text - 识别出哪些文件会被转换
  • use - 在进行转换时,应该使用哪个 loader

应用: 通过单独定义一个module对象属性,定义rules属性,来配置loader的具体属性

示例:

javascript 复制代码
module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader' }],
  },
};

3.5 plugin(插件)

插件是用来扩展webpack的工具,正是开发者社区插件的丰富使得webpack的功能更加丰富。

通常在先require引入,然后在plugins数组中定义插件。

示例

javascript 复制代码
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装

module.exports = {
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};

3.6 mode(模式)

webpack提供了模式的选择(开发模式development、生产模式production、空模式none),可通过在不同环境选择不同的配置模式,让项目性能更优。

不同环境对应修改不同的配置文件(例如webpack.dev.js、webpack.prod.js)

示例:

javascript 复制代码
module.exports = {
  mode: 'development',
};

3.7 resolve(解析)

resolve用来设置模块如何解析,常用的配置有:

  • alias:配置别名,简化模块引入
  • extensions:在引入模块时可不带后缀
  • symlinks:用于配置 npm link 是否生效(禁用可提升编译速度)

示例

javascript 复制代码
const path = require('path');
function resolve(dir) {
    return path.join(__dirname, dir);
}

module.exports = {
    resolve: {
        extensions: ['.js', '.jsx', '.tsx', '.json'],
        alias: {
          '@': resolve('src'),
        },
        symlinks: false,
      }
}

3.8 optimization(优化)

根据mode的不同值来自定义不同的webpack的内置优化配置,一般用于生产模式提升性能。

常用的配置项有:(详细的可查看API

  • minimizer:配置压缩工具(如 TerserPlugin、OptimizeCSSAssetsPlugin)
  • splitChunks:拆分 bundle
  • runtimeChunk:是否需要将所有生成 chunk 之间共享的运行时文件拆分出来

示例

javascript 复制代码
module.exports = {
  //...
  optimization: {
    splitChunks: {
      // include all types of chunks
      chunks: 'all',
      // 重复打包问题
      cacheGroups:{
        vendors:{ //node_modules里的代码
          test: /[\\/]node_modules[\\/]/,
          chunks: "all",
          name: 'vendors', //chunks name
          priority: 10, //优先级
          enforce: true 
        }
      }
    },
    runtimeChunk: {
      name: 'runtime',
    },
  },
};

3.9 devServer

帮助我们在代码发生变化后自动编译代码,具有实时重新加载功能。

常用配置项: (详细的可查看API

  • open:告诉 dev-server 在服务器项目启动后打开浏览器

  • port:本地环境的端口号

  • proxy:API请求代理配置(通过子属性targert设置API地址;默认情况,代理时会保留主机头的来源,可以通过子属性changeOrigin设置为 true覆盖此行为)

  • compress:默认为true。为每个静态文件开启gzip压缩

示例

javascript 复制代码
devServer: {
        port: 8080,
        open: true,
        overlay: {
            warnings: false,
            errors: true
        },
        proxy: {
            "/app-config": {
                ws: false,
                target: 'http://xx.xx.xx.xx:8080', // 后台接口地址
                changeOrigin: true
            },
        }
}

3.10 cache(缓存)

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

他的值在开发模式下会被设置为cache: {type: 'memory'}(与cache: true作用一致);

生产模式下会被禁用。

4 loader配置

项目中会使用到很多loader配置,每个loader对应提供了不同的功能。例如:

css-loader:会对@import和url()进行处理,就像js解析require和import一样;

babel-loader:通过babel和webpack将代码转译为js代码;

sass-loader:将预处理器scss/sass转译成css语法代码;

style-loader:把css插入到dom中;

html-loader:将html导出为字符串,在编译器需要时,将压缩html字符串

... ... 更多loader配置和使用功能可查看API

配置过程(以css-loader、style-loader为例,二者可串联配置):

1,安装loader的依赖:npm install --save-dev style-loader css-loader

2,修改通用环境配置文件 webpack.commom.js

javascript 复制代码
const paths = require('./paths');

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                include: paths.appSrc,
                use: [
                  'style-loader', // 将JS字符串生成为 style 节点
                  
                  'css-loader', // 将CSS转化成 CommonJS 模块
                ],
            },
        ]
     }
}

5 配置图片与字体

webpack5中,可以将images图片和font字体混入到系统中。

加载图片

javascript 复制代码
const paths = require('./paths');
module.exports = {
    module: {
        rules: [
          {
            test: /\.(png|svg|jpg|jpeg|gif)$/i,
            include: paths.appSrc,
            type: 'asset/resource',
          },
        ],
      },
}

加载字体

javascript 复制代码
module.exports = {
    module: {
        rules: [
            {
               test: /.(woff|woff2|eot|ttf|otf)$/i,
               include: [
                  resolveApp('src'),
                ],
               type: 'asset/resource',
             },
         ]
     }
 }

6 高级配置与性能优化

webpack可以通过一些更详细的配置来实现性能优化。例如:

配置cache加快构建时间;

合理拆分chunks、压缩代码等来减小打包体积;

设置按需加载、浏览器缓存等加快加载速度。

具体可参考学习 Webpack5 之路(优化篇)

相关推荐
迷雾漫步者1 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-2 小时前
验证码机制
前端·后端
燃先生._.3 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖3 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235244 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240254 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar4 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人5 小时前
前端知识补充—CSS
前端·css
GISer_Jing5 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试