如何从 rails 5.1.3 + webpacker 的视图中使用 jquery
How to use jquery from views on rails 5.1.3 + webpacker
我想像这样使用一个简单的 jQuery 函数:
$( document ).ready(function(){
$('body').addClass("faded");
});
来自 rails 5.1.3 应用程序的单个视图,在本例中为 'login.html.erb'
在 webpack 的 application.js 我有:
var $ = require('jquery');
如果我把它放在同一个 application.js 文件中,这使得前面提到的 jquery 调用工作,但这意味着它会被所有页面调用,因为 <%= javascript_pack_tag 'application' %> 在布局上。
当我像这样在 login.html.erb 上尝试 运行 时:
<script type="text/javascript">
$( document ).ready(function(){
$('body').addClass("faded");
});
</script>
我在控制台上收到错误消息:"ReferenceError: $ is not defined"。
如果我尝试在 login.html.erb 文件上执行 " import $ from 'jquery'; ",我会收到此错误:"SyntaxError: import declarations may only appear at top level of a module"这可以理解意味着我的本地 .erb 视图无法访问 webpacker 的 application.js 上引用的 javascript 并且无法从那里导入它。
如何从视图中引用 jquery 以及 webpacker 提供的任何模块?
如果之前有人问过这个问题,我深表歉意,在阅读了几天有关 webpack、webpacker gem 和 javascript 的文章后,我没有找到解决方案,因此发布了这个问题。
:)
要事第一。您不能使用 webpacker 在脚本标签内的 erb 模板中转换 es6。
自从在 rails 中引入资产管道以来,总体思路是交付多个 javascript 文件的捆绑包。在 webpacker 之前通过定义 sprockets 清单,现在使用 packs。这允许保存对 js 资产文件的 http 请求。浏览器在对应用程序的第一个 http 请求中只加载一个包含所有 javascript 的文件,并缓存它以供进一步的页面请求。
因此,您可以为应用程序的各个部分定义单独的 js 文件,并将所有文件导入 application.js 包中。只能通过 javascript_include_tag
包含包文件。您还必须在每个导入的 es6 模块中导入 jquery,因为 es6 模块有自己的变量范围。 (只需检查 chrome 开发工具中的转译输出)
但是现在,您不能只在 body 上调用 addClass,因为您只希望它发生在登录页面上。一种解决方法是在 erb 模板中设置一个单独的 class(例如“.login”)并将其用作 selector。
//app/javascript/packs/application.js
import 'startpage'
import 'login'
//app/javascript/src/login/index.js
import $ from 'jquery'
$('.login .content').addClass("faded");
如果 faded 确实必须添加到正文中(不在模板中),您可以通过“.login”class 中的父匹配器尝试 select 或以某种方式引入rails 布局中的一个变量,它是从 erb 模板中设置的,以便为布局添加控制器特定标记。
当然,如果您认为这不会产生很多 http 请求并且速度对您的用户来说足够好,您也可以为每个页面提供一个单独的 js 文件。只需在 packs 文件夹中将它们全部制作成单独的包文件即可。
- 安装jQuery
/bin/yarn add jquery
打开 config/webpack/shared.js
,然后 add/overwrite 使用此代码:
module: {
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
noParse: function(content) {
return /jquery/.test(content);
}
},
plugins: [
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
new ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": 'jquery',
}),
],
resolve: {
extensions: settings.extensions,
modules: [
resolve(settings.source_path),
'node_modules'
],
alias: {
jquery: 'jquery/dist/jquery.slim.js',
}
},
你可能想要完整的 jQuery,而不是 jQuery 苗条
将jQueryglobal.$ = require('jquery')
导入app/javascripts/packs
上的任何js文件
现在可以使用了
$(document).ready(function() {
//
});
我想像这样使用一个简单的 jQuery 函数:
$( document ).ready(function(){
$('body').addClass("faded");
});
来自 rails 5.1.3 应用程序的单个视图,在本例中为 'login.html.erb'
在 webpack 的 application.js 我有:
var $ = require('jquery');
如果我把它放在同一个 application.js 文件中,这使得前面提到的 jquery 调用工作,但这意味着它会被所有页面调用,因为 <%= javascript_pack_tag 'application' %> 在布局上。
当我像这样在 login.html.erb 上尝试 运行 时:
<script type="text/javascript">
$( document ).ready(function(){
$('body').addClass("faded");
});
</script>
我在控制台上收到错误消息:"ReferenceError: $ is not defined"。
如果我尝试在 login.html.erb 文件上执行 " import $ from 'jquery'; ",我会收到此错误:"SyntaxError: import declarations may only appear at top level of a module"这可以理解意味着我的本地 .erb 视图无法访问 webpacker 的 application.js 上引用的 javascript 并且无法从那里导入它。
如何从视图中引用 jquery 以及 webpacker 提供的任何模块?
如果之前有人问过这个问题,我深表歉意,在阅读了几天有关 webpack、webpacker gem 和 javascript 的文章后,我没有找到解决方案,因此发布了这个问题。
:)
要事第一。您不能使用 webpacker 在脚本标签内的 erb 模板中转换 es6。
自从在 rails 中引入资产管道以来,总体思路是交付多个 javascript 文件的捆绑包。在 webpacker 之前通过定义 sprockets 清单,现在使用 packs。这允许保存对 js 资产文件的 http 请求。浏览器在对应用程序的第一个 http 请求中只加载一个包含所有 javascript 的文件,并缓存它以供进一步的页面请求。
因此,您可以为应用程序的各个部分定义单独的 js 文件,并将所有文件导入 application.js 包中。只能通过 javascript_include_tag
包含包文件。您还必须在每个导入的 es6 模块中导入 jquery,因为 es6 模块有自己的变量范围。 (只需检查 chrome 开发工具中的转译输出)
但是现在,您不能只在 body 上调用 addClass,因为您只希望它发生在登录页面上。一种解决方法是在 erb 模板中设置一个单独的 class(例如“.login”)并将其用作 selector。
//app/javascript/packs/application.js
import 'startpage'
import 'login'
//app/javascript/src/login/index.js
import $ from 'jquery'
$('.login .content').addClass("faded");
如果 faded 确实必须添加到正文中(不在模板中),您可以通过“.login”class 中的父匹配器尝试 select 或以某种方式引入rails 布局中的一个变量,它是从 erb 模板中设置的,以便为布局添加控制器特定标记。
当然,如果您认为这不会产生很多 http 请求并且速度对您的用户来说足够好,您也可以为每个页面提供一个单独的 js 文件。只需在 packs 文件夹中将它们全部制作成单独的包文件即可。
- 安装jQuery
/bin/yarn add jquery
打开
config/webpack/shared.js
,然后 add/overwrite 使用此代码:module: { rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)), noParse: function(content) { return /jquery/.test(content); } }, plugins: [ new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))), new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'), new ManifestPlugin({ publicPath: output.publicPath, writeToFileEmit: true }), new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": 'jquery', }), ], resolve: { extensions: settings.extensions, modules: [ resolve(settings.source_path), 'node_modules' ], alias: { jquery: 'jquery/dist/jquery.slim.js', } },
你可能想要完整的 jQuery,而不是 jQuery 苗条
将jQuery
global.$ = require('jquery')
导入app/javascripts/packs
上的任何js文件
现在可以使用了
$(document).ready(function() {
//
});