import xxx from xxx 中存在变量或者import()函数中存在‘@/’报错

博主的桌面工具软件已经正式开发,获取方式:

  • 可以关注我的小程序【中二少年工具箱】获取。(若小程序更新有延迟,可先收藏小程序)

  • 通过下载链接

  • 百度网盘:
    链接:https://pan.baidu.com/s/15zDnSoEzJGSZLjpD2FYrMw?pwd=1234 提取码:1234 复制这段内容后打开百度网盘手机App,操作更方便哦

具体已实现功能,参考文章中二少年工具箱简介


正文开始

  • 前言
  • 三个知识点
  • 几个解释


前言

import xxx from xxx 中存在变量或者import()函数中存在‘@/’会报错。

这两种错误的原因都是因为对import模块化的理解不足。这里需要理解三个知识点:import模块,import函数,vue的@/绝对地址。


三个知识点

要注意下面三个场景代码生效的时机。两个是程序代码运行之前(编译时),一个是运行时。

  1. import xxx from xxx的形式,是静态代码分析阶段,简单理解就是,在程序运行前,nodejs先去解析我们的各个模块,去执行各个模块的入口文件,或直接得到export返回的变量。要重点注意这部分代码是nodejs在操作各模块文件,是项目程序运行之前。
  2. import()函数则是一个function,和我们定义的function a,function b没有本质区别,这是我们编写的程序运行代码。这部分是我们项目的程序代码
  3. @是打包工具定义的一个变量,打包工具都是基于nodejs,@之所以能够和其它相对路径组成绝对路径,是因为它在项目程序运行前,就先被node拿到,node得知@变量的值为“/src”,就去把项目里所有和模块化相关的@变量都给替换成了“/src”,所以如果把vue项目编译后得到dist打包目录,去js文件里是找不到“@”的,因为它都已经被替换过了。显而易见,@被解析的过程也是发生在项目程序运行之前

几个解释

理解了上面,就很好解释下面几个问题了。

  • 为什么import xxx from xxx中不能存在变量,但是可以有@
    因为这部分import模块解析发生在项目程序之前,所以它可以拿到由node解析的@变量,但是拿不到项目程序代码中定义的变量。

  • 为什么import()函数中不能解析@成绝对地址
    因为import()函数是原生ES6提供的函数,是运行在项目代码中的,和console、alert等等代码一样,没有运行在解析模块化的过程中,自然也就解析不了那时候定义的@变量。在import()函数眼中,@并没有什么特殊的,就是个普通字符,就像我们console.log(’@’)打印得到的也只是@字符一样。
    总之,@可以用在模块化解析过程,不能用在项目代码运行过程。

  • 为什么函数中不能使用import xxx from xxx
    同理,我们会发现所有的import xxx from xxx引入模块,都只能写在最外层,不能写在某个函数中,也是因为函数和import模块化运行的时期不一致。当函数运行的时候,说明已经来到js脚本运行的环境,已经不再依赖nodejs模块解析的能力,自然也就无法通过import xxx来解析模块。

  • 引申一下,require引入模块为什么可以随意用
    举一反三,commonjs模块化比ES6模块更自由一些,是因为require是nodejs的模块化语法,使用环境本身就是nodejs,不存在先把模块代码编译成其他代码,然后再运行的情况。在nodejs中,require就是一个函数,所以使用的时候是:

const test=require('test')

这本来就更像import()函数一样,是在用一个函数加载模块。

这可以引出下一个问题。

  • 为什么import加载Commonjs模块时,不能加载单一项,只能整体加载
    比如再midwayjs中,默认使用import加载模块,使用某些nodejs的纯js插件,不能加载其中的单一项。
    这是因为 ES6 模块需要支持静态代码分析,而 CommonJS 模块的输出接口是module.exports,是一个对象,无法被静态分析,所以只能整体加载。
    例如,我在midwayjs中使用时区插件moment-timezone:
import * as moment from 'moment-timezone'; //这样可以使用
import {tz} from 'moment-timezone' //这样会报错

其实让一个插件同时可以兼容整体和单一两种引入方式很容易,插件为什么不做个兼容处理。不知道是我下载的插件版本不对,还是引入的入口不对,竟然会遇到这种古老的兼容问题。正好这里可以拿出来作为例子。

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中二少年学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值