构建 webpack5 知识体系【近万字总结】

我持续组织了近一年的源码共读活动,感兴趣的可以 点此扫码加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外:目前建有江西|湖南|湖北籍前端群,可加我微信进群。


本文经作者@lin嘟嘟嘟(源码共读群里的小伙伴) 授权转载。

原文链接:https://juejin.cn/post/7062899360995999780 文章较长可收藏

Part11、基础篇

11.1 webpack优点

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

  • webpack 扩展性强,插件机制完善,开发者可自定义插件、loader;

  • webpack 社区庞大,更新速度快,轮子丰富;

21.2 基础应用

99108b203b453d2519affe13ffe69207.png
image.png
  • webpack 通过依赖关系图可以获取非代码资源,如 images 或 web 字体等。并会把它们作为依赖提供给应用程序。

  • 每个模块都可以明确表述它自身的依赖,在打包时可根据依赖进行打包,避免打包未使用的模块。

1.2.1 entry(入口)

入口是指依赖关系图的开始,从入口开始寻找依赖,打包构建,webpack 允许一个或多个入口配置;

module.exports = {
 entry: './src/index.js'
}

多入口配置:

068de16c1ca6fd790012c374de795eeb.png
image.png

1.2.2 output(出口)

输出用于配置 webpack 构建打包的出口,如打包的位置,打包的文件名;

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
  },
};

1.2.3 loader(转换)

webpack 自带 JavaScript 和 JSON 文件的打包构建能力,无需格外配置,对于其他类型的文件如css等,则需要安装loader处理;

loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

1.2.4 plugin(插件)

插件则是用于扩展 webpack 的能力;

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

1.2.5 mode(模式)

webpack5 提供了模式选择,包括开发模式、生产模式、空模式,并对不同模式做了对应的内置优化。可通过配置模式让项目性能更优;

module.exports = {
  mode: 'development',
};

1.2.6 resolve(解析)

resolve 用于设置模块如何解析,常用配置如下:

  • alias:配置别名,简化模块引入;

  • extensions:在引入模块时可不带后缀;

  • symlinks:用于配置 npm link 是否生效,禁用可提升编译速度。

module.exports = {
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.d.ts'],
    alias: {
      '@': './',
    },
    symlinks: false,
  }
}

1.2.7 optimization(优化)

optimization 用于自定义 webpack 的内置优化配置,一般用于生产模式提升性能,常用配置项如下:

  • minimize:是否需要压缩 bundle;

  • minimizer:配置压缩工具,如 TerserPlugin、OptimizeCSSAssetsPlugin;

  • splitChunks:拆分 bundle;

  • runtimeChunk:是否需要将所有生成 chunk 之间共享的运行时文件拆分出来。

module.exports = {
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ],
    splitChunks: {
      chunks: 'all',
      // 重复打包问题
      cacheGroups:{
        vendors:{ 
          //node_modules里的代码
          test: /[\\/]node_modules[\\/]/,
          chunks: "all",
          //chunks name
          name: 'vendors', 
          //优先级
          priority: 10, 
          enforce: true 
        }
      }
    },
  },
}

31.3 本节代码

本小节需要安装的插件

npm install webpack webpack-cli --save-dev    
npm install --save-dev html-webpack-plugin
npm install --save-dev style-loader css-loader
npm install css-minimizer-webpack-plugin --save-dev

代码地址:https://gitee.com/linhexs/webpack5/tree/1.base/[1]

Part22、实践基础篇

42.1 实现目标

  • 分离开发环境、生产环境配置;

  • 模块化开发;

  • sourceMap 定位警告和错误;

  • 动态生成引入 bundle.js 的 HTML5 文件;

  • 实时编译;

  • 封装编译、打包命令。

52.2 基础配置

2.2.1 新建项目目录

79541c78e2f6ccd57380f410577cb269.png
image.png

2.2.2 安装插件

npm i webpack-merge -D
npm install webpack webpack-cli --save-dev

2.2.3 添加config目录下的webpack代码

