【来实现一个简单的 Vite 吧】!第二章 - 修改第三方模块的路径

748 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

第二章 - 修改第三方模块的路径

书接上回 第一章 - 搭建静态web服务器,接下来我们来处理 请求第三方模块的问题。

思路

我们需要创建两个中间件

  • 修改第三方模块路径中间件
    • 主要负责 改变加载第三方模块中 import的路径,改成加载 /@/modules/${模块名称}
  • 加载第三方模块中间件
    • 重要负责 请求过来之后,判断请求路径是否有 /@/modules/${模块名称},如果有的话从node_modules中加载模块

修改第三方模块路径中间件 - 实现

  1. 当把静态文件返回给浏览器之前判断是否是js模块,如果是的话就修改模块路径为/@/modules/${模块名称}

    这里我们只需要根据ctx.type === 'application/javascript'来进行判断就好,上一节中的借鉴小点中也有提到

    app.use(async (ctx, next) => {
      if(ctx.type === 'application/javascript') {
    
      }
    })
    
  2. 找到对应内容并且处理 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)
})
  1. 转换对应的 import 路径 这里我们回忆一下,我们正常引用模块的方式是不是这两种
  2. import vue from 'vue'
  3. 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 中的请求

image.png 我们可以看见这次参数的结果,vue的路径已经被我们按照如期的进行修改了

小结

结果上面的编码接下来我们的目标就是根据请求的路径判断是否是/@modules/开头,如果是的话就去请求node_modules的模块了

这里因为篇幅有限,所以加载第三方模块就到下一节再说!

喜欢的话留个赞吧!