了解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 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai2 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9152 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼3 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風7 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#