webpack.common.js

// webpack.common.js

module.exports = {} // 暂不添加配置

webpack.dev.js

// webpack.dev.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {}) // 暂不添加配置

webpack.prod.js

// webpack.prod.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {}) // 暂不添加配置

2.2.4 entry(入口)

修改 webpack.commom.js:

// webpack.common.js

module.exports = {
  // 入口
  entry: {
    index: './src/index.js',
  },
}

2.2.5 output(出口)

output 属性输出它所创建的 bundle的位置和命名;

生产环境的 output 需要通过 contenthash 值来区分版本和变动,可达到清缓存的效果,而本地环境为了构建效率,则不引人 contenthash。

修改webpack.dev.js

// webpack.dev.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')
const { resolveApp } = require('./paths');

module.exports = merge(common, {
  // 输出
  output: {
    // bundle 文件名称
    filename: '[name].bundle.js',

    // bundle 文件路径
    path: resolveApp('dist'),

    // 编译前清除目录
    clean: true
  },
})

修改webpack.prod.js

// webpack.prod.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')
const { resolveApp } = require('./paths');

module.exports = merge(common, {
  // 输出
  output: {
    // bundle 文件名称 【只有这里和开发环境不一样】
    filename: '[name].[contenthash].bundle.js',

    // bundle 文件路径
    path: resolveApp('dist'),

    // 编译前清除目录
    clean: true
  }
})

新增 paths.js,封装路径方法resolveApp:

const fs = require('fs')
const path = require('path')

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

module.exports = {
  resolveApp
}

占位符作用

  • [name] - chunk name(例如 [name].js -> app.js)。如果 chunk 没有名称,则会使用其 id 作为名称

  • [contenthash] - 输出文件内容的 md4-hash(例如 [contenthash].js -> 4ea6ff1de66c537eb9b2.js)

2.2.6 模式(mode)

添加生产环境和开发环境:

module.exports =  merge(common, {
  // 生产模式
  mode: 'production',
})

module.exports =  merge(common, {
  // 生产模式
  mode: 'development',
})

2.2.7 source-map

使用source-map追踪 error 和 warning,将编译后的代码映射回原始源代码;

module.exports =  merge(common, {
  mode: 'development',
  // 开发环境,开启 source map,编译调试
  devtool: 'eval-cheap-module-source-map',
})

打包一下试试:

开发:

npx webpack --config config/webpack.dev.js
80b7a4329e1a96959d524ddd6562c6d3.png
image.png

生产:

npx webpack --config config/webpack.prod.js
eaf0f003dd30f290c77367a87958634d.png
image.png

2.2.8 HtmlWebpackPlugin

引入 HtmlWebpackPlugin 插件,生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包;

npm install --save-dev html-webpack-plugin

修改webpack.commom.js:

module.exports = {
  plugins: [
    // 生成html,自动引入所有bundle
    new HtmlWebpackPlugin({
      title: 'webpack',
    }),
  ],
}

2.2.9 DevServer

  • webpack-dev-server 提供了一个基本的 web server,并且具有实时重新加载功能;

  • webpack-dev-server 默认配置 conpress: true,为每个静态文件开启 gzip compression[2]

安装:

npm install --save-dev webpack-dev-server

修改开发环境配置文件webpack.dev.js:

module.exports = merge(common, {
   devServer: {
    // 告诉服务器位置。
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 8888,
    hot: true,
  },
})

代理配置:

22f69e510ecb1843cda2f040a8452e4e.png
image.png

输入命令启动:

npx webpack serve --open --config config/webpack.dev.js

2.2.10 执行命令

通过 cross-env 配置环境变量,区分开发环境和生产环境。

安装:

npm install --save-dev cross-env

修改 package.json:

{
    "scripts": {
        "dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js",
        "build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"
      },
}

现在可以运行 webpack 指令:

  • npm run dev:本地构建;

  • npm run build:生产打包;

62.3 本节代码

代码地址:https://gitee.com/linhexs/webpack5/tree/2.practice/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值