likes
comments
collection
share

Scratch3.0 二次开发——按需修改 webpack 配置

作者站长头像
站长
· 阅读数 17

概述

这次核心介绍如何在 gui 项目按需修改 webpack 的配置文件。

PS:下文没有详细讲解 webpack 是如何配置的,适合对 webpack 配置有一定了解的同学阅读,具体配置细节可参考 demo-scratch-gui 项目源码,以及百度。

需求分析

官方提供的 webpack.config.js 相对比较简单,可用,但有需要再优化优化。

梳理一下比较重要的几个需求:

  1. 区分多个环境的环境变量
    • node 提供的 process.env.NODE_ENV 只有 development、production,两种。一般情况下是不能满足大多数团队对于环境变量的需求的。像我们这边会分本地开发环境(dev)、线上测试环境(test)、线上预发布环境(uat)、线上生产环境(prod),需要标识 4 个环境。
  2. 根据不同环境设置全局变量
    • 把全局变量抽离出来(api 前缀、cdn 域名之类的),不同环境下同名覆盖,避免发布时临时更换
  3. 路径别名
  4. 将 scratch 和其它第三方库打包时独立出 js 文件出来
    • 官方 scratch 将所有 js 打包到 gui、lib.min 两个 js 文件中,且没有加 hash 值,一方面可能会有缓存问题,另一方面对于不经常变化的库来说,也没有利用好浏览器的缓存策略
  5. 开启打包分析,查看打包出来的文件的大小、占比情况

实现细节

修改 package.json 中 babel、webpack 相关的依赖

Scratch3.0 二次开发——按需修改 webpack 配置

Scratch3.0 二次开发——按需修改 webpack 配置

Scratch3.0 二次开发——按需修改 webpack 配置

PS:

  1. 这里 webpack 没有升级到 v5,升到 v5 后构建会有问题,暂时还是先保留官方的使用 v4 版本
  2. 之所以要修改 babel,是因为之前官方用的版本有点旧,而且 babel 新版对包的使用和引入都有改变,所有就一次性升级到目前最新的

在根目录下新建 .webpack 文件夹

把 webpack 的所有配置项都放在这个文件夹中,里面核心是以下几个配置文件:

  1. webpack.common.js
    • 通用配置文件,后面几个配置文件都需要合并这份配置
    • 里面有几个关键的配置特别说明一下:
      1. 在 resolve 开启别名 alias,开启别名后,需要配套在跟目录中设置 jsconfig.json 文件,才能实现在 vscode 中点击跳转到对应文件,如果不配置的话,vscode 是识别不了别名的
        • Scratch3.0 二次开发——按需修改 webpack 配置
      2. 对于 js、jsx 的 loader,分开了两个,分别处理依赖包和 gui 项目源码,具体原因请见 demo-scratch-gui 项目源码备注
      3. 增加了 optimization 的 splitChunks 代码分割,把 scratch 相关的库和其它常用第三方库分别打包到不同的 js 文件中
        • Scratch3.0 二次开发——按需修改 webpack 配置
  2. webpack.dev.js
    • 本地开发环境的配置文件
  3. webpack.test.js
    • 线上测试环境的配置文件
  4. webpack.uat.js
    • 线上预发布环境的配置文件
  5. webpack.prod.js
    • 线上生产环境的配置文件

后面 4 个环境的配置文件,基本就只用于根据不同环境设置全局变量,当然,如果有其它配置的需要也可以单独写在各自的环境里面

Scratch3.0 二次开发——按需修改 webpack 配置

PS:这里简单封装了一个 formatDefine 函数,核心作用是方便快速添加全局变量

function formatDefine(target) {
    const result = {};

    for (const key in target) {
        const element = target[key];

        if (typeof element === 'boolean' || typeof element === 'number') {
            result[key] = element;
        } else {
            result[key] = JSON.stringify(element);
        }
    }

    return result;
}

module.exports = formatDefine;

不加这个函数的话,在 webpack 中的 DefinePlugin 设置环境变量会比较麻烦,如下图

Scratch3.0 二次开发——按需修改 webpack 配置

增加各个环境的构建脚本

Scratch3.0 二次开发——按需修改 webpack 配置

"build:dev": "npm run clean && cross-env NODE_ENV=production MY_ENV=dev webpack --color --bail --progress --config .webpack/webpack.dev.js",
"build:test": "npm run clean && cross-env NODE_ENV=production MY_ENV=test webpack --color --bail --progress --config .webpack/webpack.test.js",
"build:uat": "npm run clean && cross-env NODE_ENV=production MY_ENV=uat webpack --color --bail --progress --config .webpack/webpack.uat.js",
"build:prod": "npm run clean && cross-env NODE_ENV=production MY_ENV=prod webpack --color --bail --progress --config .webpack/webpack.prod.js",
"start:dev": "cross-env NODE_ENV=development MY_ENV=dev webpack-dev-server --config .webpack/webpack.dev.js",
"start:test": "cross-env NODE_ENV=development MY_ENV=test webpack-dev-server --config .webpack/webpack.test.js",
"start:uat": "cross-env NODE_ENV=development MY_ENV=uat webpack-dev-server --config .webpack/webpack.uat.js",
"start:prod": "cross-env NODE_ENV=development MY_ENV=prod webpack-dev-server --config .webpack/webpack.prod.js",

总结

通过上面几个步骤的修改,就实现了开头需求分析中希望达到的功能

  1. 区分多个环境的环境变量、根据不同环境设置全局变量
    • 通过上述的 4 个环境的配置文件实现
    • 通过 MY_ENV 全局变量识别当前处于哪个环境
    • 4 个配置文件,对应的是 4 套构建命令,start:devstart:teststart:uatstart:prod
  2. 路径别名
  3. 将 scratch 和其它第三方库打包时独立出 js 文件出来
  4. 开启打包分析,查看打包出来的文件的大小、占比情况
    • 通过 analyze 脚本使用