使用webpack.resolve.alias替换express,保证可以正常构建出web版本

需求背景

ts 复制代码
import { readFileSync } from "fs"

我们知道,web是不支持nodejs fs模块,更不能读取磁盘文件,但是如果我要使用webpack打包为web版本,以上的代码是肯定过不去的。

所以我不得不在代码中作如下判断

ts 复制代码
if (!isWeb) {
     const { readFileSync } = require("fs")
     // ...
}

是的,我判断在非web环境我才调用引入fs模块,并且使用相关的api,这样也能解决问题。

但是当情况复杂起来,这样解决方案就行不通了,会让代码难以维护。

比如以下的情况,期望的代码是如下,也能正常通过webpack的打包

ts 复制代码
import express, { Express } from "express"

let expressInstance: Express | null = null;
if(!isWeb){
    expressInstance = express();
}

很明显express是不支持web环境的,所以你可能会这么改

ts 复制代码
let expressInstance = null; // 变量的类型标注丢失
if(!isWeb){
    const express = require("express"); // 在ts里面写require,让代码很蹩脚
    expressInstance = express();
}

怎么看,这个代码都不是太尽如人意,而且上边的2个问题,就是让代码难以维护的罪魁祸首。

因为我的cc-plugin是可以同时发布web版本和nodejs版本,所以才出现这么奇葩的需求。

解决办法

让我再阐明下我的需求,我希望代码完全的使用typescript易于维护,并且webpack能够自动兼容一些nodejs的本地接口,这些接口在web环境不实现也行,其实压根也实现不了。

因为有isWeb的判断,所以从代码编写角度来说,以下的写法肯定是最优解

ts 复制代码
import express, { Express } from "express"

let expressInstance: Express | null = null;
if(!isWeb){
    expressInstance = express();
}

那问题就指向了,有什么办法可以让预期的代码通过webpack编译呢?

如果你对webpack非常熟悉,肯定知道fallback,有许多nodejs的模块都有对应的browserify,可以让其在浏览器环境正常运行。

browserify简单来说,其原理就是使用纯js实现对应模块的api,保证其在浏览器里面也能正常工作,这和游戏引擎跨平台的道理是一样的。

而这里我的需求是仅仅保证webpack能通过编译即可,在web环境里面,我是不会调用到express的相关api的,顺着这个思路想下去,再结合fallback的思想,很自然的我就想到了解决办法:

实现一个express的browserify,相关的接口全部为空实现,这样就能保证webpack能够正常编译,而且能够正常import "express",虽然这样导入的express模块是一个空壳,但是我代码层面在web环境是不会调用到相关接口的,所以这样子也算解决了我的问题。

在webpack里面强制替换模块,使用的是webpack resolve alias,所以在webpack配置里面

json 复制代码
{
    resolve:{
        alias:{
            "express": "express-browserify"
        }
    }
}

当打包web版本时,使用以上配置,node版本时,还正常使用express,这样子就不用来回改代码了,至此问题就完美解决了,以下是我写的几个模块的browserify空实现

总结

其实我看了几个fallback的browserify,并不是所有的nodejs本地api都支持了,有些browserify也是空实现,看来大家的思路都是相同的,浏览器办不到的就不实现,保证能正常编译就行了。

相关推荐
星星不打輰5 分钟前
Vue入门常见指令
前端·javascript·vue.js
好_快36 分钟前
Lodash源码阅读-isNative
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-reIsNative
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-baseIsNative
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-toSource
前端·javascript·源码阅读
Oneforlove_twoforjob1 小时前
volta node npm yarn下载安装
前端·npm·node.js
咖啡の猫1 小时前
npm与包
前端·npm·node.js
徐福记c1 小时前
npm install -g @vue/cli 方式已经无法创建VUE3项目
前端·vue.js·npm
小王不会写code1 小时前
npm install时卡在reify:rxjs: timing reifyNode:node_modules/core-js
前端·javascript·npm
慕钦。1 小时前
图像滑块对比功能的开发记录
前端·javascript·css·html5