解决项目迁移vite引入图片资源报require is not defined的问题

02-27 1261阅读 0评论

文章目录

  • 前言
  • 一、遇到的问题
  • 二、解决办法
    • 1. 明确方向
    • 2. 解决方法
      • ① 方案一
      • ② 方案二
      • ③ 方案三
      • 三、原因及相关原理
        • 1. 为什么需要require方法
        • 2. 为什么require方法失效了
        • 3. new URL() 为什么就可以
        • 4. Vite插件介绍
        • 总结
        • 扩展阅读

          前言

          Vite是一种轻量快速的前端构建工具,能够显著提升前端开发体验,而且官方已经发布v4版本,相对比较稳定。在把VueCli搭建的项目迁移到Vite的过程中遇到了个问题,下面分享一下问题及解决办法。

          解决项目迁移vite引入图片资源报require is not defined的问题,解决项目迁移vite引入图片资源报require is not defined的问题,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,接口,第1张
          (图片来源网络,侵删)

          一、遇到的问题

          在script标签里面引入的图片资源没生效,然后一看控制台,报错显示 require is not defined …

          解决项目迁移vite引入图片资源报require is not defined的问题

          二、解决办法

          1. 明确方向

          经过查找Vite相关文档,看到官方文档静态资源处理目录,发现需要使用new URL()这个方法才能处理动态引入的URL,才能保证图片资源在经过打包和资源哈希后仍指向正确的地址。

          解决项目迁移vite引入图片资源报require is not defined的问题

          2. 解决方法

          ① 方案一

          既然如此,那么直接改为new URL() 的写法。

          原本写法是:

          解决项目迁移vite引入图片资源报require is not defined的问题,解决项目迁移vite引入图片资源报require is not defined的问题,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,接口,第4张
          (图片来源网络,侵删)
          url: require("../assets/images/banner@2x.png"),
          
          • 那么使用 new URL() 的写法:
            url: new URL(`../assets/images/banner@2x.png`, import.meta.url).href;
            
            • 或者是 import 的写法 :
              import banner from "../assets/images/banner@2x.png";
              url: banner,
              

              ② 方案二

              由于上面的方法都要一个个修改过于麻烦了,而且项目图片都位于src/assets/images/下,那么直接封装成一个函数,像hooks那样调用应该方便很多。

              1. 在utils文件下下新建useImgUrl.js文件,简简单单,只需要传入图片文件名及类型即可
              const getImgUrl = file => {
                return new URL(`../assets/images/${file}`, import.meta.url).href;
              };
              export default getImgUrl;
              
              1. 在文件中引入并使用,文件内修改只需使用全局替换功能即可
              import getImgUrl from "../utils/useImgUrl";
              url: getImgUrl("banner@2x.png"),
              

              ③ 方案三

              上面的方案虽然不用一个个改了,但是Vue3没有mixins这样可以全局引入的方法,还是需要在不同的文件去引入hook,这个时候我想能不能像webpack的loader那样去全局处理.vue文件,这样全局替换的操作交给构建工具去自动执行得了,然后发现Vite里面并没有loader配置,不过好在这时候一个Vite插件给了我灵感,可以用Vite插件API去实现类似的功能,于是转换下思路,写了这么一个插件

              1. 代码:
              // requireToUrlPlugin.js
              export default function requirePlugin() {
                return {
                  // 插件名称
                  name: "vite-plugin-vue-requireToUrlPlugin",
                  // 默认值post:在 Vite 核心插件之后调用该插件,pre:在 Vite 核心插件之前调用该插件
                  // enforce: "post",
                  // 代码转译,这个函数的功能类似于 "webpack" 的 "loader"
                  transform(code, id, opt) {
                    const vueRE = /\.vue$/;
                    const require = /require/g;
                    
                    // 过滤掉非目标文件
                    if (!vueRE.test(id) || !require.test(code)) return code;
                    // 匹配 require() 内的内容
                    const requireRegex = /require\((.*?)\)/g;
                    // 将 require() 内的内容替换为 new URL 的写法
                    const finalCode = code.replace(requireRegex, "new URL(,import.meta.url).href");
              		
              	  // 将转换后的代码返回
                    return finalCode;
                  },
                };
              }
              
              1. 在Vite配置中引入此插件:
              // vite.config.js
              import requireToUrlPlugin from './src/requireToUrlPlugin';
              export default defineConfig(({ command, mode }) => {
                  plugins: [
                    vue(),
                    requireToUrlPlugin(),
                  ]
              });
              

              引入后项目中的require方法都会被插件自动转换为new URL() 的语法,真的是终极大招[doge],这样就不用再一个个文件去改了,非常省事,而且自己写的插件也完全可以自由定制,写法仅供参考。

              解决项目迁移vite引入图片资源报require is not defined的问题

              通过查看控制台能看到通过Vite的打包运行“preview”后,图片是正常显示的。
              

              解决项目迁移vite引入图片资源报require is not defined的问题

              查看源代码能看到原本写的 require 方法已经变成了 new URL()的方法。
              

              三、原因及相关原理

              1. 为什么需要require方法

              静态资源就是直接存放在项目中的资源,这些资源不需要我们发送专门的请求进行获取。比如assets目录下面的图片,视频,音频,字体文件,css样式表等。

              解决项目迁移vite引入图片资源报require is not defined的问题,解决项目迁移vite引入图片资源报require is not defined的问题,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,接口,第7张
              (图片来源网络,侵删)

              动态资源就是需要发送请求获取到的资源

              答:因为项目引入的动态资源被当做静态资源处理了。被打包过后,被打包在新的文件夹下的图片资源会生成新的文件名,在原来的文件名后会加入一串数字,此即为资源哈希化,是为了做服务器缓存用的。那么静态的路径并不能匹配到新的文件名,导致无法正确的引入资源,所以需要加上require。require 是一个node方法,webpack会将图片当成一个模块,并根据配置文件中的规则进行打包,通过require方法拿到的文件地址,就是资源文件编译过后的文件地址。

              2. 为什么require方法失效了

              答:因为原来的项目是VueCli搭建的,其是构建于 webpack 和 webpack-dev-server 之上的,所以require方法会经过webpack处理,而Vite开发环境是基于原生ES Module的,生产环境则是通过Rollup进行打包的,Rollup默认也是不支持CommonJS模块的,所以无法识别 require 方法。

              3. new URL() 为什么就可以

              const imgUrl = new URL('./img.png', import.meta.url).href
              
              • new URL(url,base)

                用来创建一个新 URL 对象:

                • url —— 完整的 URL,或者仅路径(如果设置了 base)
                • base —— 可选的 base URL:如果设置了此参数,且参数 url 只有路径,则会根据这个 base 生成 URL

                  其中有一个属性是href,正好是函数的返回值!

                • import.meta

                  import.meta 对象包含关于当前模块的信息。

                  它的内容取决于其所在的环境。在浏览器环境中,它包含当前脚本的 URL,或者如果它是在 HTML 中的话,则包含当前页面的 URL。

                  4. Vite插件介绍

                  Vite 插件扩展了设计出色的 Rollup 接口,带有一些 Vite 独有的配置项。因此,只需要编写一个 Vite 插件,就可以同时为开发环境和生产环境工作。


                  总结

                  以上就是全部内容,本文简单介绍了Vite在生产构建时JavaScript模块对图片资源的引入方法,并且介绍了Vite插件的基本用法。

                  如果此篇文章对您有帮助欢迎您【点赞】,也欢迎您【评论】+【收藏】!


                  扩展阅读

                  1. Vite 官方中文文档 | 静态资源处理
                  2. Vite 官方中文文档 | 插件 API
                  3. Vue CLI | 处理静态资源

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,1261人围观)

还没有评论,来说两句吧...

目录[+]