我的代码:
import $ from 'jquery'
import jQuery from 'jquery'
import owlCarousel from '../../node_modules/owlcarousel/owl-carousel/owl.carousel'
class App {
…
_initSlider() {
$("#partners-carousel").owlCarousel();
}
}
我在浏览器控制台中“未定义jQuery”。怎么了? 我可以在这个类的方法中使用jQuery作为$,但不能使用名称'jQuery'。
答案 0 :(得分:14)
根据 this comment 并将其应用于您的案例,当您这样做时:
import $ from 'jquery'
import jQuery from 'jquery'
您实际上并未使用命名导出。
问题在于,当您执行
import $ ...
,import jQuery ...
然后import 'owlCarousel'
(取决于jQuery
)时,即使您声明{window.jQuery = jquery
,也会对其进行评估。导入jquery
后立即1}}。这是ES6模块语义与CommonJS要求的不同之处。
解决这个问题的一种方法是改为:
创建文件jquery-global.js
// jquery-global.js
import jquery from 'jquery';
window.jQuery = jquery;
window.$ = jquery;
然后将其导入主文件中:
// main.js
import './jquery-global.js';
import 'owlCarousel' from '../../node_modules/owlcarousel/owl-carousel/owl.carousel'
class App {
...
_initSlider() {
$("#partners-carousel").owlCarousel();
}
}
这样可以确保在加载jQuery
之前定义owlCarousel
全局。
答案 1 :(得分:1)
@Serge 您应该在问题中提到您正在使用 browserify 和 babelify 来捆绑/转译您的代码(我从评论中知道),这将帮助人们找到您问题的正确答案。
自 2021 年起,ECMA2015+/ES6+ 不允许在浏览器中原生使用 import-maps/bare-module-path。所以基本上你不能直接在浏览器中执行以下操作,因为浏览器的行为不像 nodejs,它不知道如何/从哪里获取脚本源,你不能只是说:>
import $ from 'jquery'
import jQuery from 'jquery'
但是,您可以借助 WebPack 之类的捆绑器来完成此操作,它为在浏览器中使用 import-maps/bare-module-path 打开了大门。此外,huge work is currently being done 支持在浏览器中直接实现import-maps,无需打包器,但目前还没有实现。我知道这个问题对于 OP 来说已经足够老了,但总的来说,您可以使用 WebPack 来捆绑您的代码并按照您提到的方式导入您的依赖项。
P.S. 关于 @egel 在 2016 年 10 月提出的答案(这是当时解决方案有限的旧答案),有些人要求进行更多说明。请注意 Nicolás Bevacqua 关于 ES6+ 模块范围的以下声明:
<块引用>ES6 模块中的声明作用域为该模块。这意味着在模块内声明的任何变量都不能用于其他模块,除非它们作为模块 API 的一部分显式导出(然后导入到想要访问它们的模块中)。
ES6+ 模块系统很棒并且使事情更有条理,但是我们能否在不需要打包器/转译器的情况下在浏览器中完全实现 ES6+ 模块?这是一个棘手的问题。当您的某些 JavaScript 依赖项只是不支持 ES6+ 模块系统的旧/经典脚本,并且不使用 export 关键字为您导出函数/值时,事情可能会变得更加困难。在这里,开发人员倾向于做一些变通方法来解决手头的问题。 window 对象用于附加函数/变量,以便在所有模块中使用它们。此处 window 对象用作在代码库中跨不同模块传输功能/数据的载体,但这不是推荐的方法。
以下引用自javascript.info:
<块引用>如果我们真的需要制作一个窗口级别的全局变量,我们可以显式地将它分配给window,并以window.user的身份访问。 但这是一个需要充分理由的例外。