标签: webpack5

  • 升级 Webpack 4 至 Webpack 5 笔记

    升级 Webpack 4 至 Webpack 5 笔记

    Webpack 5 已经发布一段时间了,我也找机会把几个项目从 Webpack 4 升级到 Webpack 5,从中积累了一些经验和教训,记录于本文。

    0. 请先阅读官方升级指引

    链接在此:To v5 from v4。(其实我也没认真读完……)

    0.1 @vue/cli 不要贸然升级

    @vue/cli 目前的版本号是 4.x,使用它创建的项目需要 webpack 4,升级到 Webpack 5 的话,因为两个版本配置文件存在差异,就无法正常使用了。所以如果是 @vue/cli 创建的项目,就不要贸然升级。

    如果你需要升级,比如想用最新的 TailwindCSS@3,那么可以直接升级 @vue/cli,目前最新版本是 v5.0.3,直接集成了 webpack@5。

    1. 升级依赖

    随着 Webpack 一起升级的,还有 webpack-cli、webpack-bundle-analyzer、webpack-dev-server;以及一众插件,比如 html-webpack-plugin、terser-webpack-plugin 等。

    因为存在依赖关系,建议大家一起升级:

    # 检查新版本
    npm outdated
    
    # 安装新版本的 webpack 套件
    npm i webpack@5 webpack-cli@4 webpack-dev-server@3

    2. 升级配置文件

    大部分配置可以直接继续使用。

    3. 升级 npm scripts

    Webpack 5 对内部模块的使用有所调整,所以我们需要调整一下 npm scripts。

    3.1 webpack-dev-server

    # 仍然需要安装 webpack-dev-server
    npm i webpack-dev-server -D
    
    # webpack 4
    webpack-dev-server --config build/webpack.config.dev.js
    
    # webpack 5
    webpack serve --config build/webpack.config.dev.js

    3.2 webpack-bundle-analyzer

    # 仍然需要安装 webpack-bundle-analyzer
    npm i webpack-bundle-analyzer -D
    
    # webpack 5
    webpack --analyze --config build/webpack.config.js
    
    # webpack 4,配置 build/webpack.config.js 实现

    4. 问题&解决

    4.1 解决:`Can’t resolve ‘http’ in ‘axios’

    在一个项目中,因为需要针对不同浏览器进行不同的适配,所以我们给 .browserslist 加入了环境配置:

    [modern]
    last 5 chrome versions
    last 3 firefox versions
    last 2 safari versions
     
    [withie]
    last 5 chrome versions
    last 3 firefox versions
    last 2 safari versions
    edge >= 18

    然后编译时就会报这个错误:

    Can't resolve 'http' in 'axios'

    经过一段时间的 Google,发现给 webpack.config.js 添加 target: 'web' 可解。所以我猜测,是因为我们的 .browserslist 有环境配置,所以 webpack 没认出来,所以当作 node 来打包。

    在 Webpack 4 时期,Webpack 自带针对 node.js 的 polyfill,所以没什么问题;但是 Webpack 5 把这个 polyfill 移除了,所以就报错。

    4.2 解决 HMR(自动更新,热模块更新,hot module reload)失效的问题

    使用 Webpack 5 后,有些项目的自动更新会失效,这是因为 Webpack 没有正确的识别项目的执行环境,错把它当成 node.js。这个时候,在 package.json 里添加 target: web' 即可解决。