在 Rails 6 中使 jQuery UI 全局函数可用于 webpack
Make jQuery UI global functions available with webpack in Rails 6
jQuery UI 具有全局可用的便捷功能,例如Sine、Circ、Elastic、Back、Bounce 等。但是当使用 webpack 包含 jQuery UI 时,全局函数变得不可用。以下代码失败:
function setup_sidebar_menu()
{
var $ = jQuery,
$items_with_submenu = public_vars.$sidebarMenu.find('li:has(ul)'),
submenu_options = {
submenu_open_delay: 0.25,
submenu_open_easing: Sine.easeInOut,
submenu_opened_class: 'opened'
},
root_level_class = 'root-level',
is_multiopen = public_vars.$mainMenu.hasClass('multiple-expanded');
因为正弦未定义。使用 webpack 时,有什么方法可以使这些 jQuery UI 函数全局可用?例如,$ 是全局可用的,jQuery 也是全局可用的。 $.ui 也可用。
配置如下:
environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
$: 'jquery',
JQuery: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
'window.Tether': "tether",
Popper: ['popper.js', 'default'], // for Bootstrap 4
}))
module.exports = environment
application.js
var jQuery = require("jquery")
// import jQuery from "jquery";
global.$ = global.jQuery = jQuery;
window.$ = window.jQuery = jQuery;
import 'webpack-jquery-ui'
如我所说,jQueryUI 库已正确加载并可通过 $.ui 访问,问题涉及全局函数。
更新:
看起来正确的解决方案是在 packs
目录中从头开始创建新的 js 脚本文件并重新编写有效的 ES6 / ES7。这种方法出现的问题是无法导入 jquery-ui 全局函数 Sine、Circ、Elastic、Back、Bounce:
全部失败,Sine 和任何其他类似的全局函数始终未定义:
import {Sine} from 'jquery-ui/ui/effect'
// or
import {Sine} from 'jquery-ui'
// or
import {Sine} from 'webpack-jquery-ui'
console.log(Sine)
这里有什么问题?
你可能不想听到这个,但我的感觉是你在某种程度上违背了模块化的一般精神 javascript,这并不意味着(作为一项功能)鼓励像这样的全局代码。
你或许可以让它工作,但它看起来很像一种“老派”的编写 JS 的方法,其中库在全球范围内可用。
过去,当我真的需要一些全局的东西时,我会在 window 上创建一个对象,比如 JS 链顶部的 window.APP = {}
,然后把我真正需要的东西放在那里想要成为全球性的,就像一个事件发射器,以及来自服务器的 ENV 信息。我不知道我是否会推荐这种方法,我觉得代码有点臭,但我仍然在几个应用程序中这样做了。
但我的一般感觉是你在这里感受到的痛苦是与谷物背道而驰。并不意味着您不应该这样做,但不妨让您停下来考虑一下还有什么办法可以做到这一点。
也许你应该把它放在 /packs
中它自己的文件中并导入 Sine
?
就是说,虽然我自己没有使用过,但我已经看到这可能有效:
import $ from 'jquery';
import 'jquery-ui-bundle';
import 'jquery-ui-bundle/jquery-ui.min.css';
这可能会在 $
上添加 Sine
?
正确的方法是在 packs
目录中定义一个新模块,然后在 ES6 中复制粘贴或重新编写所有需要的全局 jQuery-UI 函数。从该模块导出函数,然后将其导入到使用它的模块中。
例如,我创建了具有先前全局 jQuery-UI 函数的 ES6 模块:
app/javascript/packs/jquery-ui-es6-migrations.js
const Sine = (p) => {
return 1 - Math.cos( p * Math.PI / 2 );
}
const Circ = (p) => {
return 1 - Math.sqrt( 1 - p * p );
}
const Elastic = (p) => {
return p === 0 || p === 1 ? p :
-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
}
const Back = (p) => {
return p * p * ( 3 * p - 2 );
}
const Bounce = (p) => {
var pow2,
bounce = 4;
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
}
export {Sine, Circ, Elastic, Back, Bounce}
在另一个 ES6 模块中简单地导入这些函数:
import {Sine, Circ, Elastic, Back, Bounce} from './jquery-ui-es6-migrations'
就是这样。一切都很顺利!
jQuery UI 具有全局可用的便捷功能,例如Sine、Circ、Elastic、Back、Bounce 等。但是当使用 webpack 包含 jQuery UI 时,全局函数变得不可用。以下代码失败:
function setup_sidebar_menu()
{
var $ = jQuery,
$items_with_submenu = public_vars.$sidebarMenu.find('li:has(ul)'),
submenu_options = {
submenu_open_delay: 0.25,
submenu_open_easing: Sine.easeInOut,
submenu_opened_class: 'opened'
},
root_level_class = 'root-level',
is_multiopen = public_vars.$mainMenu.hasClass('multiple-expanded');
因为正弦未定义。使用 webpack 时,有什么方法可以使这些 jQuery UI 函数全局可用?例如,$ 是全局可用的,jQuery 也是全局可用的。 $.ui 也可用。
配置如下:
environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
$: 'jquery',
JQuery: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
'window.Tether': "tether",
Popper: ['popper.js', 'default'], // for Bootstrap 4
}))
module.exports = environment
application.js
var jQuery = require("jquery")
// import jQuery from "jquery";
global.$ = global.jQuery = jQuery;
window.$ = window.jQuery = jQuery;
import 'webpack-jquery-ui'
如我所说,jQueryUI 库已正确加载并可通过 $.ui 访问,问题涉及全局函数。
更新:
看起来正确的解决方案是在 packs
目录中从头开始创建新的 js 脚本文件并重新编写有效的 ES6 / ES7。这种方法出现的问题是无法导入 jquery-ui 全局函数 Sine、Circ、Elastic、Back、Bounce:
全部失败,Sine 和任何其他类似的全局函数始终未定义:
import {Sine} from 'jquery-ui/ui/effect'
// or
import {Sine} from 'jquery-ui'
// or
import {Sine} from 'webpack-jquery-ui'
console.log(Sine)
这里有什么问题?
你可能不想听到这个,但我的感觉是你在某种程度上违背了模块化的一般精神 javascript,这并不意味着(作为一项功能)鼓励像这样的全局代码。
你或许可以让它工作,但它看起来很像一种“老派”的编写 JS 的方法,其中库在全球范围内可用。
过去,当我真的需要一些全局的东西时,我会在 window 上创建一个对象,比如 JS 链顶部的 window.APP = {}
,然后把我真正需要的东西放在那里想要成为全球性的,就像一个事件发射器,以及来自服务器的 ENV 信息。我不知道我是否会推荐这种方法,我觉得代码有点臭,但我仍然在几个应用程序中这样做了。
但我的一般感觉是你在这里感受到的痛苦是与谷物背道而驰。并不意味着您不应该这样做,但不妨让您停下来考虑一下还有什么办法可以做到这一点。
也许你应该把它放在 /packs
中它自己的文件中并导入 Sine
?
就是说,虽然我自己没有使用过,但我已经看到这可能有效:
import $ from 'jquery';
import 'jquery-ui-bundle';
import 'jquery-ui-bundle/jquery-ui.min.css';
这可能会在 $
上添加 Sine
?
正确的方法是在 packs
目录中定义一个新模块,然后在 ES6 中复制粘贴或重新编写所有需要的全局 jQuery-UI 函数。从该模块导出函数,然后将其导入到使用它的模块中。
例如,我创建了具有先前全局 jQuery-UI 函数的 ES6 模块:
app/javascript/packs/jquery-ui-es6-migrations.js
const Sine = (p) => {
return 1 - Math.cos( p * Math.PI / 2 );
}
const Circ = (p) => {
return 1 - Math.sqrt( 1 - p * p );
}
const Elastic = (p) => {
return p === 0 || p === 1 ? p :
-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
}
const Back = (p) => {
return p * p * ( 3 * p - 2 );
}
const Bounce = (p) => {
var pow2,
bounce = 4;
while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
}
export {Sine, Circ, Elastic, Back, Bounce}
在另一个 ES6 模块中简单地导入这些函数:
import {Sine, Circ, Elastic, Back, Bounce} from './jquery-ui-es6-migrations'
就是这样。一切都很顺利!