一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
第二章 - 修改第三方模块的路径
书接上回 第一章 - 搭建静态web服务器,接下来我们来处理 请求第三方模块的问题。
思路
我们需要创建两个中间件
- 修改第三方模块路径中间件
- 主要负责 改变加载第三方模块中
import
的路径,改成加载/@/modules/${模块名称}
- 主要负责 改变加载第三方模块中
- 加载第三方模块中间件
- 重要负责 请求过来之后,判断请求路径是否有
/@/modules/${模块名称}
,如果有的话从node_modules
中加载模块
- 重要负责 请求过来之后,判断请求路径是否有
修改第三方模块路径中间件 - 实现
-
当把静态文件返回给浏览器之前判断是否是js模块,如果是的话就修改模块路径为
/@/modules/${模块名称}
这里我们只需要根据
ctx.type === 'application/javascript'
来进行判断就好,上一节中的借鉴
小点中也有提到app.use(async (ctx, next) => { if(ctx.type === 'application/javascript') { } })
-
找到对应内容并且处理 import 的路径,ctx 中的 body 就是要返回的 js 文件
app.use(async (ctx, next) => {
if(ctx.type === 'application/javascript') {
const contents = await stremToString(ctx.body)
}
})
注意 ctx 中的 body 是一个流,所以我们需要把流,转换为字符串 转换函数
// 流转换字符串函数
// 因为转换流是一个异步操作,所以我们需要返回一个 Promise 对象
const stremToString = stream => new Promise((resolve, reject) => {
const chunks = []
// 注册 stream 的 data 事件, 去监听读取到的 buffer
stream.on('data', chunk => chunks.push(chunk))
// 数据读取完毕,调用 resolve 并传递数据
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))
// 注册错误事件
stream.on('error', reject)
})
- 转换对应的 import 路径 这里我们回忆一下,我们正常引用模块的方式是不是这两种
import vue from 'vue'
import App from './App.vue'
但是我们要处理的是第一种类型,第二种是可以正常引入的,这里我们就需要使用replace
进行替换就好(简单处理垃)
app.use(async (ctx, next) => {
if(ctx.type === 'application/javascript') {
const contents = await stremToString(ctx.body)
// import vue from 'vue'
// import App from './App.vue'
ctx.body = contents.replace(/(from\s+['"])(?!\.\/)(?!\..\/)/g,'$1/@modules/')
}
})
到这里,我们的路径修改就已经处理的差不多了
测试
我们再次运行
npm link
再次进入到我们的测试模块中,运行
vite-cli
进入http://localhost:3000/
中,开启控制台
main.js 中的请求
我们可以看见这次参数的结果,vue的路径已经被我们按照如期的进行修改了
小结
结果上面的编码接下来我们的目标就是根据请求的路径判断是否是/@modules/
开头,如果是的话就去请求node_modules
的模块了
这里因为篇幅有限,所以加载第三方模块就到下一节再说!
喜欢的话留个赞吧!